fog-openstack 0.1.31 → 0.2.0
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.
- checksums.yaml +5 -5
 - data/.gitignore +1 -0
 - data/.rubocop.yml +4 -1
 - data/.travis.yml +5 -5
 - data/.zuul.yaml +8 -8
 - data/Rakefile +14 -4
 - data/fog-openstack.gemspec +3 -2
 - data/lib/fog/baremetal/openstack.rb +6 -24
 - data/lib/fog/compute/openstack.rb +6 -27
 - data/lib/fog/compute/openstack/requests/create_security_group.rb +1 -1
 - data/lib/fog/compute/openstack/requests/create_server.rb +1 -1
 - data/lib/fog/compute/openstack/requests/evacuate_server.rb +1 -5
 - data/lib/fog/container_infra/openstack.rb +6 -25
 - data/lib/fog/dns/openstack/v1.rb +5 -17
 - data/lib/fog/dns/openstack/v2.rb +5 -22
 - data/lib/fog/event/openstack.rb +5 -24
 - data/lib/fog/identity/openstack.rb +24 -71
 - data/lib/fog/identity/openstack/v2.rb +6 -4
 - data/lib/fog/identity/openstack/v3.rb +5 -11
 - data/lib/fog/image/openstack/v1.rb +8 -21
 - data/lib/fog/image/openstack/v2.rb +8 -21
 - data/lib/fog/image/openstack/v2/models/image.rb +1 -1
 - data/lib/fog/introspection/openstack.rb +4 -19
 - data/lib/fog/key_manager/openstack.rb +5 -47
 - data/lib/fog/metering/openstack.rb +8 -23
 - data/lib/fog/metric/openstack.rb +7 -26
 - data/lib/fog/monitoring/openstack.rb +3 -12
 - data/lib/fog/network/openstack.rb +5 -26
 - data/lib/fog/network/openstack/requests/set_tenant.rb +0 -1
 - data/lib/fog/nfv/openstack.rb +4 -24
 - data/lib/fog/openstack.rb +17 -431
 - data/lib/fog/openstack/auth/catalog.rb +64 -0
 - data/lib/fog/openstack/auth/catalog/v2.rb +23 -0
 - data/lib/fog/openstack/auth/catalog/v3.rb +23 -0
 - data/lib/fog/openstack/auth/name.rb +65 -0
 - data/lib/fog/openstack/auth/token.rb +69 -0
 - data/lib/fog/openstack/auth/token/v2.rb +70 -0
 - data/lib/fog/openstack/auth/token/v3.rb +116 -0
 - data/lib/fog/openstack/core.rb +100 -76
 - data/lib/fog/openstack/version.rb +1 -1
 - data/lib/fog/orchestration/openstack.rb +4 -21
 - data/lib/fog/planning/openstack.rb +13 -23
 - data/lib/fog/shared_file_system/openstack.rb +10 -27
 - data/lib/fog/storage/openstack.rb +6 -11
 - data/lib/fog/volume/openstack.rb +1 -1
 - data/lib/fog/volume/openstack/models/backup.rb +2 -2
 - data/lib/fog/volume/openstack/requests/restore_backup.rb +2 -2
 - data/lib/fog/volume/openstack/requests/update_volume.rb +12 -1
 - data/lib/fog/volume/openstack/v1.rb +4 -21
 - data/lib/fog/volume/openstack/v1/models/volume.rb +1 -2
 - data/lib/fog/volume/openstack/v1/requests/update_volume.rb +0 -17
 - data/lib/fog/volume/openstack/v2.rb +4 -21
 - data/lib/fog/volume/openstack/v2/models/volume.rb +1 -1
 - data/lib/fog/volume/openstack/v2/requests/update_volume.rb +0 -18
 - data/lib/fog/workflow/openstack/v2.rb +5 -22
 - data/playbooks/fog-openstack-unittest-spec/run.yaml +2 -1
 - data/playbooks/fog-openstack-unittest-test/run.yaml +2 -1
 - data/unit/auth/catalog_test.rb +252 -0
 - data/unit/auth/name_test.rb +115 -0
 - data/unit/auth/token_test.rb +478 -0
 - data/unit/auth_helper.rb +102 -0
 - data/unit/test_helper.rb +6 -0
 - metadata +41 -16
 - data/lib/fog/compute/openstack/requests/list_tenants.rb +0 -43
 
| 
         @@ -12,7 +12,7 @@ module Fog 
     | 
|
| 
       12 
12 
     | 
    
         
             
                             :openstack_project_name, :openstack_project_id,
         
     | 
| 
       13 
13 
     | 
    
         
             
                             :openstack_project_domain, :openstack_user_domain, :openstack_domain_name,
         
     | 
| 
       14 
14 
     | 
    
         
             
                             :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id,
         
     | 
| 
       15 
     | 
    
         
            -
                             : 
     | 
| 
      
 15 
     | 
    
         
            +
                             :openstack_identity_api_version, :openstack_temp_url_key, :openstack_cache_ttl
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         
             
                  model_path 'fog/monitoring/openstack/models'
         
     | 
| 
       18 
18 
     | 
    
         
             
                  model       :metric
         
     | 
| 
         @@ -78,17 +78,8 @@ module Fog 
     | 
|
| 
       78 
78 
     | 
    
         
             
                      Fog::Monitoring::OpenStack::NotFound
         
     | 
| 
       79 
79 
     | 
    
         
             
                    end
         
     | 
| 
       80 
80 
     | 
    
         | 
| 
       81 
     | 
    
         
            -
                    def  
     | 
| 
       82 
     | 
    
         
            -
                       
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
                      @openstack_service_type           = options[:openstack_service_type] || ['monitoring']
         
     | 
| 
       85 
     | 
    
         
            -
                      @openstack_service_name           = options[:openstack_service_name]
         
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
                      @connection_options               = options[:connection_options] || {}
         
     | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
       89 
     | 
    
         
            -
                      authenticate
         
     | 
| 
       90 
     | 
    
         
            -
                      @persistent = options[:persistent] || false
         
     | 
| 
       91 
     | 
    
         
            -
                      @connection = Fog::Core::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
         
     | 
| 
      
 81 
     | 
    
         
            +
                    def default_service_type
         
     | 
| 
      
 82 
     | 
    
         
            +
                      %w[monitoring]
         
     | 
| 
       92 
83 
     | 
    
         
             
                    end
         
     | 
| 
       93 
84 
     | 
    
         
             
                  end
         
     | 
| 
       94 
85 
     | 
    
         
             
                end
         
     | 
| 
         @@ -3,8 +3,6 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module Fog
         
     | 
| 
       4 
4 
     | 
    
         
             
              module Network
         
     | 
| 
       5 
5 
     | 
    
         
             
                class OpenStack < Fog::Service
         
     | 
| 
       6 
     | 
    
         
            -
                  SUPPORTED_VERSIONS = /v2(\.0)*/
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
6 
     | 
    
         
             
                  requires :openstack_auth_url
         
     | 
| 
       9 
7 
     | 
    
         
             
                  recognizes :openstack_auth_token, :openstack_management_url,
         
     | 
| 
       10 
8 
     | 
    
         
             
                             :persistent, :openstack_service_type, :openstack_service_name,
         
     | 
| 
         @@ -15,7 +13,7 @@ module Fog 
     | 
|
| 
       15 
13 
     | 
    
         
             
                             :openstack_project_name, :openstack_project_id,
         
     | 
| 
       16 
14 
     | 
    
         
             
                             :openstack_project_domain, :openstack_user_domain, :openstack_domain_name,
         
     | 
| 
       17 
