yao 0.15.0 → 0.16.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rubocop.yml +2 -2
  3. data/.github/workflows/ubuntu-rvm.yml +1 -1
  4. data/.github/workflows/ubuntu.yml +2 -2
  5. data/lib/yao/resources/base.rb +17 -5
  6. data/lib/yao/resources/flavor.rb +10 -0
  7. data/lib/yao/resources/floating_ip.rb +1 -7
  8. data/lib/yao/resources/loadbalancer_pool.rb +10 -20
  9. data/lib/yao/resources/meter.rb +1 -1
  10. data/lib/yao/resources/network.rb +1 -1
  11. data/lib/yao/resources/old_sample.rb +1 -1
  12. data/lib/yao/resources/port.rb +1 -1
  13. data/lib/yao/resources/{tenant_associationable.rb → project_associationable.rb} +5 -5
  14. data/lib/yao/resources/resource.rb +1 -1
  15. data/lib/yao/resources/restfully_accessible.rb +3 -2
  16. data/lib/yao/resources/role_assignment.rb +2 -2
  17. data/lib/yao/resources/router.rb +19 -10
  18. data/lib/yao/resources/security_group.rb +1 -1
  19. data/lib/yao/resources/server.rb +1 -1
  20. data/lib/yao/resources/subnet.rb +1 -1
  21. data/lib/yao/resources/volume.rb +2 -0
  22. data/lib/yao/resources.rb +1 -1
  23. data/lib/yao/version.rb +1 -1
  24. data/test/yao/resources/test_base.rb +21 -0
  25. data/test/yao/resources/test_flavor.rb +67 -33
  26. data/test/yao/resources/test_floating_ip.rb +5 -5
  27. data/test/yao/resources/test_loadbalancer_pool.rb +146 -1
  28. data/test/yao/resources/test_meter.rb +5 -5
  29. data/test/yao/resources/test_network.rb +6 -6
  30. data/test/yao/resources/test_port.rb +6 -6
  31. data/test/yao/resources/test_restfully_accessible.rb +46 -4
  32. data/test/yao/resources/test_role_assignment.rb +3 -3
  33. data/test/yao/resources/test_router.rb +33 -12
  34. data/test/yao/resources/test_security_group.rb +5 -5
  35. data/test/yao/resources/test_server.rb +6 -6
  36. data/test/yao/resources/test_subnet.rb +6 -6
  37. data/test/yao/resources/test_volume.rb +21 -0
  38. data/yao.gemspec +1 -1
  39. metadata +6 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b2448b0a2070a9d61401c29e6f53445a4cb0c9bbd8f1bc98aac172661d6d9bc0
4
- data.tar.gz: 0f50c66bd6fd508c0b47132c672395da04037cb4dd59842d48006c386d19f9fb
3
+ metadata.gz: edb91db2ac62cf431603c29ce61eaaf16f522827e455b563f0bcb2922af0fe18
4
+ data.tar.gz: 23b08a38cba8ac2d59fda37c33f9854ba0f88b8a3110e613439ba466014bbbc7
5
5
  SHA512:
6
- metadata.gz: 4e6553ffc603ead2c2ec1d4a4fcc133381b3b4065f7cdce8df9705a8776ab7cf916d1d49d7cc59f5b5453c55b8d8bb1890cec7c35ace2d67f698a43e72f11450
7
- data.tar.gz: 0b79462e8a112e7b12f490f8d24e3839b80792d2f4247fee849963c07b4b3b732d3d773a9b4806f27427812e80823e27b7f69a2e0ea198f5286bb7c18439b85c
6
+ metadata.gz: 8d1e378004468dfaf40ea14866a8404c9936f3f2276f5492767cae69178bd323dd3f8bbb5cf82e45a87b72fd9d1b8b3f495ddd745562098abc44c2b25e41570b
7
+ data.tar.gz: 3bab6f8e27cad21a6bd704276fc26dcd2ec50e1e7d3af9cd22b9911ff4b10e0daea2022fd40fc480fe215665a466d8aeb86f2713850b868345b5144ba9a0fb35
@@ -8,9 +8,9 @@ jobs:
8
8
  steps:
9
9
  - uses: actions/checkout@master
10
10
  - name: Set up Ruby
11
- uses: actions/setup-ruby@v1
11
+ uses: ruby/setup-ruby@v1
12
12
  with:
13
- ruby-version: 3.0
13
+ ruby-version: 3.1
14
14
  - name: Install dependencies
15
15
  run: |
16
16
  gem install bundler --no-document
@@ -7,7 +7,7 @@ jobs:
7
7
  runs-on: ubuntu-latest
8
8
  strategy:
9
9
  matrix:
10
- ruby: [ 'ruby-3.0.3' ]
10
+ ruby: [ 'ruby-3.1.1' ]
11
11
  steps:
12
12
  - uses: actions/checkout@master
13
13
  - name: Set up RVM
@@ -7,11 +7,11 @@ jobs:
7
7
  runs-on: ubuntu-latest
8
8
  strategy:
9
9
  matrix:
10
- ruby: [3.0, 2.7, 2.6]
10
+ ruby: [3.1, 3.0, 2.7]
11
11
  steps:
12
12
  - uses: actions/checkout@master
13
13
  - name: Set up Ruby
14
- uses: actions/setup-ruby@v1
14
+ uses: ruby/setup-ruby@v1
15
15
  with:
16
16
  ruby-version: ${{ matrix.ruby }}
17
17
  - name: Install dependencies
@@ -8,9 +8,6 @@ module Yao::Resources
8
8
  def self.friendly_attributes(*names)
9
9
  names.map(&:to_s).each do |name|
10
10
  define_method(name) do
11
- if !@data.key?(name) && id
12
- @data = self.class.get(id).to_hash
13
- end
14
11
  self[name]
15
12
  end
16
13
  end
@@ -58,6 +55,9 @@ module Yao::Resources
58
55
  # @param name [String]
59
56
  # @return [String]
60
57
  def [](name)
58
+ unless @data["id"].nil? || @data.key?(name) || name.include?("__")
59
+ @data = self.class.get(@data["id"]).to_hash
60
+ end
61
61
  @data[name]
62
62
  end
63
63
 
@@ -80,18 +80,30 @@ module Yao::Resources
80
80
 
81
81
  # @return [Date]
82
82
  def created
83
- if date = self["created"] || self["created_at"]
83
+ if date = self["created_at"] || self["created"]
84
84
  Time.parse(date)
85
85
  end
86
86
  end
87
87
 
88
88
  # @return [Date]
89
89
  def updated
90
- if date = self["updated"] || self["updated_at"]
90
+ if date = self["updated_at"] || self["updated"]
91
91
  Time.parse(date)
92
92
  end
93
93
  end
94
94
 
