yao 0.3.7 → 0.3.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: d43c067685907e1e430dc8e003d9817fdf16f260
4
- data.tar.gz: 80d85a73f095c4bcb7f4805cc7aa23e548c77493
2
+ SHA256:
3
+ metadata.gz: 90d6e614a43f68cec261e6f44fa08445acfa614f0c3d940e6aaec21b17b874b7
4
+ data.tar.gz: 133aeb2173987b98cb8bdd16a47db04135e789be94f598a45853e19e4ffe0238
5
5
  SHA512:
6
- metadata.gz: c3f5118243d9ed662b34e981dcd15f4889475eeab02b5cfcea86af12e5afe677b873f538cf4e628ca9546ca0b03fc10ad49e01df0f5a9d00194d579b1c683d11
7
- data.tar.gz: 499c01244f7d5cda681ba5f0ad0baf68bbea8f9784d14a01630ef3d4cc8668ae2941509bf9de32bed2fa988c47861d8c667855cbc73150627f93a9120769389a
6
+ metadata.gz: 15f635d55f68d4f62f10335ec52046ad02bfb2ee3cbe3f6fbff75552b9d55f5b0cb8e876f19f51675538cbc286a9c02df6736356c1836173c93a822fc8f786ed
7
+ data.tar.gz: 07bec0d33bcb5565f774ed2a3d23d5525d2a594c46f6fb85c5ef5968af72cc2aedf49f13786b3aefae0a76993bcc29805dae60b4f8d0fe3f5aaf54861e3fd3e5
data/.rubocop.yml ADDED
@@ -0,0 +1,58 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.4
3
+ DisplayCopNames: true
4
+ DisabledByDefault: true
5
+ Exclude:
6
+ - 'vendor/**/*'
7
+
8
+ Style/HashSyntax:
9
+ Enabled: true
10
+
11
+ Layout/EmptyLines:
12
+ Enabled: true
13
+
14
+ Layout/TrailingBlankLines:
15
+ Enabled: true
16
+
17
+ Layout/TrailingWhitespace:
18
+ Enabled: true
19
+
20
+ Style/MethodDefParentheses:
21
+ Enabled: true
22
+
23
+ # Generated by gry
24
+
25
+ Layout/AccessModifierIndentation:
26
+ EnforcedStyle: indent
27
+ Enabled: true
28
+
29
+ Layout/CaseIndentation:
30
+ EnforcedStyle: end
31
+ Enabled: true
32
+
33
+ Style/Encoding:
34
+ Enabled: true
35
+
36
+ Style/For:
37
+ EnforcedStyle: each
38
+ Enabled: true
39
+
40
+ Style/FrozenStringLiteralComment:
41
+ EnforcedStyle: never
42
+ Enabled: true
43
+
44
+ Layout/MultilineHashBraceLayout:
45
+ EnforcedStyle: symmetrical
46
+ Enabled: true
47
+
48
+ Style/NumericLiteralPrefix:
49
+ EnforcedOctalStyle: zero_only
50
+ Enabled: true
51
+
52
+ Style/StabbyLambdaParentheses:
53
+ EnforcedStyle: require_parentheses
54
+ Enabled: true
55
+
56
+ Rails/ActionFilter:
57
+ EnforcedStyle: action
58
+ Enabled: true
data/.travis.yml CHANGED
@@ -12,9 +12,14 @@ cache:
12
12
  directories: vendor/bundle
13
13
 
14
14
  script:
15
+ - bundle exec rubocop
15
16
  - bundle exec rake test
16
17
  - find lib -name '*.rb' | xargs -i ruby -wc {}
17
18
 
18
19
  notifications:
19
20
  slack:
20
21
  secure: XhJ3SUF4I7a+MleHLEokgNrqROeCiTfVGzVOwFCTqVETurarb0s4FA5MGWgu7C9MCkIAVFLATwgIZQ9lo9MWFujVTh4Qj+rOdjI08c2ehVxwPyGMXbvkvqMRzvBbJuswnrXuJGUzxdCCjea64cdiZxguDiODp+cfjtKGSB59aNZoMsgwqVTppGDyXAThqZx/l2UKYjzONbnuCI9T9wt+UWW8nAMDn5zSTLVqVyK4GXs2ofGXswQlHvc7VlPLkmHVGm0ywazCyct+lo/Y9x1ofOeHZJllLRc5wccLxciCJBLJDrm/28LHy1PoidR5TXNRjp5ioJGVMwqvsBY8z3OwD8XVv6CPPGRYnEsJVT90R9HJoQ5YFHX5sDeGVbHSaX63eK4W7bn8MxqvEuQF5XU86B2xpLFOTKMK7HRKYjbToRKGMolj+1zv65orHM2Ts0ZtCuwa41oiYkRLWzSc9UDODn67OF+pJlEEYouljsGfcRYcv7JJ2rhFnFXi/9uISxzQMsP4L8dwEEJHxSkaSwJBMJf/it5hD4m5oO0oBQ1DRd3qg2ljpLPuzuY+pW1/R1JY1Z/DA4Kw7dvr8R0DJmXdDiWI9EYilYcP8Wk5qYlJdDGLEUfL8I+tz+e67wAzpqm9okE4gNiJ4HsS2MtztXCJgoSkBJVvhoEE9SXsYNICAno=
22
+
23
+ matrix:
24
+ allow_failures:
25
+ - rvm: ruby-head
data/Gemfile CHANGED
@@ -4,3 +4,4 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  gem 'travis'
7
+ gem 'rubocop'
data/lib/yao/auth.rb CHANGED
@@ -2,9 +2,11 @@ require 'json'
2
2
  require 'time'
3
3
 
4
4
  require 'yao/token'
5
+ require 'yao/tokenv3'
5
6
 
6
7
  module Yao
7
- %i(tenant_name username password timeout client_cert client_key region_name).each do |name|
8
+ %i(tenant_name username password timeout client_cert client_key region_name
9
+ identity_api_version user_domain_id user_domain_name project_domain_id project_domain_name).each do |name|
8
10
  Yao.config.param name, nil
9
11
  end
10
12
 
@@ -16,21 +18,72 @@ module Yao
16
18
  end
17
19
  end
18
20
 