15 
     | 
    
         
             
                             :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id,
         
     | 
| 
       18 
     | 
    
         
            -
                             : 
     | 
| 
      
 16 
     | 
    
         
            +
                             :openstack_identity_api_version
         
     | 
| 
       19 
17 
     | 
    
         | 
| 
       20 
18 
     | 
    
         
             
                  ## MODELS
         
     | 
| 
       21 
19 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -429,8 +427,6 @@ module Fog 
     | 
|
| 
       429 
427 
     | 
    
         
             
                    def initialize(options = {})
         
     | 
| 
       430 
428 
     | 
    
         
             
                      @auth_token = Fog::Mock.random_base64(64)
         
     | 
| 
       431 
429 
     | 
    
         
             
                      @auth_token_expiration = (Time.now.utc + 86400).iso8601
         
     | 
| 
       432 
     | 
    
         
            -
             
     | 
| 
       433 
     | 
    
         
            -
                      initialize_identity options
         
     | 
| 
       434 
430 
     | 
    
         
             
                    end
         
     | 
| 
       435 
431 
     | 
    
         | 
| 
       436 
432 
     | 
    
         
             
                    def data
         
     | 
| 
         @@ -449,29 +445,12 @@ module Fog 
     | 
|
| 
       449 
445 
     | 
    
         
             
                      Fog::Network::OpenStack::NotFound
         
     | 
| 
       450 
446 
     | 
    
         
             
                    end
         
     | 
| 
       451 
447 
     | 
    
         | 
| 
       452 
     | 
    
         
            -
                    def  
     | 
| 
       453 
     | 
    
         
            -
                       
     | 
| 
       454 
     | 
    
         
            -
             
     | 
| 
       455 
     | 
    
         
            -
                      @openstack_service_type = options[:openstack_service_type] || ['network']
         
     | 
| 
       456 
     | 
    
         
            -
                      @openstack_service_name = options[:openstack_service_name]
         
     | 
| 
       457 
     | 
    
         
            -
             
     | 
| 
       458 
     | 
    
         
            -
                      @connection_options     = options[:connection_options] || {}
         
     | 
| 
       459 
     | 
    
         
            -
             
     | 
| 
       460 
     | 
    
         
            -
                      authenticate
         
     | 
| 
       461 
     | 
    
         
            -
                      set_api_path
         
     | 
| 
       462 
     | 
    
         
            -
             
     | 
| 
       463 
     | 
    
         
            -
                      @persistent = options[:persistent] || false
         
     | 
| 
       464 
     | 
    
         
            -
                      @connection = Fog::Core::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
         
     | 
| 
      
 448 
     | 
    
         
            +
                    def default_path_prefix
         
     | 
| 
      
 449 
     | 
    
         
            +
                      'v2.0'
         
     | 
| 
       465 
450 
     | 
    
         
             
                    end
         
     | 
| 
       466 
451 
     | 
    
         | 
| 
       467 
     | 
    
         
            -
                    def  
     | 
| 
       468 
     | 
    
         
            -
                       
     | 
| 
       469 
     | 
    
         
            -
                      unless @path.match(SUPPORTED_VERSIONS)
         
     | 
| 
       470 
     | 
    
         
            -
                        @path = Fog::OpenStack.get_supported_version_path(SUPPORTED_VERSIONS,
         
     | 
| 
       471 
     | 
    
         
            -
                                                                          @openstack_management_uri,
         
     | 
| 
       472 
     | 
    
         
            -
                                                                          @auth_token,
         
     | 
| 
       473 
     | 
    
         
            -
                                                                          @connection_options)
         
     | 
| 
       474 
     | 
    
         
            -
                      end
         
     | 
| 
      
 452 
     | 
    
         
            +
                    def default_service_type
         
     | 
| 
      
 453 
     | 
    
         
            +
                      %w[network]
         
     | 
| 
       475 
454 
     | 
    
         
             
                    end
         
     | 
| 
       476 
455 
     | 
    
         
             
                  end
         
     | 
| 
       477 
456 
     | 
    
         
             
                end
         
     | 
    
        data/lib/fog/nfv/openstack.rb
    CHANGED
    
    | 
         @@ -82,8 +82,6 @@ module Fog 
     | 
|
| 
       82 
82 
     | 
    
         
             
                    def initialize(options = {})
         
     | 
| 
       83 
83 
     | 
    
         
             
                      @auth_token = Fog::Mock.random_base64(64)
         
     | 
| 
       84 
84 
     | 
    
         
             
                      @auth_token_expiration = (Time.now.utc + 86_400).iso8601
         
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
                      initialize_identity options
         
     | 
| 
       87 
85 
     | 
    
         
             
                    end
         
     | 
| 
       88 
86 
     | 
    
         | 
| 
       89 
87 
     | 
    
         
             
                    def data
         
     | 
| 
         @@ -102,30 +100,12 @@ module Fog 
     | 
|
| 
       102 
100 
     | 
    
         
             
                      Fog::NFV::OpenStack::NotFound
         
     | 
| 
       103 
101 
     | 
    
         
             
                    end
         
     | 
| 
       104 
102 
     | 
    
         | 
| 
       105 
     | 
    
         
            -
                    def  
     | 
| 
       106 
     | 
    
         
            -
                       
     | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
       108 
     | 
    
         
            -
                      @openstack_service_type  = options[:openstack_service_type] || ['servicevm']
         
     | 
| 
       109 
     | 
    
         
            -
                      @openstack_service_name  = options[:openstack_service_name]
         
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
       111 
     | 
    
         
            -
                      @connection_options = options[:connection_options] || {}
         
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
                      authenticate
         
     | 
| 
       114 
     | 
    
         
            -
                      set_api_path
         
     | 
| 
       115 
     | 
    
         
            -
             
     | 
| 
       116 
     | 
    
         
            -
                      @persistent = options[:persistent] || false
         
     | 
| 
       117 
     | 
    
         
            -
                      @connection = Fog::Core::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
         
     | 
| 
      
 103 
     | 
    
         
            +
                    def default_path_prefix
         
     | 
| 
      
 104 
     | 
    
         
            +
                      'v1.0'
         
     | 
| 
       118 
105 
     | 
    
         
             
                    end
         
     | 
| 
       119 
106 
     | 
    
         | 
| 
       120 
     | 
    
         
            -
                    def  
     | 
| 
       121 
     | 
    
         
            -
                       
     | 
| 
       122 
     | 
    
         
            -
                        @path = "/" + Fog::OpenStack.get_supported_version(
         
     | 
| 
       123 
     | 
    
         
            -
                          SUPPORTED_VERSIONS,
         
     | 
| 
       124 
     | 
    
         
            -
                          @openstack_management_uri,
         
     | 
| 
       125 
     | 
    
         
            -
                          @auth_token,
         
     | 
| 
       126 
     | 
    
         
            -
                          @connection_options
         
     | 
| 
       127 
     | 
    
         
            -
                        )
         
     | 
| 
       128 
     | 
    
         
            -
                      end
         
     | 
| 
      
 107 
     | 
    
         
            +
                    def default_service_type
         
     | 
| 
      
 108 
     | 
    
         
            +
                      %w[servicevm]
         
     | 
| 
       129 
109 
     | 
    
         
             
                    end
         
     | 
| 
       130 
110 
     | 
    
         
             
                  end
         
     | 
| 
       131 
111 
     | 
    
         
             
                end
         
     | 
    
        data/lib/fog/openstack.rb
    CHANGED
    
    | 
         @@ -84,6 +84,8 @@ module Fog 
     | 
|
| 
       84 
84 
     | 
    
         
             
              end
         
     | 