95
+ # @param resource_params [Hash]
96
+ # @return [Yao::Resources::*]
97
+ def update(resource_params)
98
+ self.class.update(id, resource_params)
99
+ end
100
+
101
+ # @return [String]
102
+ def destroy
103
+ self.class.destroy(id)
104
+ end
105
+ alias delete destroy
106
+
95
107
  extend RestfullyAccessible
96
108
  end
97
109
  end
@@ -20,5 +20,15 @@ module Yao::Resources
20
20
  self.resource_name = "flavor"
21
21
  self.resources_name = "flavors"
22
22
  self.resources_detail_available = true
23
+
24
+ class << self
25
+ # override Yao::Resources::RestfullyAccessible#find_by_name
26
+ # @return [Array<Yao::Resources::Role>]
27
+ def find_by_name(name, query={})
28
+ list(query).select do |flavor|
29
+ flavor.name == name
30
+ end
31
+ end
32
+ end
23
33
  end
24
34
  end
@@ -2,7 +2,7 @@ module Yao::Resources
2
2
  class FloatingIP < Base
3
3
 
4
4
  include PortAssociationable
5
- include TenantAssociationable
5
+ include ProjectAssociationable
6
6
 
7
7
  friendly_attributes :router_id, :description, :dns_domain, :dns_name,
8
8
  :revision_number,
@@ -18,11 +18,5 @@ module Yao::Resources
18
18
  def router
19
19
  @router ||= Yao::Router.get(router_id)
20
20
  end
21
-
22
- # @return [Yao::Resources::Tenant]
23
- def project
24
- @project ||= Yao::Tenant.get(project_id)
25
- end
26
- alias :tenant :project
27
21
  end
28
22
  end
@@ -7,21 +7,11 @@ module Yao::Resources
7
7
  map_attribute_to_resources loadbalancers: LoadBalancer
8
8
  map_attribute_to_resources listeners: LoadBalancerListener
9
9
 
10
- # @return [Date]
11
- def created_at
12
- Date.parse(self["created_at"])
13
- end
14
-
15
- # @return [Date]
16
- def updated_at
17
- Date.parse(self["updated_at"])
18
- end
19
-
20
10
  # @return [Yao::Resources::LoadBalancerListener]
21
11
  def listeners
22
- self["listeners"].map do |listener|
23
- Yao::LoadBalancerListener.find listener["id"]
24
- end
12
+ @listeners ||= self["listeners"].map do |listener|
13
+ Yao::LoadBalancerListener.get(listener["id"])
14
+ end
25
15
  end
26
16
 
27
17
  # @return [Yao::Resources::Tenant]
@@ -32,18 +22,18 @@ module Yao::Resources
32
22
  end
33
23
  alias :tenant :project
34
24
 
35
- # @return [Yao::Resources::LoadBalancerListener]
25
+ # @return [Yao::Resources::LoadBalancerPoolMember]
36
26
  def members
37
- self["members"].map do |member|
38
- Yao::LoadBalancerPoolMember.find(self,member["id"])
39
- end
27
+ @members ||= self["members"].map do |member|
28
+ Yao::LoadBalancerPoolMember.get(self, member["id"])
29
+ end
40
30
  end
41
31
 
42
32
  # @return [Yao::Resources::LoadBalancerHealthMonitor]
43
33
  def healthmonitor
44
- if healthmonitor_id = self["healthmonitor_id"]
45
- Yao::LoadBalancerHealthMonitor.find healthmonitor_id
46
- end
34
+ @healthmonitor ||= if healthmonitor_id = self["healthmonitor_id"]
35
+ Yao::LoadBalancerHealthMonitor.get(healthmonitor_id)
36
+ end
47
37
  end
48
38
 
49
39
  self.service = "load-balancer"
@@ -1,7 +1,7 @@
1
1
  module Yao::Resources
2
2
  class Meter < Base
3
3
 
4
- include TenantAssociationable
4
+ include ProjectAssociationable
5
5
 
6
6
  friendly_attributes :meter_id, :name, :user_id, :resource_id, :source, :type, :unit
7
7
 
@@ -1,6 +1,6 @@
1
1
  module Yao::Resources
2
2
  class Network < Base
3
- include TenantAssociationable
3
+ include ProjectAssociationable
4
4
 
5
5
  friendly_attributes :name, :status, :shared, :subnets, :admin_state_up
6
6
  map_attribute_to_attribute "provider:physical_network" => :physical_network
@@ -1,6 +1,6 @@
1
1
  module Yao::Resources
2
2
  class OldSample < Base
3
- include TenantAssociationable
3
+ include ProjectAssociationable
4
4
 
5
5
  friendly_attributes :counter_name, :counter_type, :counter_unit, :counter_volume,
6
6
  :message_id, :resource_id, :timestamp, :resource_metadata, :user_id,
@@ -2,7 +2,7 @@ module Yao::Resources
2
2
  class Port < Base
3
3
 
4
4
  include NetworkAssociationable
5
- include TenantAssociationable
5
+ include ProjectAssociationable
6
6
 
7
7
  friendly_attributes :name, :mac_address, :status, :allowed_address_pairs,
8
8
  :device_owner, :fixed_ips, :security_groups, :device_id,
@@ -1,18 +1,18 @@
1
1
  module Yao
2
2
  module Resources
3
- module TenantAssociationable
3
+ module ProjectAssociationable
4
4
 
5
5
  def self.included(base)
6
6
  base.friendly_attributes :project_id
7
7
  base.friendly_attributes :tenant_id
8
8
  end
9
9
 
10
- # @return [Yao::Resources::Tenant]
11
- def tenant
12
- @tenant ||= Yao::Tenant.find(project_id || tenant_id)
10
+ # @return [Yao::Resources::Project]
11
+ def project
12
+ @project ||= Yao::Project.find(project_id || tenant_id)
13
13
  end
14
14
 
15
- alias :project :tenant
15
+ alias :tenant :project
16
16
  end
17
17
  end
18
18
  end
@@ -1,7 +1,7 @@
1
1
  require 'time'
2
2
  module Yao::Resources
3
3
  class Resource < Base
4
- include TenantAssociationable
4
+ include ProjectAssociationable
5
5
 
6
6
  friendly_attributes :user_id, :resource_id,
7
7
  :last_sample_timestamp, :first_sample_timestamp,
@@ -148,7 +148,7 @@ module Yao::Resources
148
148
  # @return [Yao::Resources::*]
149
149
  def get!(id_or_name_or_permalink, query={})
150
150
  get(id_or_name_or_permalink, query)
151
- rescue Yao::ItemNotFound, Yao::NotFound
151
+ rescue Yao::ItemNotFound, Yao::NotFound, Yao::InvalidResponse
152
152
  nil
153
153
  end
154
154
 