21
+ def build_authv3_info(tenant_name, username, password,
22
+ user_domain_id, user_domain_name,
23
+ project_domain_id, project_domain_name)
24
+ identity = {
25
+ methods: ["password"],
26
+ password: {
27
+ user: { name: username, password: password }
28
+ }
29
+ }
30
+ if user_domain_id
31
+ identity[:password][:user][:domain] = { id: user_domain_id }
32
+ elsif user_domain_name
33
+ identity[:password][:user][:domain] = { name: user_domain_name }
34
+ end
35
+
36
+ scope = {
37
+ project: { name: tenant_name }
38
+ }
39
+ if project_domain_id
40
+ scope[:project][:domain] = { id: project_domain_id }
41
+ elsif project_domain_name
42
+ scope[:project][:domain] = { name: project_domain_name }
43
+ end
44
+
45
+ {
46
+ auth: {
47
+ identity: identity,
48
+ scope: scope
49
+ }
50
+ }
51
+ end
52
+
53
+ def build_auth_info(tenant_name, username, password)
54
+ auth_info = {
55
+ auth: {
56
+ passwordCredentials: {
57
+ username: username, password: password
58
+ }
59
+ }
60
+ }
61
+ auth_info[:auth][:tenantName] = tenant_name if tenant_name
62
+
63
+ auth_info
64
+ end
65
+
19
66
  def new(
20
67
  tenant_name: Yao.config.tenant_name,
21
68
  username: Yao.config.username,
22
- password: Yao.config.password
69
+ password: Yao.config.password,
70
+ identity_api_version: Yao.config.identity_api_version,
71
+ user_domain_id: Yao.config.user_domain_id,
72
+ user_domain_name: Yao.config.user_domain_name,
73
+ project_domain_id: Yao.config.project_domain_id,
74
+ project_domain_name: Yao.config.project_domain_name
23
75
  )
24
- auth_info = {
25
- auth: {
26
- passwordCredentials: {
27
- username: username, password: password
28
- }
29
- }
30
- }
31
- auth_info[:auth][:tenantName] = tenant_name if tenant_name
76
+ if identity_api_version.to_i == 3
77
+ auth_info = build_authv3_info(tenant_name, username, password,
78
+ user_domain_id, user_domain_name,
79
+ project_domain_id, project_domain_name)
80
+ issue = TokenV3.issue(Yao.default_client.default, auth_info)
81
+ else
82
+ auth_info = build_auth_info(tenant_name, username, password)
83
+ issue = Token.issue(Yao.default_client.default, auth_info)
84
+ end
32
85
 
33
- return Token.issue(Yao.default_client.default, auth_info)
86
+ issue
34
87
  end
35
88
  end
36
89
  end
@@ -16,7 +16,7 @@ module Yao::Plugins
16
16
  f.request :read_only
17
17
 
18
18
  f.response :os_error_detector
19
- f.response :json, :content_type => /\bjson$/
19
+ f.response :json, content_type: /\bjson$/
20
20
 
21
21
  if Yao.config.debug
22
22
  f.response :logger
@@ -2,8 +2,8 @@ require 'yao/resources/metadata_available'
2
2
  module Yao::Resources
3
3
  class Image < Base
4
4
  friendly_attributes :name, :status, :progress, :metadata
5
- map_attribute_to_attribute :minDisk => :min_disk
6
- map_attribute_to_attribute :minRam => :min_ram
5
+ map_attribute_to_attribute minDisk: :min_disk
6
+ map_attribute_to_attribute minRam: :min_ram
7
7
 
8
8
  def size(unit=nil)
9
9
  size = self["OS-EXT-IMG-SIZE:size"]
@@ -1,34 +1,33 @@
1
1
  module Yao::Resources
2
2
  class LoadBalancer < Base
3
3
  friendly_attributes :provider, :description, :admin_state_up, :provisioning_status,
4
- :pools, :vip_address,
5
- :operationg_status, :name
4
+ :vip_address, :operationg_status, :name
5
+
6
+ map_attribute_to_resources listeners: LoadBalancerListener
7
+ map_attribute_to_resources pools: LoadBalancerListener
6
8
 
7
9
  def project
8
- Yao::Tenant.find self["project_id"]
10
+ if project_id = self["project_id"]
11
+ Yao::Tenant.find project_id
12
+ end
9
13
  end
14
+ alias :tenant :project
10
15
 
11
16
  def vip_network
12
- Yao::Network.find self["vip_network_id"]
17
+ if vip_network_id = self["vip_network_id"]
18
+ Yao::Network.find vip_network_id
19
+ end
13
20
  end
14
21
 
15
22
  def vip_port
16
- Yao::Port.find self["vip_port_id"]
17
- end
18
-
19
- def vip_subnet
20
- Yao::Subnet.find self["vip_subnet_id"]
21
- end
22
-
23
- def listeners
24
- self["listeners"].map do |listener|
25
- Yao::LoadBalancerListener.find listener["id"]
23
+ if vip_port_id = self["vip_port_id"]
24
+ Yao::Port.find vip_port_id
26
25
  end
27
26
  end
28
27
 
29
- def pools
30
- self["pools"].map do |pool|
31
- Yao::LoadBalancerPool.find pool["id"]
28
+ def vip_subnet
29
+ if vip_subnet_id = self["vip_subnet_id"]
30
+ Yao::Subnet.find vip_subnet_id
32
31
  end
33
32
  end
34
33
 
@@ -5,11 +5,22 @@ module Yao::Resources
5
5
  :http_method, :timeout, :max_retries_down,
6
6
  :url_path, :type, :operating_status
7
7
 
8
- def pools
9
- self["pools"].map do |pool|
10
- Yao::LoadBalancerPool.find pool["id"]
8
+ map_attribute_to_resources pools: LoadBalancerListener
9
+
10
+ def created_at
11
+ Date.parse(self["created_at"])
12
+ end
13
+
14
+ def updated_at
15
+ Date.parse(self["updated_at"])
16
+ end
17
+
18
+ def project
19
+ if project_id = self["project_id"]
20
+ Yao::Tenant.find project_id
11
21
  end
12
22
  end
23
+ alias :tenant :project
13
24
 
14
25
  self.service = "load-balancer"
15
26
  self.api_version = "v2.0"
@@ -6,18 +6,19 @@ module Yao::Resources
6
6
  :operating_status, :sni_container_refs,
7
7
  :l7policies, :name
8
8
 
9
- def project
10
- Yao::Tenant.find self["project_id"]
11
- end
9
+ map_attribute_to_resources loadbalancers: LoadBalancer
12
10
 
13
- def loadbalancers
14
- self["loadbalancers"].map do |loadbalancer|
15
- Yao::LoadBalancer.get loadbalancer["id"]
11
+ def project
12
+ if project_id = self["project_id"]
13
+ Yao::Tenant.find project_id
16
14
  end