| 
       85 
85 
     | 
    
         | 
| 
       86 
86 
     | 
    
         
             
              module OpenStack
         
     | 
| 
      
 87 
     | 
    
         
            +
                require 'fog/openstack/auth/token'
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
       87 
89 
     | 
    
         
             
                autoload :VERSION, 'fog/openstack/version'
         
     | 
| 
       88 
90 
     | 
    
         | 
| 
       89 
91 
     | 
    
         
             
                autoload :Core, 'fog/openstack/core'
         
     | 
| 
         @@ -123,425 +125,10 @@ module Fog 
     | 
|
| 
       123 
125 
     | 
    
         
             
                  Fog::OpenStack.token_cache = {}
         
     | 
| 
       124 
126 
     | 
    
         
             
                end
         
     | 
| 
       125 
127 
     | 
    
         | 
| 
       126 
     | 
    
         
            -
                def self.authenticate(options, connection_options = {})
         
     | 
| 
       127 
     | 
    
         
            -
                  case options[:openstack_auth_uri].path
         
     | 
| 
       128 
     | 
    
         
            -
                  when /v1(\.\d+)?/
         
     | 
| 
       129 
     | 
    
         
            -
                    authenticate_v1(options, connection_options)
         
     | 
| 
       130 
     | 
    
         
            -
                  when /v2(\.\d+)?/
         
     | 
| 
       131 
     | 
    
         
            -
                    authenticate_v2(options, connection_options)
         
     | 
| 
       132 
     | 
    
         
            -
                  when /v3(\.\d+)?/
         
     | 
| 
       133 
     | 
    
         
            -
                    authenticate_v3(options, connection_options)
         
     | 
| 
       134 
     | 
    
         
            -
                  else
         
     | 
| 
       135 
     | 
    
         
            -
                    authenticate_v2(options, connection_options)
         
     | 
| 
       136 
     | 
    
         
            -
                  end
         
     | 
| 
       137 
     | 
    
         
            -
                end
         
     | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
       139 
     | 
    
         
            -
                # legacy v1.0 style auth
         
     | 
| 
       140 
     | 
    
         
            -
                def self.authenticate_v1(options, connection_options = {})
         
     | 
| 
       141 
     | 
    
         
            -
                  uri = options[:openstack_auth_uri]
         
     | 
| 
       142 
     | 
    
         
            -
                  connection = Fog::Core::Connection.new(uri.to_s, false, connection_options)
         
     | 
| 
       143 
     | 
    
         
            -
                  @openstack_api_key  = options[:openstack_api_key]
         
     | 
| 
       144 
     | 
    
         
            -
                  @openstack_username = options[:openstack_username]
         
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
                  response = connection.request({
         
     | 
| 
       147 
     | 
    
         
            -
                    :expects  => [200, 204],
         
     | 
| 
       148 
     | 
    
         
            -
                    :headers  => {
         
     | 
| 
       149 
     | 
    
         
            -
                      'X-Auth-Key'  => @openstack_api_key,
         
     | 
| 
       150 
     | 
    
         
            -
                      'X-Auth-User' => @openstack_username
         
     | 
| 
       151 
     | 
    
         
            -
                    },
         
     | 
| 
       152 
     | 
    
         
            -
                    :method   => 'GET',
         
     | 
| 
       153 
     | 
    
         
            -
                    :path     =>  (uri.path and not uri.path.empty?) ? uri.path : 'v1.0'
         
     | 
| 
       154 
     | 
    
         
            -
                  })
         
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
                  return {
         
     | 
| 
       157 
     | 
    
         
            -
                    :token => response.headers['X-Auth-Token'],
         
     | 
| 
       158 
     | 
    
         
            -
                    :server_management_url => response.headers['X-Server-Management-Url'] || response.headers['X-Storage-Url'],
         
     | 
| 
       159 
     | 
    
         
            -
                    :identity_public_endpoint => response.headers['X-Keystone']
         
     | 
| 
       160 
     | 
    
         
            -
                  }
         
     | 
| 
       161 
     | 
    
         
            -
                end
         
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
       163 
     | 
    
         
            -
                # Keystone Style Auth
         
     | 
| 
       164 
     | 
    
         
            -
                def self.authenticate_v2(options, connection_options = {})
         
     | 
| 
       165 
     | 
    
         
            -
                  uri                   = options[:openstack_auth_uri]
         
     | 
| 
       166 
     | 
    
         
            -
                  tenant_name           = options[:openstack_tenant]
         
     | 
| 
       167 
     | 
    
         
            -
                  service_type          = options[:openstack_service_type]
         
     | 
| 
       168 
     | 
    
         
            -
                  service_name          = options[:openstack_service_name]
         
     | 
| 
       169 
     | 
    
         
            -
                  identity_service_type = options[:openstack_identity_service_type]
         
     | 
| 
       170 
     | 
    
         
            -
                  endpoint_type         = (options[:openstack_endpoint_type] || 'publicURL').to_s
         
     | 
| 
       171 
     | 
    
         
            -
                  openstack_region      = options[:openstack_region]
         
     | 
| 
       172 
     | 
    
         
            -
             
     | 
| 
       173 
     | 
    
         
            -
                  body = retrieve_tokens_v2(options, connection_options)
         
     | 
| 
       174 
     | 
    
         
            -
                  service = get_service(body, service_type, service_name)
         
     | 
| 
       175 
     | 
    
         
            -
             
     | 
| 
       176 
     | 
    
         
            -
                  options[:unscoped_token] = body['access']['token']['id']
         
     | 
| 
       177 
     | 
    
         
            -
             
     | 
| 
       178 
     | 
    
         
            -
                  unless service
         
     | 
| 
       179 
     | 
    
         
            -
                    unless tenant_name
         
     | 
| 
       180 
     | 
    
         
            -
                      response = Fog::Core::Connection.new(
         
     | 
| 
       181 
     | 
    
         
            -
                        "#{uri.scheme}://#{uri.host}:#{uri.port}/v2.0/tenants", false, connection_options).request({
         
     | 
| 
       182 
     | 
    
         
            -
                        :expects => [200, 204],
         
     | 
| 
       183 
     | 
    
         
            -
                        :headers => {'Content-Type' => 'application/json',
         
     | 
| 
       184 
     | 
    
         
            -
                                     'Accept' => 'application/json',
         
     | 
| 
       185 
     | 
    
         
            -
                                     'X-Auth-Token' => body['access']['token']['id']},
         
     | 
| 
       186 
     | 
    
         
            -
                        :method  => 'GET'
         
     | 
| 
       187 
     | 
    
         
            -
                      })
         
     | 
| 
       188 
     | 
    
         
            -
             
     | 
| 
       189 
     | 
    
         
            -
                      body = Fog::JSON.decode(response.body)
         
     | 
| 
       190 
     | 
    
         
            -
                      if body['tenants'].empty?
         
     | 
| 
       191 
     | 
    
         
            -
                        raise Fog::Errors::NotFound.new('No Tenant Found')
         
     | 
| 
       192 
     | 
    
         
            -
                      else
         
     | 
| 
       193 
     | 
    
         
            -
                        options[:openstack_tenant] = body['tenants'].first['name']
         
     | 
| 
       194 
     | 
    
         
            -
                      end
         
     | 
| 
       195 
     | 
    
         
            -
                    end
         
     | 
| 
       196 
     | 
    
         
            -
             
     | 
| 
       197 
     | 
    
         
            -
                    body = retrieve_tokens_v2(options, connection_options)
         
     | 
| 
       198 
     | 
    
         
            -
                    service = get_service(body, service_type, service_name)
         
     | 