@@ -188,6 +188,7 @@ module Yao::Resources
188
188
  res = DELETE(create_url(id))
189
189
  res.body
190
190
  end
191
+ alias delete destroy
191
192
 
192
193
  private
193
194
 
@@ -238,7 +239,7 @@ module Yao::Resources
238
239
  GET(create_url(name), query)
239
240
  rescue => e
240
241
  raise e unless e.class == Yao::ItemNotFound || e.class == Yao::NotFound
241
- item = find_by_name(name)
242
+ item = find_by_name(name).select { |r| r.name == name }
242
243
  if item.size > 1
243
244
  raise Yao::TooManyItemFonud.new("More than one resource exists with the name '#{name}'")
244
245
  elsif item.size.zero?
@@ -11,9 +11,9 @@ module Yao::Resources
11
11
  self.admin = true
12
12
  self.api_version = "v3"
13
13
 
14
- # @return [Yao::Resources::Tenant]
14
+ # @return [Yao::Resources::Project]
15
15
  def project
16
- @project ||= Yao::Tenant.get(scope["project"]["id"])
16
+ @project ||= Yao::Project.get(scope["project"]["id"])
17
17
  end
18
18
 
19
19
  class << self
@@ -1,15 +1,31 @@
1
1
  module Yao::Resources
2
2
  class Router < Base
3
- include TenantAssociationable
3
+ include ProjectAssociationable
4
4
 
5
5
  friendly_attributes :name, :description, :admin_state_up, :status, :external_gateway_info,
6
- :network_id, :enable_snat, :external_fixed_ips, :routes, :destination, :nexthop, :distributed,
7
- :ha, :availability_zone_hints, :availability_zones
6
+ :routes, :distributed, :ha, :availability_zone_hints, :availability_zones
8
7
 
9
8
  self.service = 'network'
10
9
  self.resource_name = 'router'
11
10
  self.resources_name = 'routers'
12
11
 
12
+ # @return [bool]
13
+ def enable_snat
14
+ external_gateway_info["enable_snat"]
15
+ end
16
+
17
+ # @return [Array<Hash>]
18
+ def external_fixed_ips
19
+ external_gateway_info["external_fixed_ips"]
20
+ end
21
+
22
+ # @return [Yao::Resource::Network]
23
+ def external_network
24
+ @external_network ||= if network_id = external_gateway_info["network_id"]
25
+ Yao::Network.get(network_id)
26
+ end
27
+ end
28
+
13
29
  # @return [Array<Yao::Resources::Port>]
14
30
  def interfaces
15
31
  Yao::Port.list(device_id: id)
@@ -29,13 +45,6 @@ module Yao::Resources
29
45
  def remove_interface(id, param)
30
46
  PUT(['routers', id, 'remove_router_interface.json'].join('/'), param.to_json)
31
47
  end
32
-
33
- # @param name [String]
34
- # @return [Array<Yao::Resources::Router>]
35
- def get_by_name(name)
36
- self.list(name: name)
37
- end
38
- alias find_by_name get_by_name
39
48
  end
40
49
  end
41
50
  end
@@ -1,7 +1,7 @@
1
1
  require 'yao/resources/security_group_rule'
2
2
  module Yao::Resources
3
3
  class SecurityGroup < Base
4
- include TenantAssociationable
4
+ include ProjectAssociationable
5
5
 
6
6
  friendly_attributes :name, :description
7
7
 
@@ -2,7 +2,7 @@ require 'yao/resources/metadata_available'
2
2
  require 'yao/resources/action'
3
3
  module Yao::Resources
4
4
  class Server < Base
5
- include TenantAssociationable
5
+ include ProjectAssociationable
6
6
 
7
7
  friendly_attributes :addresses, :metadata, :name, :progress,
8
8
  :status, :user_id, :key_name
@@ -2,7 +2,7 @@ module Yao::Resources
2
2
  class Subnet < Base
3
3
 
4
4
  include NetworkAssociationable
5
- include TenantAssociationable
5
+ include ProjectAssociationable
6
6
 
7
7
  friendly_attributes :name, :cidr, :gateway_ip, :network_id, :ip_version,
8
8
  :dns_nameservers, :host_routes, :enable_dhcp
@@ -2,6 +2,8 @@ require 'yao/resources/volume_action'
2
2
 
3
3
  module Yao::Resources
4
4
  class Volume < Base
5
+ include ProjectAssociationable
6
+
5
7
  friendly_attributes :attachments, :availability_zone, :bootable, :descriptions, :encrypted, :metadata, :multiattach, :name, :replication_status, :size, :snapshot_id, :status, :user_id, :volume_type
6
8
  alias :type :volume_type
7
9
 
data/lib/yao/resources.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Yao
2
2
  module Resources
3
3
  require "yao/resources/base"
4
- require "yao/resources/tenant_associationable"
4
+ require "yao/resources/project_associationable"
5
5
  require "yao/resources/port_associationable"
6
6
  require "yao/resources/network_associationable"
7
7
  require "yao/resources/server_usage_associationable"
data/lib/yao/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Yao
2
- VERSION = "0.15.0"
2
+ VERSION = "0.16.0"
3
3
  end
@@ -23,4 +23,25 @@ class TestResourceBase < TestYaoResource
23
23
  assert_equal(nil, base.empty)
24
24
  end
25
25
 
26
+ def test_update
27
+ stub(Yao::Resources::Base).update('foo', {name: 'BAR'}) { Yao::Resources::Base.new('id' => 'foo', 'name' => 'BAR')}
28
+ base = Yao::Resources::Base.new({'id' => 'foo', 'name' => 'bar'})
29
+ got = base.update(name: 'BAR')
30
+ assert_equal(got.name, 'BAR')
31
+ end
32
+
33
+ def test_destroy
34
+ stub(Yao::Resources::Base).destroy('foo') { nil }
35
+ base = Yao::Resources::Base.new({'id' => 'foo'})
36
+ got = base.destroy
37
+ assert_equal(got, nil)
38
+ end
39
+
40
+ def test_delete
41
+ stub(Yao::Resources::Base).destroy('foo') { nil }
42
+ base = Yao::Resources::Base.new({'id' => 'foo'})
43
+ got = base.delete
44
+ assert_equal(got, nil)
45
+ end
46
+
26
47
  end
@@ -46,48 +46,64 @@ class TestFlavor < TestYaoResource
46
46
  assert_equal(512, flavor.memory)
47
47
  end
48
48
 