17
15
  end
16
+ alias :tenant :project
18
17
 
19
18
  def default_pool
20
- Yao::LoadBalancerPool.find self["default_pool_id"]
19
+ if default_pool_id = self["default_pool_id"]
20
+ Yao::LoadBalancerPool.find default_pool_id
21
+ end
21
22
  end
22
23
  alias pool default_pool
23
24
 
@@ -2,12 +2,17 @@ module Yao::Resources
2
2
  class LoadBalancerPool < Base
3
3
  friendly_attributes :lb_algorithm, :protocol, :description,
4
4
  :admin_state_up, :provisioning_status,
5
- :session_persistence, :operating_status, :name,
5
+ :session_persistence, :operating_status, :name
6
6
 
7
- def loadbalancers
8
- self["loadbalancers"].map do |loadbalancer|
9
- Yao::LoadBalancer.find loadbalancer["id"]
10
- end
7
+ map_attribute_to_resources loadbalancers: LoadBalancer
8
+ map_attribute_to_resources listeners: LoadBalancerListener
9
+
10
+ def created_at
11
+ Date.parse(self["created_at"])
12
+ end
13
+
14
+ def updated_at
15
+ Date.parse(self["updated_at"])
11
16
  end
12
17
 
13
18
  def listeners
@@ -17,8 +22,11 @@ module Yao::Resources
17
22
  end
18
23
 
19
24
  def project
20
- Yao::Tenant.find self["project_id"]
25
+ if project_id = self["project_id"]
26
+ Yao::Tenant.find project_id
27
+ end
21
28
  end
29
+ alias :tenant :project
22
30
 
23
31
  def members
24
32
  self["members"].map do |member|
@@ -27,7 +35,9 @@ module Yao::Resources
27
35
  end
28
36
 
29
37
  def healthmonitor
30
- Yao::LoadBalancerHealthMonitor.find self["healthmonitor_id"]
38
+ if healthmonitor_id = self["healthmonitor_id"]
39
+ Yao::LoadBalancerHealthMonitor.find healthmonitor_id
40
+ end
31
41
  end
32
42
 
33
43
  self.service = "load-balancer"
@@ -6,11 +6,16 @@ module Yao::Resources
6
6
  :protocol_port, :operating_status
7
7
 
8
8
  def project
9
- Yao::Tenant.find self["project_id"]
9
+ if project_id = self["project_id"]
10
+ Yao::Tenant.find project_id
11
+ end
10
12
  end
13
+ alias :tenant :project
11
14
 
12
15
  def subnet
13
- Yao::Subnet.find self["subnet_id"]
16
+ if subnet_id = self["subnet_id"]
17
+ Yao::Subnet.find subnet_id
18
+ end
14
19
  end
15
20
 
16
21
  self.service = "load-balancer"
@@ -84,16 +84,22 @@ module Yao::Resources
84
84
  end
85
85
  end
86
86
 
87
- def get(id_or_permalink, query={})
88
- res = if id_or_permalink =~ /^https?:\/\//
87
+ def get(id_or_name_or_permalink, query={})
88
+ res = if id_or_name_or_permalink =~ /^https?:\/\//
89
89
  GET(id_or_permalink, query)
90
+ elsif uuid?(id_or_name_or_permalink)
91
+ GET([resources_path, id_or_name_or_permalink].join("/"), query)
90
92
  else
91
- GET([resources_path, id_or_permalink].join("/"), query)
93
+ find_by_name(id_or_name_or_permalink, query)
92
94
  end
93
95
  return_resource(resource_from_json(res.body))
94
96
  end
95
97
  alias find get
96
98
 
99
+ def find_by_name(name, query={})
100
+ list(query.merge({"name" => name}))
101
+ end
102
+
97
103
  def create(resource_params)