| 
       199 
     | 
    
         
            -
             
     | 
| 
       200 
     | 
    
         
            -
                  end
         
     | 
| 
       201 
     | 
    
         
            -
             
     | 
| 
       202 
     | 
    
         
            -
                  unless service
         
     | 
| 
       203 
     | 
    
         
            -
                    available = body['access']['serviceCatalog'].map { |endpoint|
         
     | 
| 
       204 
     | 
    
         
            -
                      endpoint['type']
         
     | 
| 
       205 
     | 
    
         
            -
                    }.sort.join ', '
         
     | 
| 
       206 
     | 
    
         
            -
             
     | 
| 
       207 
     | 
    
         
            -
                    missing = service_type.join ', '
         
     | 
| 
       208 
     | 
    
         
            -
             
     | 
| 
       209 
     | 
    
         
            -
                    message = "Could not find service #{missing}.  Have #{available}"
         
     | 
| 
       210 
     | 
    
         
            -
             
     | 
| 
       211 
     | 
    
         
            -
                    raise Fog::Errors::NotFound, message
         
     | 
| 
       212 
     | 
    
         
            -
                  end
         
     | 
| 
       213 
     | 
    
         
            -
             
     | 
| 
       214 
     | 
    
         
            -
                  service['endpoints'] = service['endpoints'].select do |endpoint|
         
     | 
| 
       215 
     | 
    
         
            -
                    endpoint['region'] == openstack_region
         
     | 
| 
       216 
     | 
    
         
            -
                  end if openstack_region
         
     | 
| 
       217 
     | 
    
         
            -
             
     | 
| 
       218 
     | 
    
         
            -
                  if service['endpoints'].empty?
         
     | 
| 
       219 
     | 
    
         
            -
                    raise Fog::Errors::NotFound.new("No endpoints available for region '#{openstack_region}'")
         
     | 
| 
       220 
     | 
    
         
            -
                  end if openstack_region
         
     | 
| 
       221 
     | 
    
         
            -
             
     | 
| 
       222 
     | 
    
         
            -
                  regions = service["endpoints"].map{ |e| e['region'] }.uniq
         
     | 
| 
       223 
     | 
    
         
            -
                  if regions.count > 1
         
     | 
| 
       224 
     | 
    
         
            -
                    raise Fog::Errors::NotFound.new("Multiple regions available choose one of these '#{regions.join(',')}'")
         
     | 
| 
       225 
     | 
    
         
            -
                  end
         
     | 
| 
       226 
     | 
    
         
            -
             
     | 
| 
       227 
     | 
    
         
            -
                  identity_service = get_service(body, identity_service_type) if identity_service_type
         
     | 
| 
       228 
     | 
    
         
            -
                  tenant = body['access']['token']['tenant']
         
     | 
| 
       229 
     | 
    
         
            -
                  user = body['access']['user']
         
     | 
| 
       230 
     | 
    
         
            -
             
     | 
| 
       231 
     | 
    
         
            -
                  management_url = service['endpoints'].find{|s| s[endpoint_type]}[endpoint_type]
         
     | 
| 
       232 
     | 
    
         
            -
                  identity_url   = identity_service['endpoints'].find{|s| s['publicURL']}['publicURL'] if identity_service
         
     | 
| 
       233 
     | 
    
         
            -
             
     | 
| 
       234 
     | 
    
         
            -
                  {
         
     | 
| 
       235 
     | 
    
         
            -
                    :user                     => user,
         
     | 
| 
       236 
     | 
    
         
            -
                    :tenant                   => tenant,
         
     | 
| 
       237 
     | 
    
         
            -
                    :identity_public_endpoint => identity_url,
         
     | 
| 
       238 
     | 
    
         
            -
                    :server_management_url    => management_url,
         
     | 
| 
       239 
     | 
    
         
            -
                    :token                    => body['access']['token']['id'],
         
     | 
| 
       240 
     | 
    
         
            -
                    :expires                  => body['access']['token']['expires'],
         
     | 
| 
       241 
     | 
    
         
            -
                    :current_user_id          => body['access']['user']['id'],
         
     | 
| 
       242 
     | 
    
         
            -
                    :unscoped_token           => options[:unscoped_token]
         
     | 
| 
       243 
     | 
    
         
            -
                  }
         
     | 
| 
       244 
     | 
    
         
            -
                end
         
     | 
| 
       245 
     | 
    
         
            -
             
     | 
| 
       246 
     | 
    
         
            -
                # Keystone Style Auth
         
     | 
| 
       247 
     | 
    
         
            -
                def self.authenticate_v3(options, connection_options = {})
         
     | 
| 
       248 
     | 
    
         
            -
                  uri                   = options[:openstack_auth_uri]
         
     | 
| 
       249 
     | 
    
         
            -
                  project_name          = options[:openstack_project_name]
         
     | 
| 
       250 
     | 
    
         
            -
                  service_type          = options[:openstack_service_type]
         
     | 
| 
       251 
     | 
    
         
            -
                  service_name          = options[:openstack_service_name]
         
     | 
| 
       252 
     | 
    
         
            -
                  identity_service_type = options[:openstack_identity_service_type]
         
     | 
| 
       253 
     | 
    
         
            -
                  endpoint_type         = map_endpoint_type(options[:openstack_endpoint_type] || 'publicURL')
         
     | 
| 
       254 
     | 
    
         
            -
                  openstack_region      = options[:openstack_region]
         
     | 
| 
       255 
     | 
    
         
            -
             
     | 
| 
       256 
     | 
    
         
            -
                  token, body = retrieve_tokens_v3 options, connection_options
         
     | 
| 
       257 
     | 
    
         
            -
             
     | 
| 
       258 
     | 
    
         
            -
                  service = get_service_v3(body, service_type, service_name, openstack_region, options)
         
     | 
| 
       259 
     | 
    
         
            -
             
     | 
| 
       260 
     | 
    
         
            -
                  options[:unscoped_token] = token
         
     | 
| 
       261 
     | 
    
         
            -
             
     | 
| 
       262 
     | 
    
         
            -
                  unless service
         
     | 
| 
       263 
     | 
    
         
            -
                    unless project_name
         
     | 
| 
       264 
     | 
    
         
            -
                      request_body = {
         
     | 
| 
       265 
     | 
    
         
            -
                          :expects => [200],
         
     | 
| 
       266 
     | 
    
         
            -
                          :headers => {'Content-Type' => 'application/json',
         
     | 
| 
       267 
     | 
    
         
            -
                                       'Accept' => 'application/json',
         
     | 
| 
       268 
     | 
    
         
            -
                                       'X-Auth-Token' => token},
         
     | 
| 
       269 
     | 
    
         
            -
                          :method => 'GET'
         
     | 
| 
       270 
     | 
    
         
            -
                      }
         
     | 
| 
       271 
     | 
    
         
            -
                      user_id = body['token']['user']['id']
         
     | 
| 
       272 
     | 
    
         
            -
                      project_uri = uri.clone
         
     | 
| 
       273 
     | 
    
         
            -
                      project_uri.path = uri.path.sub('/auth/tokens', "/users/#{user_id}/projects")
         
     | 
| 
       274 
     | 
    
         
            -
                      project_uri_param = "#{project_uri.scheme}://#{project_uri.host}:#{project_uri.port}#{project_uri.path}"
         
     | 
| 
       275 
     | 
    
         
            -
                      response = Fog::Core::Connection.new(project_uri_param, false, connection_options).request(request_body)
         
     | 
| 
       276 
     | 
    
         
            -
             
     | 
| 
       277 
     | 
    
         
            -
                      projects_body = Fog::JSON.decode(response.body)
         
     | 