49
- def test_list
50
- stub = stub_request(:get, "https://example.com:12345/flavors/detail").
49
+ def flavor_detail
50
+ JSON.parse(<<~JSON)
51
+ {
52
+ "OS-FLV-DISABLED:disabled": false,
53
+ "disk": 20,
54
+ "OS-FLV-EXT-DATA:ephemeral": 0,
55
+ "os-flavor-access:is_public": true,
56
+ "id": "7",
57
+ "links": [
58
+ {
59
+ "href": "http://openstack.example.com/v2/6f70656e737461636b20342065766572/flavors/7",
60
+ "rel": "self"
61
+ },
62
+ {
63
+ "href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/7",
64
+ "rel": "bookmark"
65
+ }
66
+ ],
67
+ "name": "m1.small.description",
68
+ "ram": 2048,
69
+ "swap": 0,
70
+ "vcpus": 1,
71
+ "rxtx_factor": 1.0,
72
+ "description": "test description",
73
+ "extra_specs": {
74
+ "hw:cpu_policy": "shared",
75
+ "hw:numa_nodes": "1"
76
+ }
77
+ }
78
+ JSON
79
+ end
80
+
81
+ def stub_flavors_detail(query=nil)
82
+ url = ['https://example.com:12345/flavors/detail',query].compact.join('?')
83
+ stub_request(:get, url).
51
84
  to_return(
52
85
  status: 200,
53
- body: <<-JSON,
54
- {
55
- "flavors": [
56
- {
57
- "OS-FLV-DISABLED:disabled": false,
58
- "disk": 1,
59
- "OS-FLV-EXT-DATA:ephemeral": 0,
60
- "os-flavor-access:is_public": true,
61
- "id": "1",
62
- "links": [
63
- {
64
- "href": "http://openstack.example.com/v2/6f70656e737461636b20342065766572/flavors/1",
65
- "rel": "self"
66
- },
67
- {
68
- "href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/1",
69
- "rel": "bookmark"
70
- }
71
- ],
72
- "name": "m1.tiny",
73
- "ram": 512,
74
- "swap": "",
75
- "vcpus": 1,
76
- "rxtx_factor": 1.0,
77
- "description": null,
78
- "extra_specs": {}
79
- }
80
- ]
81
- }
82
- JSON
86
+ body: { flavors:[flavor_detail] }.to_json,
83
87
  headers: {'Content-Type' => 'application/json'}
84
88
  )
89
+ end
85
90
 
91
+ def stub_flavor(id)
92
+ stub_request(:get, "https://example.com:12345/flavors/#{id}").
93
+ to_return(
94
+ status: 200,
95
+ body: { 'flavor': flavor_detail }.to_json,
96
+ headers: {'Content-Type' => 'application/json'}
97
+ )
98
+ end
99
+
100
+ def test_list
101
+ stub = stub_flavors_detail
86
102
  assert(Yao::Flavor.resources_detail_available)
87
103
 
88
104
  flavors = Yao::Flavor.list
89
105
  assert_instance_of(Yao::Flavor, flavors.first)
90
- assert_equal("m1.tiny", flavors.first.name)
106
+ assert_equal("m1.small.description", flavors.first.name)
91
107
 
92
108
  assert_requested(stub)
93
109
  end
@@ -97,4 +113,22 @@ class TestFlavor < TestYaoResource
97
113
  # see also: https://stackoverflow.com/questions/25883618/how-to-test-method-alias-ruby
98
114
  assert_equal(Yao::Flavor.method(:list), Yao::Flavor.method(:list_detail))
99
115
  end
116
+
117
+ def test_get_by_id
118
+ stub = stub_flavor(7)
119
+ flavor = Yao::Flavor.get('7')
120
+ assert_equal('m1.small.description', flavor.name)
121
+ assert_requested(stub)
122
+ end
123
+
124
+ def test_get_by_name
125
+ stub = stub_request(:get, "https://example.com:12345/flavors/m1.small.description").to_return(status: 404)
126
+ stub2 = stub_flavors_detail
127
+ stub3 = stub_flavor(7)
128
+ flavor = Yao::Flavor.get('m1.small.description')
129
+ assert_equal('7', flavor.id)
130
+ assert_requested(stub)
131
+ assert_requested(stub2)
132
+ assert_requested(stub3)
133
+ end
100
134
  end
@@ -82,14 +82,14 @@ class TestFloatingIP < TestYaoResource
82
82
  assert_requested(stub)
83
83
  end
84
84
 
85
- def test_tenant
85
+ def test_project
86
86
 
87
- stub = stub_request(:get, "https://example.com:12345/tenants/0123456789abcdef0123456789abcdef")
87
+ stub = stub_request(:get, "https://example.com:12345/projects/0123456789abcdef0123456789abcdef")
88
88
  .to_return(
89
89
  status: 200,
90
90
  body: <<-JSON,
91
91
  {
92
- "tenant": {
92
+ "project": {
93
93
  "id": "0123456789abcdef0123456789abcdef"
94
94
  }
95
95
  }
@@ -102,8 +102,8 @@ class TestFloatingIP < TestYaoResource
102
102
  "tenant_id" => "0123456789abcdef0123456789abcdef",
103
103
  )
104
104
 
105
- assert_instance_of(Yao::Tenant, fip.tenant)
106
- assert_instance_of(Yao::Tenant, fip.project)
105
+ assert_instance_of(Yao::Project, fip.tenant)
106
+ assert_instance_of(Yao::Project, fip.project)
107
107
  assert_equal('0123456789abcdef0123456789abcdef', fip.tenant.id)
108
108
 
109
109
  assert_requested(stub)
@@ -13,7 +13,14 @@ class TestLoadBalancerPool < TestYaoResource
13
13
  "type" => "SOURCE_IP"
14
14
  },
15
15
  "operating_status" => "ONLINE",
16
- "name" => "round_robin_pool"
16
+ "name" => "round_robin_pool",
17
+ "members" => [
18
+ {"id" => "957a1ace-1bd2-449b-8455-820b6e4b63f3"},
19
+ ],
20
+ "listeners" => [
21
+ {"id" => "023f2e34-7806-443b-bfae-16c324569a3d"}
22
+ ],
23
+ "healthmonitor_id" => "8ed3c5ac-6efa-420c-bedb-99ba14e58db5",
17
24
  }
18
25
 
19
26
  pool = Yao::Resources::LoadBalancerPool.new(params)
@@ -30,5 +37,143 @@ class TestLoadBalancerPool < TestYaoResource
30
37
  }, pool.session_persistence)
31
38
  assert_equal("ONLINE", pool.operating_status)
32
39
  assert_equal("round_robin_pool", pool.name)