98
104
  params = {
99
105
  resource_name_in_json => resource_params
@@ -142,5 +148,9 @@ module Yao::Resources
142
148
  def return_resources(arr)
143
149
  arr.map{|d| return_resource(d) }
144
150
  end
151
+
152
+ def uuid?(str)
153
+ /^[\da-f]{8}-([\da-f]{4}-){3}[\da-f]{12}$/ === str
154
+ end
145
155
  end
146
156
  end
@@ -12,7 +12,7 @@ module Yao::Resources
12
12
  @project ||= Yao::Tenant.get(scope["project"]["id"])
13
13
  end
14
14
 
15
- map_attribute_to_resource :role => Role
16
- map_attribute_to_resource :user => User
15
+ map_attribute_to_resource role: Role
16
+ map_attribute_to_resource user: User
17
17
  end
18
18
  end
@@ -4,10 +4,10 @@ module Yao::Resources
4
4
  class Server < Base
5
5
  friendly_attributes :addresses, :metadata, :name, :progress,
6
6
  :status, :tenant_id, :user_id, :key_name
7
- map_attribute_to_attribute :hostId => :host_id
8
- map_attribute_to_resource :flavor => Flavor
9
- map_attribute_to_resource :image => Image
10
- map_attribute_to_resources :security_groups => SecurityGroup
7
+ map_attribute_to_attribute hostId: :host_id
8
+ map_attribute_to_resource flavor: Flavor
9
+ map_attribute_to_resource image: Image
10
+ map_attribute_to_resources security_groups: SecurityGroup
11
11
 
12
12
  map_attribute_to_attribute 'OS-EXT-AZ:availability_zone' => :availability_zone
13
13
  map_attribute_to_attribute 'OS-DCF:diskConfig' => :dcf_disk_config
@@ -0,0 +1,72 @@
1
+ require 'yao/client'
2
+
3
+ module Yao
4
+ class TokenV3
5
+ def self.issue(cli, auth_info)
6
+ t = new(auth_info)
7
+ t.refresh(cli)
8
+ t
9
+ end
10
+
11
+ def initialize(auth_info, token_data=nil)
12
+ @auth_info = auth_info
13
+
14
+ @endpoints = {}
15
+ end
16
+ attr_accessor :auth_info, :token, :issued_at, :expire_at, :endpoints
17
+ alias expires expire_at
18
+ alias to_s token
19
+
20
+ def register(response)
21
+ @token = response.headers["X-Subject-Token"]
22
+
23
+ token_data = response.body["token"]
24
+ @issued_at = Time.parse(token_data["issued_at"]).localtime
25
+ @expire_at = Time.parse(token_data["expires_at"]).localtime
26
+ Yao.current_tenant_id token_data["project"]["id"]
27
+ end
28
+
29
+ def expired?
30
+ return true unless self.expire_at
31
+ Time.now >= self.expire_at
32
+ end
33
+
34
+ def refresh(cli)
35
+ @endpoints.clear
36
+
37
+ res = cli.post("#{Yao.config.auth_url}/auth/tokens") do |req|
38
+ req.body = auth_info.to_json
39
+ req.headers['Content-Type'] = 'application/json'
40
+ end
41
+
42
+ register(res)
43
+ register_endpoints(res.body["token"]["catalog"])
44
+ self
45
+ end
46
+
47
+ def register_endpoints(_endpoints)
48
+ return unless _endpoints
49
+
50
+ _endpoints.each do |endpoint_data|
51
+ type = endpoint_data["type"]
52
+ region_name = Yao.config.region_name ? Yao.config.region_name : 'RegionOne'
53
+ endpoints = endpoint_data["endpoints"].select { |ep| ep.has_value?(region_name) }
54
+ urls = {}
55
+ endpoints.each do |ep|
56
+ name = "#{ep["interface"]}_url".to_sym
57
+ urls[name] = ep["url"]
58
+ end
59
+ @endpoints[type] = urls
60
+ end
61
+
62
+ Yao.default_client.register_endpoints(@endpoints, token: self)
63
+ end
64
+ end
65
+
66
+ def self.current_tenant_id(id=nil)
67
+ if id
68
+ @__tenant_id = id
69
+ end
70
+ @__tenant_id
71
+ end
72
+ end
data/lib/yao/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Yao
2
- VERSION = "0.3.7"
2
+ VERSION = "0.3.8"
3
3
  end
data/test/config.rb CHANGED
@@ -4,6 +4,7 @@ require 'power_assert'
4
4
  require 'yao'
5
5
 
6
6
  require 'support/auth_stub'
7
+ require 'support/authv3_stub'
7
8
 
8
9
  require 'webmock/test_unit'
9
10
 
@@ -4,9 +4,9 @@ module AuthStub
4
4
  .with(
5
5
  body: auth_json(username, password, tenant)
6
6
  ).to_return(
7
- :status => 200,
8
- :body => response_json(auth_url, username, tenant),
9
- :headers => {'Content-Type' => 'application/json'}
7
+ status: 200,
8
+ body: response_json(auth_url, username, tenant),
9
+ headers: {'Content-Type' => 'application/json'}
10
10
  )
11
11
  end
12
12
 
@@ -0,0 +1,308 @@
1
+ module AuthV3Stub
2
+ def stub_auth_request(auth_url, username, password, tenant, user_domain_name, project_domain_name)
3
+ stub_request(:post, "#{auth_url}/auth/tokens")
4
+ .with(
5
+ body: auth_json(username, password, tenant, user_domain_name, project_domain_name)
6
+ ).to_return(
7
+ status: 200,
8
+ body: response_json(auth_url, username, tenant, user_domain_name, project_domain_name),
9
+ headers: {
10
+ 'Content-Type' => 'application/json',
11
+ 'X-Subject-Token' => 'aaaa166533fd49f3b11b1cdce2430000'
12
+ }
13
+ )
14
+ end
15
+
16
+ private
17
+
18
+ def auth_json(username, password, tenant, user_domain_name, project_domain_name)
19
+ json = <<-JSON
20
+ {"auth":{"identity":{"methods":["password"],"password":{"user":{"name":"#{username}","password":"XXXXXXXX","domain":{"name":"#{user_domain_name}"}}}},"scope":{"project":{"name":"#{tenant}","domain":{"name":"#{project_domain_name}"}}}}}
21
+ JSON
22
+
23
+ json.strip
24
+ end
25
+
26
+ def response_json(auth_url, username, tenant, user_domain_name, project_domain_name)
27
+ <<-JSON
28
+ {
29
+ "token": {
30
+ "methods": ["password"],
31
+ "roles": [{
32
+ "id": "aaaa166533fd49f3b11b1cdce2430000",
33
+ "name": "admin"
34
+ }],
35
+ "issued_at": "#{Time.now.iso8601}",
36
+ "expires_at": "#{(Time.now + 3600).utc.iso8601}",
37
+ "project": {
38
+ "domain": {
39
+ "id": "aaaa166533fd49f3b11b1cdce2430000",
40
+ "name": "#{project_domain_name}"
41
+ },
42
+ "id": "aaaa166533fd49f3b11b1cdce2430000",
43
+ "name": "#{project_domain_name}"
44
+ },
45
+ "catalog": [
46
+ {
47
+ "endpoints": [
48
+ {
49
+ "region_id": "RegionOne",
50
+ "url": "http://nova-endpoint.example.com:8774/v2/b598bf98671c47e1b955f8c9660e3c44",
51
+ "region": "RegionOne",
52
+ "interface": "internal",
53
+ "id": "1a66e6af97c440b2a7bbc4f9735923d9"
54
+ },
55
+ {
56
+ "region_id": "RegionOne",
57
+ "url": "http://nova-endpoint.example.com:8774/v2/b598bf98671c47e1b955f8c9660e3c44",
58
+ "region": "RegionOne",
59
+ "interface": "public",
60
+ "id": "1a66e6af97c440b2a7bbc4f9735923d9"
61
+ },
62
+ {
63
+ "region_id": "RegionOne",
64
+ "url": "http://nova-endpoint.example.com:8774/v2/b598bf98671c47e1b955f8c9660e3c44",
65
+ "region": "RegionOne",
66
+ "interface": "admin",
67
+ "id": "1a66e6af97c440b2a7bbc4f9735923d9"
68
+ },
69
+ {
70
+ "region_id": "RegionTest",
71
+ "url": "http://global-endpoint.example.com:8774/v2/b598bf98671c47e1b955f8c9660e3c44",
72
+ "region": "RegionTest",
73
+ "interface": "internal",
74
+ "id": "1a66e6af97c440b2a7bbc4f9735923d9"
75
+ },
76
+ {
77
+ "region_id": "RegionTest",
78
+ "url": "http://global-endpoint.example.com:8774/v2/b598bf98671c47e1b955f8c9660e3c44",
79
+ "region": "RegionTest",
80
+ "interface": "public",
81
+ "id": "1a66e6af97c440b2a7bbc4f9735923d9"
82
+ },
83
+ {
84
+ "region_id": "RegionTest",
85
+ "url": "http://global-endpoint.example.com:8774/v2/b598bf98671c47e1b955f8c9660e3c44",
86
+ "region": "RegionTest",
87
+ "interface": "admin",
88
+ "id": "1a66e6af97c440b2a7bbc4f9735923d9"
89
+ }
90
+ ],
91
+ "type": "compute",
92
+ "id": "a226b3eeb5594f50bf8b6df94636ed28",
93
+ "name": "nova"
94
+ },
95
+ {
96
+ "endpoints": [
97
+ {
98
+ "region_id": "RegionOne",
99
+ "url": "http://neutron-endpoint.example.com:9696/",
100
+ "region": "RegionOne",
101
+ "interface": "internal",
102
+ "id": "0418104da877468ca65d739142fa3454"
103
+ },
104
+ {
105
+ "region_id": "RegionOne",
106
+ "url": "http://neutron-endpoint.example.com:9696/",
107
+ "region": "RegionOne",
108
+ "interface": "public",
109
+ "id": "0418104da877468ca65d739142fa3454"
110
+ },
111
+ {
112
+ "region_id": "RegionTest",
113
+ "url": "http://global-endpoint.example.com:9696/",
114
+ "region": "RegionTest",
115
+ "interface": "admin",
116
+ "id": "0418104da877468ca65d739142fa3454"
117
+ },
118
+ {
119
+ "region_id": "RegionTest",
120
+ "url": "http://global-endpoint.example.com:9696/",
121
+ "region": "RegionTest",
122
+ "interface": "internal",
123
+ "id": "0418104da877468ca65d739142fa3454"
124
+ },
125
+ {
126
+ "region_id": "RegionTest",
127
+ "url": "http://global-endpoint.example.com:9696/",
128
+ "region": "RegionTest",
129
+ "interface": "public",
130
+ "id": "0418104da877468ca65d739142fa3454"
131
+ },
132
+ {
133
+ "region_id": "RegionTest",
134
+ "url": "http://global-endpoint.example.com:9696/",
135
+ "region": "RegionTest",
136
+ "interface": "admin",
137
+ "id": "0418104da877468ca65d739142fa3454"
138
+ }
139
+ ],
140
+ "type": "network",
141
+ "id": "67b993549db94296a853d635b48db3c9",
142
+ "name": "neutron"
143
+ },
144
+ {
145
+ "endpoints": [
146
+ {
147
+ "region_id": "RegionOne",
148
+ "url": "http://glance-endpoint.example.com:9292",
149
+ "region": "RegionOne",
150
+ "interface": "internal",
151
+ "id": "246f33509ff64802b86eb081307ecec0"
152
+ },
153
+ {
154
+ "region_id": "RegionOne",
155
+ "url": "http://glance-endpoint.example.com:9292",
156
+ "region": "RegionOne",
157
+ "interface": "public",
158
+ "id": "246f33509ff64802b86eb081307ecec0"
159
+ },
160
+ {
161
+ "region_id": "RegionOne",
162
+ "url": "http://glance-endpoint.example.com:9292",
163
+ "region": "RegionOne",
164
+ "interface": "admin",
165
+ "id": "246f33509ff64802b86eb081307ecec0"
166
+ },
167
+ {
168
+ "region_id": "RegionTest",
169
+ "url": "http://global-endpoint.example.com:9292",
170
+ "region": "RegionTest",
171
+ "interface": "internal",
172
+ "id": "246f33509ff64802b86eb081307ecec0"
173
+ },
174
+ {
175
+ "region_id": "RegionTest",
176
+ "url": "http://global-endpoint.example.com:9292",
177
+ "region": "RegionTest",
178
+ "interface": "public",
179
+ "id": "246f33509ff64802b86eb081307ecec0"
180
+ },
181
+ {
182
+ "region_id": "RegionTest",
183
+ "url": "http://global-endpoint.example.com:9292",
184
+ "region": "RegionOne",
185
+ "interface": "admin",
186
+ "id": "246f33509ff64802b86eb081307ecec0"
187
+ }
188
+ ],
189
+ "type": "image",
190
+ "id": "d512f8860c0f45cf99b1c3cef86cfd97",
191
+ "name": "glance"
192
+ },
193
+ {
194
+ "endpoints": [
195
+ {
196
+ "region_id": "RegionOne",
197
+ "url": "http://endpoint.example.com:5000/v2.0",
198
+ "region": "RegionOne",
199
+ "interface": "internal",
200
+ "id": "2b982236cc084128bf42b647c1b7fb49"
201
+ },
202
+ {
203
+ "region_id": "RegionOne",
204
+ "url": "http://endpoint.example.com:5000/v2.0",
205
+ "region": "RegionOne",
206
+ "interface": "public",
207
+ "id": "2b982236cc084128bf42b647c1b7fb49"
208
+ },
209
+ {
210
+ "region_id": "RegionOne",
211
+ "url": "#{auth_url}",
212
+ "region": "RegionOne",
213
+ "interface": "admin",
214
+ "id": "2b982236cc084128bf42b647c1b7fb49"
215
+ },
216
+ {
217
+ "region_id": "RegionTest",
218
+ "url": "https://global-endpoint.example.com/api/keystone/",
219
+ "region": "RegionTest",
220
+ "interface": "internal",
221
+ "id": "2b982236cc084128bf42b647c1b7fb49"
222
+ },
223
+ {
224
+ "region_id": "RegionTest",
225
+ "url": "https://global-endpoint.example.com/api/keystone/",
226
+ "region": "RegionTest",
227
+ "interface": "public",
228
+ "id": "2b982236cc084128bf42b647c1b7fb49"
229
+ },
230
+ {
231
+ "region_id": "RegionTest",
232
+ "url": "https://global-endpoint.example.com/api/admin/keystone/",
233
+ "region": "RegionTest",
234
+ "interface": "admin",
235
+ "id": "2b982236cc084128bf42b647c1b7fb49"
236
+ }
237
+ ],
238
+ "type": "identity",
239
+ "id": "050726f278654128aba89757ae25950c",
240
+ "name": "keystone"
241
+ },
242
+ {
243
+ "endpoints": [
244
+ {
245
+ "region_id": "RegionOne",
246
+ "internalurl": "http://octavia-endpoint.example.com:9876",
247
+ "region": "RegionOne",
248
+ "interface": "internal",
249
+ "id": "bde3abca8864400a809f0089f025370a"
250
+ },
251
+ {
252
+ "region_id": "RegionOne",
253
+ "internalurl": "http://octavia-endpoint.example.com:9876",
254
+ "region": "RegionOne",
255
+ "interface": "public",
256
+ "id": "bde3abca8864400a809f0089f025370a"
257
+ },
258
+ {
259
+ "region_id": "RegionOne",
260
+ "internalurl": "http://octavia-endpoint.example.com:9876",
261
+ "region": "RegionOne",
262
+ "interface": "admin",
263
+ "id": "bde3abca8864400a809f0089f025370a"
264
+ },
265
+ {
266
+ "region_id": "RegionTest",
267
+ "internalurl": "http://global-endpoint.example.com:9876",
268
+ "region": "RegionTest",
269
+ "interface": "internal",
270
+ "id": "bde3abca8864400a809f0089f025370a"
271
+ },
272
+ {
273
+ "region_id": "RegionTest",
274
+ "internalurl": "http://global-endpoint.example.com:9876",
275
+ "region": "RegionTest",
276
+ "interface": "public",
277
+ "id": "bde3abca8864400a809f0089f025370a"
278
+ },
279
+ {
280
+ "region_id": "RegionTest",
281
+ "internalurl": "http://global-endpoint.example.com:9876",
282
+ "region": "RegionTest",
283
+ "interface": "admin",
284
+ "id": "bde3abca8864400a809f0089f025370a"
285
+ }
286
+ ],
287
+ "type": "load-balancer",
288
+ "id": "a5f7070bda40443fa3819fbdf1689af1",
289
+ "name": "octavia"
290
+ }
291
+ ],
292
+ "user": {
293
+ "domain": {
294
+ "id": "a9994b2dee82423da7da572397d3157a",
295
+ "name": "#{user_domain_name}"
296
+ },
297
+ "name": "#{username}",
298
+ "id": "a9994b2dee82423da7da572397d3157a",
299
+ "name": "#{username}"
300
+ },
301
+ "audit_ids": [
302
+ "3t2dc1cgqxyjshddu1xkcw"
303
+ ]
304
+ }
305
+ }
306
+ JSON
307
+ end
308
+ end
@@ -14,7 +14,7 @@ class TestRole < Test::Unit::TestCase
14
14
  "updated_at" => "2017-02-28T00:43:30",
15
15
  }