| 
       278 
     | 
    
         
            -
                      if projects_body['projects'].empty?
         
     | 
| 
       279 
     | 
    
         
            -
                        options[:openstack_domain_id] = body['token']['user']['domain']['id']
         
     | 
| 
       280 
     | 
    
         
            -
                      else
         
     | 
| 
       281 
     | 
    
         
            -
                        options[:openstack_project_id] = projects_body['projects'].first['id']
         
     | 
| 
       282 
     | 
    
         
            -
                        options[:openstack_project_name] = projects_body['projects'].first['name']
         
     | 
| 
       283 
     | 
    
         
            -
                        options[:openstack_domain_id] = projects_body['projects'].first['domain_id']
         
     | 
| 
       284 
     | 
    
         
            -
                      end
         
     | 
| 
       285 
     | 
    
         
            -
                    end
         
     | 
| 
       286 
     | 
    
         
            -
             
     | 
| 
       287 
     | 
    
         
            -
                    token, body = retrieve_tokens_v3(options, connection_options)
         
     | 
| 
       288 
     | 
    
         
            -
                    service = get_service_v3(body, service_type, service_name, openstack_region, options)
         
     | 
| 
       289 
     | 
    
         
            -
                  end
         
     | 
| 
       290 
     | 
    
         
            -
             
     | 
| 
       291 
     | 
    
         
            -
                  # If no identity endpoint is found, try the auth uri (slicing /auth/tokens)
         
     | 
| 
       292 
     | 
    
         
            -
                  # It covers the case where identityv3 endpoint is not present in the catalog but we have to use it
         
     | 
| 
       293 
     | 
    
         
            -
                  unless service
         
     | 
| 
       294 
     | 
    
         
            -
                    if service_type.include? "identity"
         
     | 
| 
       295 
     | 
    
         
            -
                      identity_uri = uri.to_s.sub('/auth/tokens', '')
         
     | 
| 
       296 
     | 
    
         
            -
                      response = Fog::Core::Connection.new(identity_uri, false, connection_options).request({:method => 'GET'})
         
     | 
| 
       297 
     | 
    
         
            -
                      if response.status == 200
         
     | 
| 
       298 
     | 
    
         
            -
                        service = {
         
     | 
| 
       299 
     | 
    
         
            -
                          "endpoints" => [{
         
     | 
| 
       300 
     | 
    
         
            -
                             "url"       => identity_uri,
         
     | 
| 
       301 
     | 
    
         
            -
                             "region"    => openstack_region,
         
     | 
| 
       302 
     | 
    
         
            -
                             "interface" => endpoint_type
         
     | 
| 
       303 
     | 
    
         
            -
                          }],
         
     | 
| 
       304 
     | 
    
         
            -
                          "type"      => service_type,
         
     | 
| 
       305 
     | 
    
         
            -
                          "name"      => service_name
         
     | 
| 
       306 
     | 
    
         
            -
                        }
         
     | 
| 
       307 
     | 
    
         
            -
                      end
         
     | 
| 
       308 
     | 
    
         
            -
                    end
         
     | 
| 
       309 
     | 
    
         
            -
                  end
         
     | 
| 
       310 
     | 
    
         
            -
             
     | 
| 
       311 
     | 
    
         
            -
                  unless service
         
     | 
| 
       312 
     | 
    
         
            -
                    available_services = body['token']['catalog'].map { |service|
         
     | 
| 
       313 
     | 
    
         
            -
                      service['type']
         
     | 
| 
       314 
     | 
    
         
            -
                    }.sort.join ', '
         
     | 
| 
       315 
     | 
    
         
            -
             
     | 
| 
       316 
     | 
    
         
            -
                    available_regions = body['token']['catalog'].map { |service|
         
     | 
| 
       317 
     | 
    
         
            -
                      service['endpoints'].map { |endpoint|
         
     | 
| 
       318 
     | 
    
         
            -
                        endpoint['region']
         
     | 
| 
       319 
     | 
    
         
            -
                      }.uniq
         
     | 
| 
       320 
     | 
    
         
            -
                    }.uniq.sort.join ', '
         
     | 
| 
       321 
     | 
    
         
            -
             
     | 
| 
       322 
     | 
    
         
            -
                    missing = service_type.join ', '
         
     | 
| 
       323 
     | 
    
         
            -
             
     | 
| 
       324 
     | 
    
         
            -
                    message = "Could not find service #{missing}#{(' in region '+openstack_region) if openstack_region}."+
         
     | 
| 
       325 
     | 
    
         
            -
                        " Have #{available_services}#{(' in regions '+available_regions) if openstack_region}"
         
     | 
| 
       326 
     | 
    
         
            -
             
     | 
| 
       327 
     | 
    
         
            -
                    raise Fog::Errors::NotFound, message
         
     | 
| 
       328 
     | 
    
         
            -
                  end
         
     | 
| 
       329 
     | 
    
         
            -
             
     | 
| 
       330 
     | 
    
         
            -
                  service['endpoints'] = service['endpoints'].select do |endpoint|
         
     | 
| 
       331 
     | 
    
         
            -
                    endpoint['region'] == openstack_region && endpoint['interface'] == endpoint_type
         
     | 
| 
       332 
     | 
    
         
            -
                  end if openstack_region
         
     | 
| 
       333 
     | 
    
         
            -
             
     | 
| 
       334 
     | 
    
         
            -
                  if service['endpoints'].empty?
         
     | 
| 
       335 
     | 
    
         
            -
                    raise Fog::Errors::NotFound.new("No endpoints available for region '#{openstack_region}'")
         
     | 
| 
       336 
     | 
    
         
            -
                  end if openstack_region
         
     | 
| 
       337 
     | 
    
         
            -
             
     | 
| 
       338 
     | 
    
         
            -
                  regions = service["endpoints"].map { |e| e['region'] }.uniq
         
     | 
| 
       339 
     | 
    
         
            -
                  if regions.count > 1
         
     | 
| 
       340 
     | 
    
         
            -
                    raise Fog::Errors::NotFound.new("Multiple regions available choose one of these '#{regions.join(',')}'")
         
     | 
| 
       341 
     | 
    
         
            -
                  end
         
     | 
| 
       342 
     | 
    
         
            -
             
     | 
| 
       343 
     | 
    
         
            -
                  identity_service = get_service_v3(body, identity_service_type, nil, nil, :openstack_endpoint_path_matches => /\/v3/) if identity_service_type
         
     | 
| 
       344 
     | 
    
         
            -
             
     | 
| 
       345 
     | 
    
         
            -
                  management_url = service['endpoints'].find { |e| e['interface']==endpoint_type }['url']
         
     | 
| 
       346 
     | 
    
         
            -
                  identity_url = identity_service['endpoints'].find { |e| e['interface']=='public' }['url'] if identity_service
         
     | 
| 
       347 
     | 
    
         
            -
             
     | 
| 
       348 
     | 
    
         
            -
                  if body['token']['project']
         
     | 
| 
       349 
     | 
    
         
            -
                    tenant = body['token']['project']
         
     | 
| 
       350 
     | 
    
         
            -
                  elsif body['token']['user']['project']
         
     | 
| 
       351 
     | 
    
         
            -
                    tenant = body['token']['user']['project']
         
     | 
| 
       352 
     | 
    
         
            -
                  end
         
     | 
| 
       353 
     | 
    
         
            -
             
     | 