40
+
41
+ # https://docs.openstack.org/api-ref/load-balancer/v2/?expanded=show-member-details-detail#show-member-details
42
+ stub = stub_request(:get, "http://endpoint.example.com:9876/v2.0/lbaas/pools//members/957a1ace-1bd2-449b-8455-820b6e4b63f3")
43
+ .to_return(
44
+ status: 200,
45
+ body: <<-JSON,
46
+ {
47
+ "member": {
48
+ "monitor_port": 8080,
49
+ "project_id": "e3cd678b11784734bc366148aa37580e",
50
+ "name": "web-server-1",
51
+ "weight": 20,
52
+ "backup": false,
53
+ "admin_state_up": true,
54
+ "subnet_id": "bbb35f84-35cc-4b2f-84c2-a6a29bba68aa",
55
+ "created_at": "2017-05-11T17:21:34",
56
+ "provisioning_status": "ACTIVE",
57
+ "monitor_address": null,
58
+ "updated_at": "2017-05-11T17:21:37",
59
+ "address": "192.0.2.16",
60
+ "protocol_port": 80,
61
+ "id": "957a1ace-1bd2-449b-8455-820b6e4b63f3",
62
+ "operating_status": "NO_MONITOR",
63
+ "tags": ["test_tag"]
64
+ }
65
+ }
66
+ JSON
67
+ headers: {'Content-Type' => 'application/json'}
68
+ )
69
+
70
+ assert_instance_of(Yao::LoadBalancerPoolMember, pool.members.first)
71
+ assert_equal("957a1ace-1bd2-449b-8455-820b6e4b63f3", pool.members.first.id)
72
+ assert_equal("web-server-1", pool.members.first.name)
73
+ assert_requested(stub)
74
+
75
+ # https://docs.openstack.org/api-ref/load-balancer/v2/?expanded=show-member-details-detail,show-listener-details-detail,show-pool-details-detail#show-listener-details
76
+ stub = stub_request(:get, "http://endpoint.example.com:9876/v2.0/lbaas/listeners/023f2e34-7806-443b-bfae-16c324569a3d")
77
+ .to_return(
78
+ status: 200,
79
+ body: <<-JSON,
80
+ {
81
+ "listener": {
82
+ "description": "A great TLS listener",
83
+ "admin_state_up": true,
84
+ "project_id": "e3cd678b11784734bc366148aa37580e",
85
+ "protocol": "TERMINATED_HTTPS",
86
+ "protocol_port": 443,
87
+ "provisioning_status": "ACTIVE",
88
+ "default_tls_container_ref": "http://198.51.100.10:9311/v1/containers/a570068c-d295-4780-91d4-3046a325db51",
89
+ "loadbalancers": [
90
+ {
91
+ "id": "607226db-27ef-4d41-ae89-f2a800e9c2db"
92
+ }
93
+ ],
94
+ "insert_headers": {
95
+ "X-Forwarded-Port": "true",
96
+ "X-Forwarded-For": "true"
97
+ },
98
+ "created_at": "2017-02-28T00:42:44",
99
+ "updated_at": "2017-02-28T00:44:30",
100
+ "id": "023f2e34-7806-443b-bfae-16c324569a3d",
101
+ "operating_status": "ONLINE",
102
+ "default_pool_id": "ddb2b28f-89e9-45d3-a329-a359c3e39e4a",
103
+ "sni_container_refs": [
104
+ "http://198.51.100.10:9311/v1/containers/a570068c-d295-4780-91d4-3046a325db51",
105
+ "http://198.51.100.10:9311/v1/containers/aaebb31e-7761-4826-8cb4-2b829caca3ee"
106
+ ],
107
+ "l7policies": [
108
+ {
109
+ "id": "5e618272-339d-4a80-8d14-dbc093091bb1"
110
+ }
111
+ ],
112
+ "name": "great_tls_listener",
113
+ "timeout_client_data": 50000,
114
+ "timeout_member_connect": 5000,
115
+ "timeout_member_data": 50000,
116
+ "timeout_tcp_inspect": 0,
117
+ "tags": ["test_tag"],
118
+ "client_ca_tls_container_ref": "http://198.51.100.10:9311/v1/containers/35649991-49f3-4625-81ce-2465fe8932e5",
119
+ "client_authentication": "MANDATORY",
120
+ "client_crl_container_ref": "http://198.51.100.10:9311/v1/containers/e222b065-b93b-4e2a-9a02-804b7a118c3c",
121
+ "allowed_cidrs": [
122
+ "192.0.2.0/24",
123
+ "198.51.100.0/24"
124
+ ],
125
+ "tls_ciphers": "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256",
126
+ "tls_versions": ["TLSv1.2", "TLSv1.3"],
127
+ "alpn_protocols": ["http/1.1", "http/1.0"]
128
+ }
129
+ }
130
+ JSON
131
+ headers: {'Content-Type' => 'application/json'}
132
+ )
133
+ assert_instance_of(Yao::LoadBalancerListener, pool.listeners.first)
134
+ assert_equal("023f2e34-7806-443b-bfae-16c324569a3d", pool.listeners.first.id)
135
+ assert_equal("great_tls_listener", pool.listeners.first.name)
136
+ assert_requested(stub)
137
+
138
+ # https://docs.openstack.org/api-ref/load-balancer/v2/?expanded=show-member-details-detail,show-listener-details-detail,show-pool-details-detail,show-health-monitor-details-detail#show-health-monitor-details
139
+ stub = stub_request(:get, "http://endpoint.example.com:9876/v2.0/lbaas/healthmonitors/8ed3c5ac-6efa-420c-bedb-99ba14e58db5")
140
+ .to_return(
141
+ status: 200,
142
+ body: <<-JSON,
143
+ {
144
+ "healthmonitor": {
145
+ "project_id": "e3cd678b11784734bc366148aa37580e",
146
+ "name": "super-pool-health-monitor",
147
+ "admin_state_up": true,
148
+ "pools": [
149
+ {
150
+ "id": "4029d267-3983-4224-a3d0-afb3fe16a2cd"
151
+ }
152
+ ],
153
+ "created_at": "2017-05-11T23:53:47",
154
+ "provisioning_status": "ACTIVE",
155
+ "updated_at": "2017-05-11T23:53:47",
156
+ "delay": 10,
157
+ "expected_codes": "200",
158
+ "max_retries": 1,
159
+ "http_method": "GET",
160
+ "timeout": 5,
161
+ "max_retries_down": 3,
162
+ "url_path": "/",
163
+ "type": "HTTP",
164
+ "id": "8ed3c5ac-6efa-420c-bedb-99ba14e58db5",
165
+ "operating_status": "ONLINE",
166
+ "tags": ["test_tag"],
167
+ "http_version": 1.0,
168
+ "domain_name": null
169
+ }
170
+ }
171
+ JSON
172
+ headers: {'Content-Type' => 'application/json'}
173
+ )
174
+ assert_instance_of(Yao::LoadBalancerHealthMonitor, pool.healthmonitor)
175
+ assert_equal("8ed3c5ac-6efa-420c-bedb-99ba14e58db5", pool.healthmonitor.id)
176
+ assert_equal("super-pool-health-monitor", pool.healthmonitor.name)
177
+ assert_requested(stub)
33
178
  end