16
16
 
17
- lb = Yao::LoadBalancer.new(params)
17
+ lb = Yao::Resources::LoadBalancer.new(params)
18
18
  assert_equal(lb.provider, "octavia")
19
19
  assert_equal(lb.description, "greate loadbalancer")
20
20
  assert_equal(lb.admin_state_up, true)
@@ -17,9 +17,9 @@ class TestRole < Test::Unit::TestCase
17
17
  "url_path" => "/",
18
18
  "type" => "HTTP",
19
19
  "operating_status" => "ONLINE"
20
- }
20
+ }
21
21
 
22
- healthmonitor = Yao::LoadBalancerHealthMonitor.new(params)
22
+ healthmonitor = Yao::Resources::LoadBalancerHealthMonitor.new(params)
23
23
  assert_equal(healthmonitor.name, "super-pool-health-monitor")
24
24
  assert_equal(healthmonitor.admin_state_up, true)
25
25
  assert_equal(healthmonitor.created, Time.parse("2017-05-11T23:53:47"))
@@ -29,7 +29,7 @@ class TestRole < Test::Unit::TestCase
29
29
  "name" => "great_tls_listener"
30
30
  }
31
31
 
32
- listener = Yao::LoadBalancerListener.new(params)
32
+ listener = Yao::Resources::LoadBalancerListener.new(params)
33
33
  assert_equal(listener.description, "A great TLS listener")