| 
       354 
     | 
    
         
            -
                  return {
         
     | 
| 
       355 
     | 
    
         
            -
                      :user                     => body['token']['user']['name'],
         
     | 
| 
       356 
     | 
    
         
            -
                      :tenant                   => tenant,
         
     | 
| 
       357 
     | 
    
         
            -
                      :identity_public_endpoint => identity_url,
         
     | 
| 
       358 
     | 
    
         
            -
                      :server_management_url    => management_url,
         
     | 
| 
       359 
     | 
    
         
            -
                      :token                    => token,
         
     | 
| 
       360 
     | 
    
         
            -
                      :expires                  => body['token']['expires_at'],
         
     | 
| 
       361 
     | 
    
         
            -
                      :current_user_id          => body['token']['user']['id'],
         
     | 
| 
       362 
     | 
    
         
            -
                      :unscoped_token           => options[:unscoped_token]
         
     | 
| 
       363 
     | 
    
         
            -
                  }
         
     | 
| 
       364 
     | 
    
         
            -
                end
         
     | 
| 
       365 
     | 
    
         
            -
             
     | 
| 
       366 
     | 
    
         
            -
                def self.get_service(body, service_type=[], service_name=nil)
         
     | 
| 
       367 
     | 
    
         
            -
                  if not body['access'].nil?
         
     | 
| 
       368 
     | 
    
         
            -
                    body['access']['serviceCatalog'].find do |s|
         
     | 
| 
       369 
     | 
    
         
            -
                      if service_name.nil? or service_name.empty?
         
     | 
| 
       370 
     | 
    
         
            -
                        service_type.include?(s['type'])
         
     | 
| 
       371 
     | 
    
         
            -
                      else
         
     | 
| 
       372 
     | 
    
         
            -
                        service_type.include?(s['type']) and s['name'] == service_name
         
     | 
| 
       373 
     | 
    
         
            -
                      end
         
     | 
| 
       374 
     | 
    
         
            -
                    end
         
     | 
| 
       375 
     | 
    
         
            -
                  elsif not body['token']['catalog'].nil?
         
     | 
| 
       376 
     | 
    
         
            -
                    body['token']['catalog'].find do |s|
         
     | 
| 
       377 
     | 
    
         
            -
                      if service_name.nil? or service_name.empty?
         
     | 
| 
       378 
     | 
    
         
            -
                        service_type.include?(s['type'])
         
     | 
| 
       379 
     | 
    
         
            -
                      else
         
     | 
| 
       380 
     | 
    
         
            -
                        service_type.include?(s['type']) and s['name'] == service_name
         
     | 
| 
       381 
     | 
    
         
            -
                      end
         
     | 
| 
       382 
     | 
    
         
            -
                    end
         
     | 
| 
       383 
     | 
    
         
            -
             
     | 
| 
       384 
     | 
    
         
            -
                  end
         
     | 
| 
       385 
     | 
    
         
            -
                end
         
     | 
| 
       386 
     | 
    
         
            -
             
     | 
| 
       387 
     | 
    
         
            -
                def self.retrieve_tokens_v2(options, connection_options = {})
         
     | 
| 
       388 
     | 
    
         
            -
                  api_key           = options[:openstack_api_key].to_s
         
     | 
| 
       389 
     | 
    
         
            -
                  username          = options[:openstack_username].to_s
         
     | 
| 
       390 
     | 
    
         
            -
                  tenant_name       = options[:openstack_tenant].to_s
         
     | 
| 
       391 
     | 
    
         
            -
                  auth_token        = options[:openstack_auth_token] || options[:unscoped_token]
         
     | 
| 
       392 
     | 
    
         
            -
                  uri               = options[:openstack_auth_uri]
         
     | 
| 
       393 
     | 
    
         
            -
                  omit_default_port = options[:openstack_auth_omit_default_port]
         
     | 
| 
       394 
     | 
    
         
            -
             
     | 
| 
       395 
     | 
    
         
            -
                  identity_v2_connection = Fog::Core::Connection.new(uri.to_s, false, connection_options)
         
     | 
| 
       396 
     | 
    
         
            -
                  request_body = {:auth => Hash.new}
         
     | 
| 
       397 
     | 
    
         
            -
             
     | 
| 
       398 
     | 
    
         
            -
                  if auth_token
         
     | 
| 
       399 
     | 
    
         
            -
                    request_body[:auth][:token] = {
         
     | 
| 
       400 
     | 
    
         
            -
                      :id => auth_token
         
     | 
| 
       401 
     | 
    
         
            -
                    }
         
     | 
| 
       402 
     | 
    
         
            -
                  else
         
     | 
| 
       403 
     | 
    
         
            -
                    request_body[:auth][:passwordCredentials] = {
         
     | 
| 
       404 
     | 
    
         
            -
                      :username => username,
         
     | 
| 
       405 
     | 
    
         
            -
                      :password => api_key
         
     | 
| 
       406 
     | 
    
         
            -
                    }
         
     | 
| 
       407 
     | 
    
         
            -
                  end
         
     | 
| 
       408 
     | 
    
         
            -
                  request_body[:auth][:tenantName] = tenant_name if tenant_name
         
     | 
| 
       409 
     | 
    
         
            -
             
     | 
| 
       410 
     | 
    
         
            -
                  request = {
         
     | 
| 
       411 
     | 
    
         
            -
                    :expects => [200, 204],
         
     | 
| 
       412 
     | 
    
         
            -
                    :headers => {'Content-Type' => 'application/json'},
         
     | 
| 
       413 
     | 
    
         
            -
                    :body    => Fog::JSON.encode(request_body),
         
     | 
| 
       414 
     | 
    
         
            -
                    :method  => 'POST',
         
     | 
| 
       415 
     | 
    
         
            -
                    :path    => (uri.path and not uri.path.empty?) ? uri.path : 'v2.0'
         
     | 
| 
       416 
     | 
    
         
            -
                  }
         
     | 
| 
       417 
     | 
    
         
            -
                  request[:omit_default_port] = omit_default_port unless omit_default_port.nil?
         
     | 
| 
       418 
     | 
    
         
            -
             
     | 
| 
       419 
     | 
    
         
            -
                  response = identity_v2_connection.request(request)
         
     | 
| 
       420 
     | 
    
         
            -
             
     | 
| 
       421 
     | 
    
         
            -
                  Fog::JSON.decode(response.body)
         
     | 
| 
       422 
     | 
    
         
            -
                end
         
     | 
| 
       423 
     | 
    
         
            -
             
     | 
| 
       424 
     | 
    
         
            -
                def self.retrieve_tokens_v3(options, connection_options = {})
         
     | 
| 
       425 
     | 
    
         
            -
             
     | 
| 
       426 
     | 
    
         
            -
                  api_key           = options[:openstack_api_key].to_s
         
     | 
| 
       427 
     | 
    
         
            -
                  username          = options[:openstack_username].to_s
         
     | 
| 
       428 
     | 
    
         
            -
                  userid            = options[:openstack_userid]
         
     | 
| 
       429 
     | 
    
         
            -
                  domain_id         = options[:openstack_domain_id]
         
     | 
| 
       430 
     | 
    
         
            -
                  domain_name       = options[:openstack_domain_name]
         
     | 
| 
       431 
     | 
    
         
            -
                  project_domain    = options[:openstack_project_domain]
         
     | 
| 
       432 
     | 
    
         
            -
                  project_domain_id = options[:openstack_project_domain_id]
         
     | 
| 
       433 
     | 
    
         
            -
                  user_domain       = options[:openstack_user_domain]
         
     | 
| 
       434 
     | 
    
         
            -
                  user_domain_id    = options[:openstack_user_domain_id]
         
     | 
| 
       435 
     | 
    
         
            -
                  project_name      = options[:openstack_project_name]
         
     | 