34
179
  end
@@ -88,13 +88,13 @@ class TestMeter < TestYaoResource
88
88
  assert_requested(stub)
89
89
  end
90
90
 
91
- def test_tenant
92
- stub = stub_request(:get, "https://example.com:12345/tenants/00000000-0000-0000-0000-000000000000")
91
+ def test_project
92
+ stub = stub_request(:get, "https://example.com:12345/projects/00000000-0000-0000-0000-000000000000")
93
93
  .to_return(
94
94
  status: 200,
95
95
  body: <<-JSON,
96
96
  {
97
- "tenant": {
97
+ "project": {
98
98
  "id": "00000000-0000-0000-0000-000000000000"
99
99
  }
100
100
  }
@@ -107,8 +107,8 @@ class TestMeter < TestYaoResource
107
107
  }
108
108
 
109
109
  meter = Yao::Meter.new(params)
110
- assert_instance_of(Yao::Tenant, meter.tenant)
111
- assert_equal("00000000-0000-0000-0000-000000000000", meter.tenant.id)
110
+ assert_instance_of(Yao::Project, meter.project)
111
+ assert_equal("00000000-0000-0000-0000-000000000000", meter.project.id)
112
112
 
113
113
  assert_requested(stub)
114
114
  end
@@ -37,14 +37,14 @@ class TestNetwork < TestYaoResource
37
37
  assert_equal(1000, network.segmentation_id)
38
38
  end
39
39
 
40
- def test_tenant
40
+ def test_project
41
41
 
42
- stub = stub_request(:get, "https://example.com:12345/tenants/0123456789abcdef0123456789abcdef")
42
+ stub = stub_request(:get, "https://example.com:12345/projects/0123456789abcdef0123456789abcdef")
43
43
  .to_return(
44
44
  status: 200,
45
45
  body: <<-JSON,
46
46
  {
47
- "tenant": {
47
+ "project": {
48
48
  "id": "0123456789abcdef0123456789abcdef"
49
49
  }
50
50
  }
@@ -57,9 +57,9 @@ class TestNetwork < TestYaoResource
57
57
  "tenant_id" => "0123456789abcdef0123456789abcdef",
58
58
  )
59
59
 
60
- assert_instance_of(Yao::Tenant, network.tenant)
61
- assert_instance_of(Yao::Tenant, network.project)
62
- assert_equal('0123456789abcdef0123456789abcdef', network.tenant.id)
60
+ assert_instance_of(Yao::Project, network.tenant)
61
+ assert_instance_of(Yao::Project, network.project)
62
+ assert_equal('0123456789abcdef0123456789abcdef', network.project.id)
63
63
 
64
64
  assert_requested(stub)
65
65
  end
@@ -77,14 +77,14 @@ class TestPort < TestYaoResource
77
77
  assert_equal("10.0.0.1", port.primary_ip)
78
78
  end
79
79
 
80
- def test_tenant
80
+ def test_project
81
81
 
82
- stub = stub_request(:get, "https://example.com:12345/tenants/0123456789abcdef0123456789abcdef")
82
+ stub = stub_request(:get, "https://example.com:12345/projects/0123456789abcdef0123456789abcdef")
83
83
  .to_return(
84
84
  status: 200,
85
85
  body: <<-JSON,
86
86
  {
87
- "tenant": {
87
+ "project": {
88
88
  "id": "0123456789abcdef0123456789abcdef"
89
89
  }
90
90
  }
@@ -92,9 +92,9 @@ class TestPort < TestYaoResource
92
92
  headers: {'Content-Type' => 'application/json'}
93
93
  )
94
94
 
95
- port = Yao::Port.new('tenant_id' => '0123456789abcdef0123456789abcdef')
96
- assert_instance_of(Yao::Tenant, port.tenant)
97
- assert_equal('0123456789abcdef0123456789abcdef', port.tenant.id)
95
+ port = Yao::Port.new('project_id' => '0123456789abcdef0123456789abcdef')
96
+ assert_instance_of(Yao::Project, port.project)
97
+ assert_equal('0123456789abcdef0123456789abcdef', port.project.id)
98
98
 
99
99
  assert_requested(stub)
100
100
  end
@@ -1,6 +1,18 @@
1
1
  class TestRestfullyAccesible < Test::Unit::TestCase
2
2
  include RestfullyAccessibleStub
3
3
  class Test
4
+ def initialize(data_via_json)
5
+ @data = data_via_json
6
+ end
7
+
8
+ def id
9
+ @data['id']
10
+ end
11
+
12
+ def name
13
+ @data['name']
14
+ end
15
+
4
16
  class << self
5
17
  attr_accessor :client
6
18
  end
@@ -45,7 +57,7 @@ class TestRestfullyAccesible < Test::Unit::TestCase
45
57
 
46
58
  stub_get_request_not_found([@url, @resources_name, name].join('/'))
47
59
  stub_get_request([@url, "#{@resources_name}?name=dummy"].join('/'), @resources_name)
48
- mock(Test).new("dummy_resource") { Struct.new(:id).new(uuid) }
60
+ mock(Test).new("dummy_resource") { Struct.new(:id, :name).new(uuid, name) }
49
61
  stub_get_request([@url, @resources_name, uuid].join('/'), @resources_name)
50
62
  mock(Test).new("dummy_resource") { "OK" }
51
63
 
@@ -60,7 +72,7 @@ class TestRestfullyAccesible < Test::Unit::TestCase
60
72
 
61
73
  stub_get_request_not_found([@url, @resources_name, name].join('/'))
62
74
  stub_get_request_with_json_response([@url, "#{@resources_name}?name=dummy"].join('/'), body)
63
- mock(Test).new("dummy_resources") { Struct.new(:id).new(uuid) }
75
+ mock(Test).new("dummy_resources") { Struct.new(:id, :name).new(uuid, name) }
64
76
  stub_get_request([@url, @resources_name, uuid].join('/'), @resource_name)
65
77
  mock(Test).new("dummy_resource") { "OK" }
66
78
 
@@ -84,8 +96,17 @@ class TestRestfullyAccesible < Test::Unit::TestCase
84
96
 
85
97
  sub_test_case 'get!' do
86
98
  test 'not found' do
87
- stub_get_request_not_found("https://example.com/dummy_resource")
88
- assert_equal(nil, Test.get!("https://example.com/dummy_resource"))
99
+ Test.return_single_on_querying = false
100
+ name = "dummy"
101
+ uuid = "00112233-4455-6677-8899-aabbccddeeff"
102
+ body = {@resources_name => []}
103
+
104
+ stub1 = stub_get_request_not_found([@url, @resources_name, name].join('/'))
105
+ stub2 = stub_get_request_with_json_response([@url, "#{@resources_name}?name=#{name}"].join('/'), body)
106
+
107
+ assert_equal(nil, Test.get!(name))
108
+ assert_requested(stub1)
109
+ assert_requested(stub2)
89
110
  end
90
111
 
91
112
  test 'found' do
@@ -103,6 +124,23 @@ class TestRestfullyAccesible < Test::Unit::TestCase
103
124
  end
104
125
  end
105
126
 
127
+ sub_test_case 'get_by_name' do
128
+ test 'multiple found' do
129
+ name = 'dummy'
130
+ uuid = '00112233-4455-6677-8899-aabbccddeeff'
131
+ list_body = { @resources_name => [
132
+ { 'name' => 'dummy', 'id' => uuid },
133
+ { 'name' => 'dummy2', 'id' => '308cb410-9c84-40ec-a3eb-583001aaa7fd' }
134
+ ]}
135
+ get_body = { @resource_name => { 'name' => 'dummy', 'id' => uuid } }
136
+ stub1 = stub_get_request_not_found([@url, @resources_name, name].join('/'))
137
+ stub2 = stub_get_request_with_json_response([@url, "#{@resources_name}?name=#{name}"].join('/'), list_body)
138
+ stub3 = stub_get_request_with_json_response([@url, @resources_name, name].join('/'), get_body)
139
+
140
+ assert_equal(uuid, Test.send(:get_by_name, 'dummy').body[@resource_name]['id'])
141
+ end
142
+ end
143
+
106
144
  def test_find_by_name
107
145
  mock(Test).list({"name" => "dummy"}) { "dummy" }
108
146
 
@@ -116,4 +154,8 @@ class TestRestfullyAccesible < Test::Unit::TestCase
116
154
  assert_equal(false, Test.send(:uuid?, "dummy resource"))
117
155
  assert_equal(false, Test.send(:uuid?, "00112233445566778899aabbccddeeff"))
118
156
  end
157
+
158
+ def test_delete
159
+ assert_equal(Test.method(:delete), Test.method(:destroy))
160
+ end
119
161
  end
@@ -130,12 +130,12 @@ class TestRoleAssignment < TestYaoResource
130
130
  end
131
131
 
132
132
  def test_project
133
- stub = stub_request(:get, "https://example.com:12345/tenants/456789").
133
+ stub = stub_request(:get, "https://example.com:12345/projects/456789").
134
134
  to_return(
135
135
  status: 200,
136
136
  body: <<-JSON,
137
137
  {
138
- "tenant": {
138
+ "project": {
139
139
  "id": "456789"
140
140
  }
141
141
  }
@@ -152,7 +152,7 @@ class TestRoleAssignment < TestYaoResource
152
152
  }
153
153
 
154
154
  role_assignment = Yao::RoleAssignment.new(params)
155
- assert_instance_of(Yao::Resources::Tenant, role_assignment.project)
155
+ assert_instance_of(Yao::Project, role_assignment.project)
156
156
  assert_equal("456789", role_assignment.project.id)
157
157
 
158
158
  assert_requested(stub)
@@ -95,12 +95,33 @@ class TestRouter < TestYaoResource
95
95
  assert_equal([], router.availability_zone_hints)
96
96
  assert_equal([ "nova" ], router.availability_zones)
97
97
 
98
- pend 'oops. These are invalid friendly_attributes'
99
- assert_equal( '', router.network_id)
100
- assert_equal('', router.enable_snat)
101
- assert_equal(router.external_fixed_ips '')
102
- assert_equal(router.destination '')
103
- assert_equal(router.nexthop '')
98
+ stub = stub_request(:get, "https://example.com:12345/networks/ae34051f-aa6c-4c75-abf5-50dc9ac99ef3")
99
+ .to_return(
100
+ status: 200,
101
+ body: <<~JSON,
102
+ {
103
+ "network": {
104
+ "id": "ae34051f-aa6c-4c75-abf5-50dc9ac99ef3",
105
+ "name": "example-network"
106
+ }
107
+ }
108
+ JSON
109
+ headers: {'Content-Type' => 'application/json'}
110
+ )
111
+ assert_instance_of(Yao::Network, router.external_network)
112
+ assert_equal("ae34051f-aa6c-4c75-abf5-50dc9ac99ef3", router.external_network.id)
113
+ assert_equal("example-network", router.external_network.name)
114
+ assert_equal(true, router.enable_snat)
115
+ assert_equal([
116
+ {
117
+ "ip_address" => "172.24.4.3",
118
+ "subnet_id" => "b930d7f6-ceb7-40a0-8b81-a425dd994ccf"
119
+ },
120
+ {
121
+ "ip_address" => "2001:db8::c",
122
+ "subnet_id" => "0c56df5d-ace5-46c8-8f4c-45fa4e334d18"
123
+ }
124
+ ], router.external_fixed_ips)
104
125
  end
105
126
 
106
127
  def test_iterfaces
@@ -129,14 +150,14 @@ class TestRouter < TestYaoResource
129
150
  assert_requested(stub)
130
151
  end
131
152
 
132
- def test_tenant
153
+ def test_project
133
154
 
134
- stub = stub_request(:get, "https://example.com:12345/tenants/0123456789abcdef0123456789abcdef")
155
+ stub = stub_request(:get, "https://example.com:12345/projects/0123456789abcdef0123456789abcdef")
135
156
  .to_return(
136
157
  status: 200,
137
158
  body: <<-JSON,
138
159
  {
139
- "tenant": {
160
+ "project": {
140
161
  "id": "0123456789abcdef0123456789abcdef"
141
162
  }
142
163
  }
@@ -144,9 +165,9 @@ class TestRouter < TestYaoResource
144
165
  headers: {'Content-Type' => 'application/json'}
145
166
  )
146
167
 
147
- router = Yao::Router.new('tenant_id' => '0123456789abcdef0123456789abcdef')
148
- assert_instance_of(Yao::Tenant, router.tenant)
149
- assert_equal('0123456789abcdef0123456789abcdef', router.tenant.id)
168
+ router = Yao::Router.new('project_id' => '0123456789abcdef0123456789abcdef')
169
+ assert_instance_of(Yao::Project, router.project)
170
+ assert_equal('0123456789abcdef0123456789abcdef', router.project.id)
150
171
 
151
172
  assert_requested(stub)
152
173
  end
@@ -25,12 +25,12 @@ class TestSecurityGroup < TestYaoResource
25
25
 
26
26
  def test_sg_to_tenant
27
27
 
28
- stub = stub_request(:get, "https://example.com:12345/tenants/0123456789abcdef0123456789abcdef")
28
+ stub = stub_request(:get, "https://example.com:12345/projects/0123456789abcdef0123456789abcdef")
29
29
  .to_return(
30
30
  status: 200,
31
31
  body: <<-JSON,
32
32
  {
33
- "tenant": {
33
+ "project": {
34
34
  "id": "0123456789abcdef0123456789abcdef"
35
35
  }
36
36
  }
@@ -38,9 +38,9 @@ class TestSecurityGroup < TestYaoResource
38
38
  headers: {'Content-Type' => 'application/json'}
39
39
  )
40
40
 
41
- sg = Yao::SecurityGroup.new('tenant_id' => '0123456789abcdef0123456789abcdef')
42
- assert_instance_of(Yao::Tenant, sg.tenant)
43
- assert_equal('0123456789abcdef0123456789abcdef', sg.tenant.id)
41
+ sg = Yao::SecurityGroup.new('project_id' => '0123456789abcdef0123456789abcdef')
42
+ assert_instance_of(Yao::Project, sg.project)
43
+ assert_equal('0123456789abcdef0123456789abcdef', sg.project.id)
44
44
 
45
45
  assert_requested(stub)
46
46
  end
@@ -206,14 +206,14 @@ class TestServer < TestYaoResource
206
206
  assert_equal(Yao::Server.method(:list), Yao::Server.method(:list_detail))
207
207
  end
208
208
 
209
- def test_tenant
209
+ def test_project
210
210
 
211
- stub = stub_request(:get, "https://example.com:12345/tenants/0123456789abcdef0123456789abcdef")
211
+ stub = stub_request(:get, "https://example.com:12345/projects/0123456789abcdef0123456789abcdef")
212
212
  .to_return(
213
213
  status: 200,
214
214
  body: <<-JSON,
215
215
  {
216
- "tenant": {
216
+ "project": {
217
217
  "id": "0123456789abcdef0123456789abcdef"
218
218
  }
219
219
  }
@@ -221,9 +221,9 @@ class TestServer < TestYaoResource
221
221
  headers: {'Content-Type' => 'application/json'}
222
222
  )
223
223
 
224
- server = Yao::Server.new('tenant_id' => '0123456789abcdef0123456789abcdef')
225
- assert_instance_of(Yao::Tenant, server.tenant)
226
- assert_equal('0123456789abcdef0123456789abcdef', server.tenant.id)
224
+ server = Yao::Server.new('project_id' => '0123456789abcdef0123456789abcdef')
225
+ assert_instance_of(Yao::Project, server.project)
226
+ assert_equal('0123456789abcdef0123456789abcdef', server.project.id)
227
227
 
228
228
  assert_requested(stub)
229
229
  end
@@ -76,13 +76,13 @@ class TestSubnet < TestYaoResource
76
76
  assert_requested(stub)
77
77
  end
78
78
 
79
- def test_tenant
80
- stub = stub_request(:get, "https://example.com:12345/tenants/0123456789abcdef0123456789abcdef")
79
+ def test_project
80
+ stub = stub_request(:get, "https://example.com:12345/projects/0123456789abcdef0123456789abcdef")
81
81
  .to_return(
82
82
  status: 200,
83
83
  body: <<-JSON,
84
84
  {
85
- "tenant": {
85
+ "project": {
86
86
  "id": "0123456789abcdef0123456789abcdef"
87
87
  }
88
88
  }
@@ -90,9 +90,9 @@ class TestSubnet < TestYaoResource
90
90
  headers: {'Content-Type' => 'application/json'}
91
91
  )
92
92
 
93
- subnet = Yao::Subnet.new('tenant_id' => '0123456789abcdef0123456789abcdef')
94
- assert_instance_of(Yao::Tenant, subnet.tenant)
95
- assert_equal('0123456789abcdef0123456789abcdef', subnet.tenant.id)
93
+ subnet = Yao::Subnet.new('project_id' => '0123456789abcdef0123456789abcdef')
94
+ assert_instance_of(Yao::Project, subnet.project)
95
+ assert_equal('0123456789abcdef0123456789abcdef', subnet.project.id)
96
96
 
97
97
  assert_requested(stub)
98
98
  end
@@ -98,4 +98,25 @@ class TestVolume < TestYaoResource
98
98
  volume.status = 'error'
99
99
  assert_requested(stub)
100
100
  end
101
+
102
+ def test_project
103
+ stub = stub_request(:get, "https://example.com:12345/projects/0123456789abcdef0123456789abcdef")
104
+ .to_return(
105
+ status: 200,
106
+ body: <<-JSON,
107
+ {
108
+ "project": {
109
+ "id": "0123456789abcdef0123456789abcdef"
110
+ }
111
+ }
112
+ JSON
113
+ headers: {'Content-Type' => 'application/json'}
114
+ )
115
+
116
+ volume = Yao::Volume.new('project_id' => '0123456789abcdef0123456789abcdef')
117
+ assert_instance_of(Yao::Project, volume.project)
118
+ assert_equal('0123456789abcdef0123456789abcdef', volume.project.id)
119
+
120
+ assert_requested(stub)
121
+ end
101
122
  end
data/yao.gemspec CHANGED
@@ -19,6 +19,6 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.add_dependency "json"
21
21
  spec.add_dependency "deep_merge"
22
- spec.add_dependency "faraday", "~> 1.8.0"
22
+ spec.add_dependency "faraday", ">= 1.8.0"
23
23
  spec.add_dependency "faraday_middleware"
24
24
  end
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.15.0
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Uchio, KONDO
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-10 00:00:00.000000000 Z
11
+ date: 2022-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -42,14 +42,14 @@ dependencies:
42
42
  name: faraday
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: 1.8.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 1.8.0
55
55
  - !ruby/object:Gem::Dependency
@@ -122,6 +122,7 @@ files:
122
122
  - lib/yao/resources/port.rb
123
123
  - lib/yao/resources/port_associationable.rb
124
124
  - lib/yao/resources/project.rb
125
+ - lib/yao/resources/project_associationable.rb
125
126
  - lib/yao/resources/resource.rb
126
127
  - lib/yao/resources/restfully_accessible.rb
127
128
  - lib/yao/resources/role.rb
@@ -135,7 +136,6 @@ files:
135
136
  - lib/yao/resources/server_usage_associationable.rb
136
137
  - lib/yao/resources/subnet.rb
137
138
  - lib/yao/resources/tenant.rb
138
- - lib/yao/resources/tenant_associationable.rb
139
139
  - lib/yao/resources/user.rb
140
140
  - lib/yao/resources/volume.rb
141
141
  - lib/yao/resources/volume_action.rb
@@ -216,7 +216,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
216
216
  - !ruby/object:Gem::Version
217
217
  version: '0'
218
218
  requirements: []
219
- rubygems_version: 3.2.32
219
+ rubygems_version: 3.3.7
220
220
  signing_key:
221
221
  specification_version: 4
222
222
  summary: Yet Another OpenStack API Wrapper that rocks!!