34
34
  assert_equal(listener.admin_state_up, true)
35
35
  assert_equal(listener.protocol, "TERMINATED_HTTPS")
@@ -18,7 +18,7 @@ class TestRole < Test::Unit::TestCase
18
18
  "name" => "round_robin_pool"
19
19
  }
20
20
 
21
- pool = Yao::LoadBalancerPool.new(params)
21
+ pool = Yao::Resources::LoadBalancerPool.new(params)
22
22
  assert_equal(pool.lb_algorithm, "ROUND_ROBIN")
23
23
  assert_equal(pool.protocol, "HTTP")
24
24
  assert_equal(pool.description, "My round robin pool")
@@ -16,7 +16,7 @@ class TestRole < Test::Unit::TestCase
16
16
  "operating_status" => "NO_MONITOR"
17
17
  }
18
18
 
19
- member = Yao::LoadBalancerPoolMember.new(params)
19
+ member = Yao::Resources::LoadBalancerPoolMember.new(params)
20
20
  assert_equal(member.monitor_port, 8080)
21
21
  assert_equal(member.name, "web-server-1")
22
22
  assert_equal(member.weight, 20)
@@ -0,0 +1,26 @@
1
+ class TestRestfullyAccesible < Test::Unit::TestCase
2
+ include Yao::Resources::RestfullyAccessible
3
+
4
+ def test_get
5
+ mock(self).find_by_name("dummy", {}) { Struct.new(:body).new("dummy") }
6
+ mock(self).resource_from_json("dummy") { "dummy" }
7
+ mock(self).return_resource("dummy") { "dummy" }
8
+
9
+ get("dummy")
10
+ RR.verify
11
+ end
12
+
13
+ def test_find_by_name
14
+ mock(self).list({"name" => "dummy"}) { "dummy" }
15
+
16
+ assert_equal(find_by_name("dummy"), "dummy")
17
+ end
18
+
19
+ def test_uuid?
20
+ assert_equal(uuid?("00112233-4455-6677-8899-aabbccddeeff"), true)
21
+
22
+ # not uuid
23
+ assert_equal(uuid?("dummy resource"), false)
24
+ assert_equal(uuid?("00112233445566778899aabbccddeeff"), false)
25
+ end
26
+ end
@@ -87,4 +87,10 @@ class TestAuth < Test::Unit::TestCase
87
87
  end
88
88
  end
89
89
 
90
+ def test_build_auth_info
91
+ auth_info = Yao::Auth.build_auth_info("example", "udzura", "XXXXXXXX")
92
+ assert { auth_info[:auth][:tenantName] == "example" }
93
+ assert { auth_info[:auth][:passwordCredentials][:username] == "udzura" }
94
+ assert { auth_info[:auth][:passwordCredentials][:password] == "XXXXXXXX" }
95
+ end
90
96
  end