| 
       436 
     | 
    
         
            -
                  project_id        = options[:openstack_project_id]
         
     | 
| 
       437 
     | 
    
         
            -
                  auth_token        = options[:openstack_auth_token] || options[:unscoped_token]
         
     | 
| 
       438 
     | 
    
         
            -
                  uri               = options[:openstack_auth_uri]
         
     | 
| 
       439 
     | 
    
         
            -
                  omit_default_port = options[:openstack_auth_omit_default_port]
         
     | 
| 
       440 
     | 
    
         
            -
                  cache_ttl         = options[:openstack_cache_ttl] || 0
         
     | 
| 
       441 
     | 
    
         
            -
             
     | 
| 
       442 
     | 
    
         
            -
                  connection = Fog::Core::Connection.new(uri.to_s, false, connection_options)
         
     | 
| 
       443 
     | 
    
         
            -
                  request_body = {:auth => {}}
         
     | 
| 
       444 
     | 
    
         
            -
             
     | 
| 
       445 
     | 
    
         
            -
                  scope = {}
         
     | 
| 
       446 
     | 
    
         
            -
             
     | 
| 
       447 
     | 
    
         
            -
                  if project_name || project_id
         
     | 
| 
       448 
     | 
    
         
            -
                    scope[:project] = if project_id.nil? then
         
     | 
| 
       449 
     | 
    
         
            -
                                        if project_domain || project_domain_id
         
     | 
| 
       450 
     | 
    
         
            -
                                          {:name => project_name, :domain => project_domain_id.nil? ? {:name => project_domain} : {:id => project_domain_id}}
         
     | 
| 
       451 
     | 
    
         
            -
                                        else
         
     | 
| 
       452 
     | 
    
         
            -
                                          {:name => project_name, :domain => domain_id.nil? ? {:name => domain_name} : {:id => domain_id}}
         
     | 
| 
       453 
     | 
    
         
            -
                                        end
         
     | 
| 
       454 
     | 
    
         
            -
                                      else
         
     | 
| 
       455 
     | 
    
         
            -
                                        {:id => project_id}
         
     | 
| 
       456 
     | 
    
         
            -
                                      end
         
     | 
| 
       457 
     | 
    
         
            -
                  elsif domain_name || domain_id
         
     | 
| 
       458 
     | 
    
         
            -
                    scope[:domain] = domain_id.nil? ? {:name => domain_name} : {:id => domain_id}
         
     | 
| 
       459 
     | 
    
         
            -
                  else
         
     | 
| 
       460 
     | 
    
         
            -
                    # unscoped token
         
     | 
| 
       461 
     | 
    
         
            -
                  end
         
     | 
| 
       462 
     | 
    
         
            -
             
     | 
| 
       463 
     | 
    
         
            -
                  if auth_token
         
     | 
| 
       464 
     | 
    
         
            -
                    request_body[:auth][:identity] = {
         
     | 
| 
       465 
     | 
    
         
            -
                        :methods => %w{token},
         
     | 
| 
       466 
     | 
    
         
            -
                        :token => {
         
     | 
| 
       467 
     | 
    
         
            -
                            :id => auth_token
         
     | 
| 
       468 
     | 
    
         
            -
                        }
         
     | 
| 
       469 
     | 
    
         
            -
                    }
         
     | 
| 
       470 
     | 
    
         
            -
                  else
         
     | 
| 
       471 
     | 
    
         
            -
                    request_body[:auth][:identity] = {
         
     | 
| 
       472 
     | 
    
         
            -
                        :methods => %w{password},
         
     | 
| 
       473 
     | 
    
         
            -
                        :password => {
         
     | 
| 
       474 
     | 
    
         
            -
                            :user => {
         
     | 
| 
       475 
     | 
    
         
            -
                                :password => api_key
         
     | 
| 
       476 
     | 
    
         
            -
                            }
         
     | 
| 
       477 
     | 
    
         
            -
                        }
         
     | 
| 
       478 
     | 
    
         
            -
                    }
         
     | 
| 
       479 
     | 
    
         
            -
             
     | 
| 
       480 
     | 
    
         
            -
                    if userid
         
     | 
| 
       481 
     | 
    
         
            -
                      request_body[:auth][:identity][:password][:user][:id] = userid
         
     | 
| 
       482 
     | 
    
         
            -
                    else
         
     | 
| 
       483 
     | 
    
         
            -
                      if user_domain || user_domain_id
         
     | 
| 
       484 
     | 
    
         
            -
                        request_body[:auth][:identity][:password][:user].merge! :domain => user_domain_id.nil? ? {:name => user_domain} : {:id => user_domain_id}
         
     | 
| 
       485 
     | 
    
         
            -
                      elsif domain_name || domain_id
         
     | 
| 
       486 
     | 
    
         
            -
                        request_body[:auth][:identity][:password][:user].merge! :domain => domain_id.nil? ? {:name => domain_name} : {:id => domain_id}
         
     | 
| 
       487 
     | 
    
         
            -
                      end
         
     | 
| 
       488 
     | 
    
         
            -
                      request_body[:auth][:identity][:password][:user][:name] = username
         
     | 
| 
       489 
     | 
    
         
            -
                    end
         
     | 
| 
       490 
     | 
    
         
            -
             
     | 
| 
       491 
     | 
    
         
            -
                  end
         
     | 
| 
       492 
     | 
    
         
            -
                  request_body[:auth][:scope] = scope unless scope.empty?
         
     | 
| 
       493 
     | 
    
         
            -
             
     | 
| 
       494 
     | 
    
         
            -
                  path     = (uri.path and not uri.path.empty?) ? uri.path : 'v3'
         
     | 
| 
       495 
     | 
    
         
            -
             
     | 
| 
       496 
     | 
    
         
            -
                  response, expires = Fog::OpenStack.token_cache[{:body => request_body, :path => path}] if cache_ttl > 0
         
     | 
| 
       497 
     | 
    
         
            -
             
     | 
| 
       498 
     | 
    
         
            -
                  unless response && expires > Time.now
         
     | 
| 
       499 
     | 
    
         
            -
                    request = {
         
     | 
| 
       500 
     | 
    
         
            -
                      :expects => [201],
         
     | 
| 
       501 
     | 
    
         
            -
                      :headers => {'Content-Type' => 'application/json'},
         
     | 
| 
       502 
     | 
    
         
            -
                      :body    => Fog::JSON.encode(request_body),
         
     | 
| 
       503 
     | 
    
         
            -
                      :method  => 'POST',
         
     | 
| 
       504 
     | 
    
         
            -
                      :path    => path
         
     | 
| 
       505 
     | 
    
         
            -
                    }
         
     | 
| 
       506 
     | 
    
         
            -
                    request[:omit_default_port] = omit_default_port unless omit_default_port.nil?
         
     | 
| 
       507 
     | 
    
         
            -
             
     | 
| 
       508 
     | 
    
         
            -
                    response = connection.request(request)
         
     | 
| 
       509 
     | 
    
         
            -
                    if cache_ttl > 0
         
     | 
| 
       510 
     | 
    
         
            -
                      cache = Fog::OpenStack.token_cache
         
     | 
| 
       511 
     | 
    
         
            -
                      cache[{:body => request_body, :path => path}] = response, Time.now + cache_ttl
         
     | 
| 
       512 
     | 
    
         
            -
                      Fog::OpenStack.token_cache = cache
         
     | 
| 
       513 
     | 
    
         
            -
                    end
         
     | 
| 
       514 
     | 
    
         
            -
                  end
         
     | 
| 
       515 
     | 
    
         
            -
             
     | 