@@ -0,0 +1,121 @@
1
+ class TestAuthV3 < Test::Unit::TestCase
2
+ include AuthV3Stub
3
+
4
+ def setup
5
+ @auth_url = "http://endpoint.example.com:12345/v3"
6
+ username = "udzura"
7
+ tenant = "example"
8
+ password = "XXXXXXXX"
9
+ identity_api_version = "3"
10
+ user_domain_name = "default"
11
+ project_domain_name = "default"
12
+
13
+ stub_auth_request(@auth_url, username, password, tenant, user_domain_name, project_domain_name)
14
+
15
+ Yao.config.set :auth_url, @auth_url
16
+ @token = Yao::Auth.new(tenant_name: tenant, username: username, password: password,
17
+ identity_api_version: identity_api_version,
18
+ user_domain_name: user_domain_name, project_domain_name: project_domain_name)
19
+ end
20
+
21
+ def teardown
22
+ Yao.configure do
23
+ endpoints nil
24
+ identity_api_version nil
25
+ end
26
+ end
27
+
28
+ def test_auth_successful
29
+ cli = Yao.default_client.pool["default"]
30
+ assert { cli.url_prefix.to_s == "http://endpoint.example.com:12345/v3" }
31
+ end
32
+
33
+ def test_service_sclients_initialized
34
+ %w(compute network image identity).each do |service|
35
+ cli = Yao.default_client.pool[service]
36
+ assert { !cli.nil? }
37
+ end
38
+ end
39
+
40
+ def test_nova_tenant_logged_in
41
+ tenant_id = "b598bf98671c47e1b955f8c9660e3c44"
42
+ cli = Yao.default_client.compute
43
+ assert { cli.url_prefix.to_s == "http://nova-endpoint.example.com:8774/v2/#{tenant_id}" }
44
+ end
45
+
46
+ def test_neutron_prefix_added
47
+ cli = Yao.default_client.network
48
+ assert { cli.url_prefix.to_s == "http://neutron-endpoint.example.com:9696/v2.0" }
49
+ end
50
+
51
+ def test_token_is_valid
52
+ assert { @token.token == "aaaa166533fd49f3b11b1cdce2430000" }
53
+ assert { @token.expire_at - @token.issued_at == 3600 }
54
+ assert { @token.endpoints.size == 5 }
55
+ end
56
+
57
+ def test_hooked_by_configure_block
58
+ auth = Yao::Auth
59
+ stub(auth).new
60
+
61
+ Yao.configure do
62
+ auth_url "http://endpoint.example.com:12345/v2.0"
63
+ tenant_name "example"
64
+ username "udzura"
65
+ password "XXXXXXXX"
66
+ identity_api_version "3"
67
+ user_domain_name "default"
68
+ project_domain_name "default"
69
+ end
70
+ assert_received(auth) {|a| a.new }
71
+ end
72
+
73
+ def test_override_endpoint
74
+ Yao.configure do
75
+ auth_url "http://endpoint.example.com:12345/v3"
76
+ tenant_name "example"
77
+ username "udzura"
78
+ password "XXXXXXXX"
79
+ identity_api_version "3"
80
+ user_domain_name "default"
81
+ project_domain_name "default"
82
+ endpoints ({ identity: { public: "http://override-endpoint.example.com:35357/v3.0" } })
83
+ end
84
+ assert { Yao.default_client.pool["identity"].url_prefix.to_s == "http://override-endpoint.example.com:35357/v3.0" }
85
+ end
86
+
87
+ def test_region
88
+ Yao.configure do
89
+ auth_url "http://endpoint.example.com:12345/v3"
90
+ tenant_name "example"
91
+ username "udzura"
92
+ password "XXXXXXXX"
93
+ identity_api_version "3"
94
+ user_domain_name "default"
95
+ project_domain_name "default"
96
+ region_name "RegionTest"
97
+ end
98
+ assert { Yao.default_client.pool["identity"].url_prefix.to_s == "https://global-endpoint.example.com/api/keystone/" }
99
+ ensure
100
+ Yao.configure do
101
+ region_name "RegionOne"
102
+ end
103
+ end
104
+
105
+ def test_build_authv3_info
106
+ auth_info = Yao::Auth.build_authv3_info("example", "udzura", "XXXXXXXX", "default", nil, "default", nil)
107
+
108
+ user = auth_info[:auth][:identity][:password][:user]
109
+ assert { user[:name] == "udzura" }
110
+ assert { user[:password] == "XXXXXXXX" }
111
+ assert { user[:domain][:id] == "default" }
112
+
113
+ project = auth_info[:auth][:scope][:project]
114
+ assert { project[:name] == "example" }
115
+ assert { project[:domain][:id] == "default" }
116
+
117
+ auth_info = Yao::Auth.build_authv3_info("example", "udzura", "XXXXXXXX", nil, "default", nil, "default")
118
+ assert { auth_info[:auth][:identity][:password][:user][:domain][:name] == "default" }
119
+ assert { auth_info[:auth][:scope][:project][:domain][:name] == "default" }
120
+ end
121
+ end
@@ -21,7 +21,7 @@ class TestClientPlugin < Test::Unit::TestCase
21
21
 
22
22
  class ::Yao::Plugins::TestCustomClientGenerator
23
23
  def call(f, t)
24
- f.response :xml, :content_type => /\/xml$/
24
+ f.response :xml, content_type: /\/xml$/
25
25
  end
26
26
  ::Yao::Plugins.register self, type: :client_generator, name: :test_custom
27
27
  end
@@ -0,0 +1,108 @@
1
+ class TestTokenV3 < Test::Unit::TestCase
2
+ include AuthV3Stub
3
+
4
+ class TestResponse
5
+ attr :headers, :body
6
+
7
+ def initialize
8
+ @headers = Hash.new
9
+ @body = Hash.new
10
+ end
11
+ end
12
+
13
+ def setup
14
+ stub(Yao.config).debug { false }
15
+ stub(Yao.config).debug_record_response { false }
16
+ end
17
+
18
+ def test_expired
19
+ t = Yao::TokenV3.new({})
20
+ r = TestResponse.new
21
+ r.headers["X-Subject-Token"] = "aaaa166533fd49f3b11b1cdce2430000"
22
+ r.body["token"] = {
23
+ "issued_at" => Time.now.iso8601,
24
+ "expires_at" => (Time.now - 3600).utc.iso8601,
25
+ "project" => {
26
+ "id" => "aaaa166533fd49f3b11b1cdce2430000"
27
+ }
28
+ }
29
+ t.register(r)
30
+
31
+ assert { t.expired? }
32
+
33
+ r.body["token"] = {
34
+ "issued_at" => Time.now.iso8601,
35
+ "expires_at" => (Time.now + 3600).utc.iso8601,
36
+ "project" => {
37
+ "id" => "aaaa166533fd49f3b11b1cdce2430000"
38
+ }
39
+ }
40
+ t.register(r)
41
+ assert { ! t.expired? }
42
+ end
43
+
44
+ def test_refresh
45
+ auth_url = "http://endpoint.example.com:12345/v3"
46
+ username = "udzura"
47
+ tenant = "example"
48
+ password = "XXXXXXXX"
49
+ identity_api_version = 3
50
+ user_domain_name = "default"
51
+ project_domain_name = "default"
52
+
53
+ auth_info = {
54
+ auth: {
55
+ identity: {
56
+ methods: ["password"],
57
+ password: {
58
+ user: {
59
+ name: username, password: password,
60
+ domain: { name: user_domain_name },
61
+ }
62
+ }
63
+ },
64
+ scope: {
65
+ project: {
66
+ name: tenant,
67
+ domain: { name: project_domain_name },
68
+ }
69
+ }
70
+ }
71
+ }
72
+ t = Yao::TokenV3.new(auth_info)
73
+ r = TestResponse.new
74
+ r.headers["X-Subject-Token"] = "old_token"
75
+ r.body["token"] = {
76
+ "issued_at" => Time.now.iso8601,
77
+ "expires_at" => (Time.now - 3600).utc.iso8601,
78
+ "project" => {
79
+ "id" => "aaaa166533fd49f3b11b1cdce2430000"
80
+ }
81
+ }
82
+ t.register(r)
83
+ assert { t.token == "old_token" }
84
+
85
+ stub_auth_request(auth_url, username, password, tenant, user_domain_name, project_domain_name)
86
+
87
+ Yao.config.auth_url auth_url
88
+ t.refresh(Yao.default_client.default)
89
+
90
+ assert { t.token == "aaaa166533fd49f3b11b1cdce2430000" }
91
+ end
92
+
93
+ def test_current_tenant_id
94
+ t = Yao::TokenV3.new({})
95
+ r = TestResponse.new
96
+ r.headers["X-Subject-Token"] = "aaaa166533fd49f3b11b1cdce2430000"
97
+ r.body["token"] = {
98
+ "issued_at" => Time.now.iso8601,
99
+ "expires_at" => (Time.now - 3600).utc.iso8601,
100
+ "project" => {
101
+ "id" => "aaaa166533fd49f3b11b1cdce2430000"
102
+ }
103
+ }
104
+ t.register(r)
105
+
106
+ assert { Yao.current_tenant_id == "aaaa166533fd49f3b11b1cdce2430000" }
107
+ end
108
+ end
data/yao.gemspec CHANGED
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  lib = File.expand_path('../lib', __FILE__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'yao/version'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yao
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.7
4
+ version: 0.3.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Uchio, KONDO
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-27 00:00:00.000000000 Z
11
+ date: 2018-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -158,6 +158,7 @@ extensions: []
158
158
  extra_rdoc_files: []
159
159
  files:
160
160
  - ".gitignore"
161
+ - ".rubocop.yml"
161
162
  - ".travis.yml"
162
163
  - CHANGELOG.md
163
164
  - CODE_OF_CONDUCT.md
@@ -210,11 +211,13 @@ files:
210
211
  - lib/yao/resources/user.rb
211
212
  - lib/yao/setup.rb
212
213
  - lib/yao/token.rb
214
+ - lib/yao/tokenv3.rb
213
215
  - lib/yao/version.rb
214
216
  - test/config.rb
215
217
  - test/fixtures/dummy.key
216
218
  - test/fixtures/dummy.pem
217
219
  - test/support/auth_stub.rb
220
+ - test/support/authv3_stub.rb
218
221
  - test/yao/resources/test_aggregates.rb
219
222
  - test/yao/resources/test_base.rb
220
223
  - test/yao/resources/test_hypervisor.rb
@@ -223,17 +226,20 @@ files:
223
226
  - test/yao/resources/test_loadbalancer_listener.rb
224
227
  - test/yao/resources/test_loadbalancer_pool.rb
225
228
  - test/yao/resources/test_loadbalancer_pool_member.rb
229
+ - test/yao/resources/test_restfully_accessible.rb
226
230
  - test/yao/resources/test_role.rb
227
231
  - test/yao/resources/test_security_group.rb
228
232
  - test/yao/resources/test_security_group_rule.rb
229
233
  - test/yao/resources/test_user.rb
230
234
  - test/yao/test_auth.rb
235
+ - test/yao/test_authv3.rb
231
236
  - test/yao/test_client.rb
232
237
  - test/yao/test_client_plugin.rb
233
238
  - test/yao/test_config.rb
234
239
  - test/yao/test_read_only.rb
235
240
  - test/yao/test_server_error.rb
236
241
  - test/yao/test_token.rb
242
+ - test/yao/test_tokenv3.rb
237
243
  - yao-logo.png
238
244
  - yao.gemspec
239
245
  homepage: https://github.com/yaocloud/yao
@@ -256,7 +262,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
256
262
  version: '0'
257
263
  requirements: []
258
264
  rubyforge_project:
259
- rubygems_version: 2.4.5
265
+ rubygems_version: 2.7.3
260
266
  signing_key:
261
267
  specification_version: 4
262
268
  summary: Yet Another OpenStack API Wrapper that rocks!!
@@ -265,6 +271,7 @@ test_files:
265
271
  - test/fixtures/dummy.key
266
272
  - test/fixtures/dummy.pem
267
273
  - test/support/auth_stub.rb
274
+ - test/support/authv3_stub.rb
268
275
  - test/yao/resources/test_aggregates.rb
269
276
  - test/yao/resources/test_base.rb
270
277
  - test/yao/resources/test_hypervisor.rb
@@ -273,14 +280,17 @@ test_files:
273
280
  - test/yao/resources/test_loadbalancer_listener.rb
274
281
  - test/yao/resources/test_loadbalancer_pool.rb
275
282
  - test/yao/resources/test_loadbalancer_pool_member.rb
283
+ - test/yao/resources/test_restfully_accessible.rb
276
284
  - test/yao/resources/test_role.rb
277
285
  - test/yao/resources/test_security_group.rb
278
286
  - test/yao/resources/test_security_group_rule.rb
279
287
  - test/yao/resources/test_user.rb
280
288
  - test/yao/test_auth.rb
289
+ - test/yao/test_authv3.rb
281
290
  - test/yao/test_client.rb
282
291
  - test/yao/test_client_plugin.rb
283
292
  - test/yao/test_config.rb
284
293
  - test/yao/test_read_only.rb
285
294
  - test/yao/test_server_error.rb
286
295
  - test/yao/test_token.rb
296
+ - test/yao/test_tokenv3.rb