| 
       516 
     | 
    
         
            -
                  [response.headers["X-Subject-Token"], Fog::JSON.decode(response.body)]
         
     | 
| 
       517 
     | 
    
         
            -
                end
         
     | 
| 
       518 
     | 
    
         
            -
             
     | 
| 
       519 
     | 
    
         
            -
                def self.get_service_v3(hash, service_type=[], service_name=nil, region=nil, options={})
         
     | 
| 
       520 
     | 
    
         
            -
             
     | 
| 
       521 
     | 
    
         
            -
                  # Find all services matching any of the types in service_type, filtered by service_name if it's non-nil
         
     | 
| 
       522 
     | 
    
         
            -
                  services = hash['token']['catalog'].find_all do |s|
         
     | 
| 
       523 
     | 
    
         
            -
                    if service_name.nil? or service_name.empty?
         
     | 
| 
       524 
     | 
    
         
            -
                      service_type.include?(s['type'])
         
     | 
| 
       525 
     | 
    
         
            -
                    else
         
     | 
| 
       526 
     | 
    
         
            -
                      service_type.include?(s['type']) and s['name'] == service_name
         
     | 
| 
       527 
     | 
    
         
            -
                    end
         
     | 
| 
       528 
     | 
    
         
            -
                  end if hash['token']['catalog']
         
     | 
| 
       529 
     | 
    
         
            -
             
     | 
| 
       530 
     | 
    
         
            -
                  # Filter the found services by region (if specified) and whether the endpoint path matches the given regex (e.g. /\/v3/)
         
     | 
| 
       531 
     | 
    
         
            -
                  services.find do |s|
         
     | 
| 
       532 
     | 
    
         
            -
                    s['endpoints'].any? { |ep| endpoint_region?(ep, region) && endpoint_path_match?(ep, options[:openstack_endpoint_path_matches])}
         
     | 
| 
       533 
     | 
    
         
            -
                  end if services
         
     | 
| 
       534 
     | 
    
         
            -
             
     | 
| 
       535 
     | 
    
         
            -
                end
         
     | 
| 
       536 
     | 
    
         
            -
             
     | 
| 
       537 
128 
     | 
    
         
             
                def self.endpoint_region?(endpoint, region)
         
     | 
| 
       538 
129 
     | 
    
         
             
                  region.nil? || endpoint['region'] == region
         
     | 
| 
       539 
130 
     | 
    
         
             
                end
         
     | 
| 
       540 
131 
     | 
    
         | 
| 
       541 
     | 
    
         
            -
                def self.endpoint_path_match?(endpoint, match_regex)
         
     | 
| 
       542 
     | 
    
         
            -
                  match_regex.nil? || URI(endpoint['url']).path =~ match_regex
         
     | 
| 
       543 
     | 
    
         
            -
                end
         
     | 
| 
       544 
     | 
    
         
            -
             
     | 
| 
       545 
132 
     | 
    
         
             
                def self.get_supported_version(supported_versions, uri, auth_token, connection_options = {})
         
     | 
| 
       546 
133 
     | 
    
         
             
                  supported_version = get_version(supported_versions, uri, auth_token, connection_options)
         
     | 
| 
       547 
134 
     | 
    
         
             
                  version = supported_version['id'] if supported_version
         
     | 
| 
         @@ -571,22 +158,14 @@ module Fog 
     | 
|
| 
       571 
158 
     | 
    
         
             
                  end
         
     | 
| 
       572 
159 
     | 
    
         
             
                end
         
     | 
| 
       573 
160 
     | 
    
         | 
| 
       574 
     | 
    
         
            -
                def self.map_endpoint_type type
         
     | 
| 
       575 
     | 
    
         
            -
                  case type
         
     | 
| 
       576 
     | 
    
         
            -
                    when "publicURL"
         
     | 
| 
       577 
     | 
    
         
            -
                      "public"
         
     | 
| 
       578 
     | 
    
         
            -
                    when "internalURL"
         
     | 
| 
       579 
     | 
    
         
            -
                      "internal"
         
     | 
| 
       580 
     | 
    
         
            -
                    when "adminURL"
         
     | 
| 
       581 
     | 
    
         
            -
                      "admin"
         
     | 
| 
       582 
     | 
    
         
            -
                  end
         
     | 
| 
       583 
     | 
    
         
            -
             
     | 
| 
       584 
     | 
    
         
            -
                end
         
     | 
| 
       585 
     | 
    
         
            -
             
     | 
| 
       586 
161 
     | 
    
         
             
                def self.get_version(supported_versions, uri, auth_token, connection_options = {})
         
     | 
| 
       587 
162 
     | 
    
         
             
                  version_cache = "#{uri}#{supported_versions}"
         
     | 
| 
       588 
163 
     | 
    
         
             
                  return @version[version_cache] if @version && @version[version_cache]
         
     | 
| 
       589 
     | 
    
         
            -
             
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
                  # To allow version discovery we need a "version less" endpoint
         
     | 
| 
      
 166 
     | 
    
         
            +
                  path = uri.path.gsub(/\/v([1-9]+\d*)(\.[1-9]+\d*)*.*$/, '/')
         
     | 
| 
      
 167 
     | 
    
         
            +
                  url = "#{uri.scheme}://#{uri.host}:#{uri.port}#{path}"
         
     | 
| 
      
 168 
     | 
    
         
            +
                  connection = Fog::Core::Connection.new(url, false, connection_options)
         
     | 
| 
       590 
169 
     | 
    
         
             
                  response = connection.request(
         
     | 
| 
       591 
170 
     | 
    
         
             
                    :expects => [200, 204, 300],
         
     | 
| 
       592 
171 
     | 
    
         
             
                    :headers => {'Content-Type' => 'application/json',
         
     | 
| 
         @@ -602,10 +181,17 @@ module Fog 
     | 
|
| 
       602 
181 
     | 
    
         
             
                end
         
     | 
| 
       603 
182 
     | 
    
         | 
| 
       604 
183 
     | 
    
         
             
                def self.extract_version_from_body(body, supported_versions)
         
     | 
| 
       605 
     | 
    
         
            -
                   
     | 
| 
       606 
     | 
    
         
            -
                   
     | 
| 
      
 184 
     | 
    
         
            +
                  versions = []
         
     | 
| 
      
 185 
     | 
    
         
            +
                  unless body['versions'].nil? || body['versions'].empty?
         
     | 
| 
      
 186 
     | 
    
         
            +
                    versions = body['versions'].kind_of?(Array) ? body['versions'] : body['versions']['values']
         
     | 
| 
      
 187 
     | 
    
         
            +
                  end
         
     | 
| 
      
 188 
     | 
    
         
            +
                  # Some version API would return single endpoint rather than endpoints list, try to get it via 'version'.
         
     | 
| 
      
 189 
     | 
    
         
            +
                  unless body['version'].nil? or versions.length != 0
         
     | 
| 
      
 190 
     | 
    
         
            +
                    versions = [body['version']]
         
     | 
| 
      
 191 
     | 
    
         
            +
                  end
         
     | 
| 
       607 
192 
     | 
    
         
             
                  version = nil
         
     | 
| 
       608 
     | 
    
         
            -
             
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
                  # order is important, preferred status should be first
         
     | 
| 
       609 
195 
     | 
    
         
             
                  %w(CURRENT stable SUPPORTED DEPRECATED).each do |status|
         
     | 
| 
       610 
196 
     | 
    
         
             
                    version = versions.find { |x| x['id'].match(supported_versions) && (x['status'] == status) }
         
     | 
| 
       611 
197 
     | 
    
         
             
                    break if version
         
     |