fog-proxmox 0.5.5 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci.yml +7 -0
  3. data/.travis.yml +1 -0
  4. data/.vscode/launch.json +3 -21
  5. data/.vscode/settings.json +7 -7
  6. data/Gemfile.lock +39 -39
  7. data/README.md +9 -2
  8. data/examples/compute.rb +20 -23
  9. data/examples/identity.rb +16 -21
  10. data/fog-proxmox.gemspec +1 -2
  11. data/lib/fog/compute/proxmox.rb +2 -8
  12. data/lib/fog/compute/proxmox/models/disk.rb +13 -11
  13. data/lib/fog/compute/proxmox/models/disks.rb +3 -5
  14. data/lib/fog/compute/proxmox/models/interface.rb +6 -11
  15. data/lib/fog/compute/proxmox/models/interfaces.rb +3 -5
  16. data/lib/fog/compute/proxmox/models/node.rb +38 -43
  17. data/lib/fog/compute/proxmox/models/nodes.rb +5 -11
  18. data/lib/fog/compute/proxmox/models/server.rb +123 -80
  19. data/lib/fog/compute/proxmox/models/server_config.rb +56 -24
  20. data/lib/fog/compute/proxmox/models/servers.rb +34 -26
  21. data/lib/fog/compute/proxmox/models/snapshot.rb +28 -14
  22. data/lib/fog/compute/proxmox/models/snapshots.rb +9 -17
  23. data/lib/fog/compute/proxmox/models/storage.rb +15 -11
  24. data/lib/fog/compute/proxmox/models/storages.rb +13 -22
  25. data/lib/fog/compute/proxmox/models/task.rb +10 -14
  26. data/lib/fog/compute/proxmox/models/tasks.rb +9 -18
  27. data/lib/fog/compute/proxmox/models/volume.rb +12 -12
  28. data/lib/fog/compute/proxmox/models/volumes.rb +10 -19
  29. data/lib/fog/compute/proxmox/requests/action_server.rb +1 -4
  30. data/lib/fog/compute/proxmox/requests/clone_server.rb +1 -4
  31. data/lib/fog/compute/proxmox/requests/create_backup.rb +1 -4
  32. data/lib/fog/compute/proxmox/requests/create_server.rb +1 -4
  33. data/lib/fog/compute/proxmox/requests/create_snapshot.rb +1 -4
  34. data/lib/fog/compute/proxmox/requests/create_spice.rb +1 -4
  35. data/lib/fog/compute/proxmox/requests/create_term.rb +1 -4
  36. data/lib/fog/compute/proxmox/requests/create_vnc.rb +1 -4
  37. data/lib/fog/compute/proxmox/requests/delete_server.rb +1 -4
  38. data/lib/fog/compute/proxmox/requests/delete_snapshot.rb +1 -4
  39. data/lib/fog/compute/proxmox/requests/get_node_statistics.rb +1 -4
  40. data/lib/fog/compute/proxmox/requests/get_server_config.rb +1 -4
  41. data/lib/fog/compute/proxmox/requests/get_server_status.rb +1 -4
  42. data/lib/fog/compute/proxmox/requests/{get_snapshot.rb → get_snapshot_config.rb} +5 -8
  43. data/lib/fog/compute/proxmox/requests/get_task.rb +1 -4
  44. data/lib/fog/compute/proxmox/requests/get_vnc.rb +1 -4
  45. data/lib/fog/compute/proxmox/requests/list_nodes.rb +1 -2
  46. data/lib/fog/compute/proxmox/requests/list_storages.rb +3 -1
  47. data/lib/fog/compute/proxmox/requests/log_task.rb +1 -4
  48. data/lib/fog/compute/proxmox/requests/move_disk.rb +1 -4
  49. data/lib/fog/compute/proxmox/requests/move_volume.rb +1 -4
  50. data/lib/fog/compute/proxmox/requests/next_vmid.rb +5 -3
  51. data/lib/fog/compute/proxmox/requests/resize_container.rb +1 -4
  52. data/lib/fog/compute/proxmox/requests/status_task.rb +1 -4
  53. data/lib/fog/compute/proxmox/requests/update_server.rb +1 -4
  54. data/lib/fog/identity/proxmox.rb +2 -8
  55. data/lib/fog/identity/proxmox/models/domain.rb +25 -21
  56. data/lib/fog/identity/proxmox/models/{ldap.rb → domain_type.rb} +9 -18
  57. data/lib/fog/identity/proxmox/models/domains.rb +6 -76
  58. data/lib/fog/identity/proxmox/models/group.rb +6 -19
  59. data/lib/fog/identity/proxmox/models/groups.rb +6 -12
  60. data/lib/fog/identity/proxmox/models/permission.rb +27 -31
  61. data/lib/fog/identity/proxmox/models/permissions.rb +8 -25
  62. data/lib/fog/identity/proxmox/models/pool.rb +9 -22
  63. data/lib/fog/identity/proxmox/models/pools.rb +7 -13
  64. data/lib/fog/identity/proxmox/models/principal.rb +1 -6
  65. data/lib/fog/identity/proxmox/models/role.rb +7 -20
  66. data/lib/fog/identity/proxmox/models/roles.rb +6 -13
  67. data/lib/fog/identity/proxmox/models/user.rb +7 -21
  68. data/lib/fog/identity/proxmox/models/users.rb +6 -12
  69. data/lib/fog/identity/proxmox/requests/check_permissions.rb +1 -4
  70. data/lib/fog/identity/proxmox/requests/list_roles.rb +0 -1
  71. data/lib/fog/identity/proxmox/requests/read_version.rb +1 -5
  72. data/lib/fog/identity/proxmox/requests/update_group.rb +2 -3
  73. data/lib/fog/identity/proxmox/requests/{add_permission.rb → update_permissions.rb} +4 -4
  74. data/lib/fog/network/proxmox/models/network.rb +12 -18
  75. data/lib/fog/network/proxmox/models/networks.rb +11 -17
  76. data/lib/fog/network/proxmox/models/node.rb +14 -10
  77. data/lib/fog/network/proxmox/models/nodes.rb +5 -11
  78. data/lib/fog/network/proxmox/requests/create_network.rb +1 -4
  79. data/lib/fog/network/proxmox/requests/delete_network.rb +1 -4
  80. data/lib/fog/network/proxmox/requests/get_network.rb +1 -4
  81. data/lib/fog/network/proxmox/requests/get_node.rb +1 -4
  82. data/lib/fog/network/proxmox/requests/power_node.rb +1 -4
  83. data/lib/fog/network/proxmox/requests/update_network.rb +1 -4
  84. data/lib/fog/{compute/proxmox/requests/check_vmid.rb → proxmox/attributes.rb} +9 -17
  85. data/lib/fog/proxmox/core.rb +2 -1
  86. data/lib/fog/proxmox/helpers/cpu_helper.rb +6 -3
  87. data/lib/fog/proxmox/helpers/disk_helper.rb +1 -1
  88. data/lib/fog/proxmox/helpers/nic_helper.rb +37 -22
  89. data/lib/fog/proxmox/version.rb +1 -1
  90. data/lib/fog/storage/proxmox.rb +1 -1
  91. data/spec/compute_spec.rb +64 -45
  92. data/spec/fixtures/proxmox/compute/containers.yml +1684 -4137
  93. data/spec/fixtures/proxmox/compute/identity_ticket.yml +4 -4
  94. data/spec/fixtures/proxmox/compute/nodes.yml +21 -21
  95. data/spec/fixtures/proxmox/compute/servers.yml +3065 -7741
  96. data/spec/fixtures/proxmox/compute/snapshots.yml +279 -827
  97. data/spec/fixtures/proxmox/compute/storages.yml +60 -21
  98. data/spec/fixtures/proxmox/compute/tasks.yml +56 -98
  99. data/spec/fixtures/proxmox/identity/auth.yml +6 -6
  100. data/spec/fixtures/proxmox/identity/domains.yml +252 -84
  101. data/spec/fixtures/proxmox/identity/groups.yml +93 -54
  102. data/spec/fixtures/proxmox/identity/identity_ticket.yml +4 -4
  103. data/spec/fixtures/proxmox/identity/permissions.yml +317 -79
  104. data/spec/fixtures/proxmox/identity/pools.yml +266 -71
  105. data/spec/fixtures/proxmox/identity/read_version.yml +6 -6
  106. data/spec/fixtures/proxmox/identity/roles.yml +96 -57
  107. data/spec/fixtures/proxmox/identity/users.yml +224 -107
  108. data/spec/fixtures/proxmox/network/identity_ticket.yml +4 -4
  109. data/spec/fixtures/proxmox/network/networks.yml +54 -95
  110. data/spec/helpers/nic_helper_spec.rb +4 -4
  111. data/spec/identity_spec.rb +38 -46
  112. data/spec/network_spec.rb +1 -1
  113. metadata +9 -23
  114. data/lib/fog/compute/proxmox/models/container.rb +0 -86
  115. data/lib/fog/compute/proxmox/models/container_config.rb +0 -114
  116. data/lib/fog/compute/proxmox/models/containers.rb +0 -43
  117. data/lib/fog/compute/proxmox/requests/get_node.rb +0 -44
  118. data/lib/fog/compute/proxmox/requests/get_storage.rb +0 -44
  119. data/lib/fog/identity/proxmox/models/activedirectory.rb +0 -57
  120. data/lib/fog/identity/proxmox/models/oath.rb +0 -50
  121. data/lib/fog/identity/proxmox/models/pam.rb +0 -46
  122. data/lib/fog/identity/proxmox/models/pve.rb +0 -46
  123. data/lib/fog/identity/proxmox/models/yubico.rb +0 -51
  124. data/lib/fog/identity/proxmox/requests/remove_permission.rb +0 -42
  125. data/lib/fog/proxmox/models/collection.rb +0 -85
  126. data/lib/fog/proxmox/models/model.rb +0 -58
@@ -1,12 +1,3 @@
1
- # frozen_string_literal: true
2
- # Copyright 2018 Tristan Robert
3
-
4
- # This file is part of Fog::Proxmox.
5
-
6
- # Fog::Proxmox is free software: you can redistribute it and/or modify
7
- # it under the terms of the GNU General Public License as published by
8
- # the Free Software Foundation, either version 3 of the License, or
9
- # (at your option) any later version.
10
1
  # Copyright 2018 Tristan Robert
11
2
 
12
3
  # This file is part of Fog::Proxmox.
@@ -26,22 +17,18 @@
26
17
 
27
18
  # frozen_string_literal: true
28
19
 
29
- require 'fog/proxmox/models/model'
30
-
31
20
  module Fog
32
21
  module Identity
33
22
  class Proxmox
34
23
  # class Role model authentication
35
- class Role < Fog::Proxmox::Model
24
+ class Role < Fog::Model
36
25
  identity :roleid
37
26
  attribute :privs
38
- attribute :append
39
- def to_s
40
- roleid
41
- end
27
+ attribute :special
42
28
 
43
- def create(new_attributes = {})
44
- service.create_role(attributes.merge(new_attributes))
29
+ def save(options = {})
30
+ service.create_role(attributes.merge(options))
31
+ reload
45
32
  end
46
33
 
47
34
  def destroy
@@ -52,8 +39,8 @@ module Fog
52
39
 
53
40
  def update
54
41
  requires :roleid
55
- attr = attributes.reject { |key, _value| key == :roleid }
56
- service.update_role(roleid, attr)
42
+ service.update_role(roleid, attributes.reject { |attribute| [:roleid, :special].include? attribute })
43
+ reload
57
44
  end
58
45
  end
59
46
  end
@@ -17,32 +17,25 @@
17
17
  # You should have received a copy of the GNU General Public License
18
18
  # along with Fog::Proxmox. If not, see <http://www.gnu.org/licenses/>.
19
19
 
20
- require 'fog/proxmox/models/collection'
21
20
  require 'fog/identity/proxmox/models/role'
22
21
 
23
22
  module Fog
24
23
  module Identity
25
24
  class Proxmox
26
25
  # class Roles model collection authentication
27
- class Roles < Fog::Proxmox::Collection
26
+ class Roles < Fog::Collection
28
27
  model Fog::Identity::Proxmox::Role
29
28
 
30
- def all(_options = {})
31
- # special attibute is volatile in role
32
- load_response(service.list_roles, 'roles', ['special'])
29
+ def all
30
+ load service.list_roles
33
31
  end
34
32
 
35
- def find_by_id(id)
36
- cached_role = find { |role| role.roleid == id }
37
- return cached_role if cached_role
38
- role_hash = service.get_role(id)
39
- Fog::Identity::Proxmox::Role.new(
40
- role_hash.merge(service: service)
41
- )
33
+ def get(id)
34
+ all.find { |role| role.identity === id }
42
35
  end
43
36
 
44
37
  def destroy(id)
45
- role = find_by_id(id)
38
+ role = get(id)
46
39
  role.destroy
47
40
  end
48
41
  end
@@ -1,12 +1,3 @@
1
- # frozen_string_literal: true
2
- # Copyright 2018 Tristan Robert
3
-
4
- # This file is part of Fog::Proxmox.
5
-
6
- # Fog::Proxmox is free software: you can redistribute it and/or modify
7
- # it under the terms of the GNU General Public License as published by
8
- # the Free Software Foundation, either version 3 of the License, or
9
- # (at your option) any later version.
10
1
  # Copyright 2018 Tristan Robert
11
2
 
12
3
  # This file is part of Fog::Proxmox.
@@ -26,13 +17,11 @@
26
17
 
27
18
  # frozen_string_literal: true
28
19
 
29
- require 'fog/proxmox/models/model'
30
-
31
20
  module Fog
32
21
  module Identity
33
22
  class Proxmox
34
23
  # class User model
35
- class User < Fog::Proxmox::Model
24
+ class User < Fog::Model
36
25
  identity :userid
37
26
  attribute :firstname
38
27
  attribute :lastname
@@ -43,12 +32,10 @@ module Fog
43
32
  attribute :enable
44
33
  attribute :groups
45
34
  attribute :keys
46
- def to_s
47
- userid
48
- end
49
35
 
50
- def create(new_attributes = {})
51
- service.create_user(attributes.merge(new_attributes))
36
+ def save(options = {})
37
+ service.create_user(attributes.merge(options))
38
+ reload
52
39
  end
53
40
 
54
41
  def destroy
@@ -59,13 +46,12 @@ module Fog
59
46
 
60
47
  def update
61
48
  requires :userid
62
- attr = attributes.reject { |key, _value| key == :userid }
63
- service.update_user(userid, attr)
49
+ service.update_user(userid, attributes.reject { |attribute| [:userid].include? attribute })
50
+ reload
64
51
  end
65
52
 
66
53
  def change_password
67
- requires :userid
68
- requires :password
54
+ requires :userid, :password
69
55
  service.change_password(userid, password)
70
56
  end
71
57
  end
@@ -17,31 +17,25 @@
17
17
  # You should have received a copy of the GNU General Public License
18
18
  # along with Fog::Proxmox. If not, see <http://www.gnu.org/licenses/>.
19
19
 
20
- require 'fog/proxmox/models/collection'
21
20
  require 'fog/identity/proxmox/models/user'
22
21
 
23
22
  module Fog
24
23
  module Identity
25
24
  class Proxmox
26
25
  # class Users model collection
27
- class Users < Fog::Proxmox::Collection
26
+ class Users < Fog::Collection
28
27
  model Fog::Identity::Proxmox::User
29
28
 
30
- def all(options = {})
31
- load_response(service.list_users(options), 'users')
29
+ def all(filters = {})
30
+ load service.list_users(filters)
32
31
  end
33
32
 
34
- def find_by_id(id)
35
- cached_user = find { |user| user.userid == id }
36
- return cached_user if cached_user
37
- user_hash = service.get_user(id)
38
- Fog::Identity::Proxmox::User.new(
39
- user_hash.merge(service: service)
40
- )
33
+ def get(id)
34
+ all.find { |user| user.identity === id }
41
35
  end
42
36
 
43
37
  def destroy(id)
44
- user = find_by_id(id)
38
+ user = get(id)
45
39
  user.destroy
46
40
  end
47
41
  end
@@ -24,15 +24,12 @@ module Fog
24
24
  # class Real check_permissions request
25
25
  class Real
26
26
  def check_permissions(principal)
27
- response = request(
27
+ request(
28
28
  expects: [200],
29
29
  method: 'POST',
30
30
  path: 'access/ticket',
31
31
  body: URI.encode_www_form(principal)
32
32
  )
33
- body = JSON.decode(response.body)
34
- data = body['data']
35
- data
36
33
  end
37
34
  end
38
35
 
@@ -1,4 +1,3 @@
1
- # frozen_string_literal: true
2
1
  # Copyright 2018 Tristan Robert
3
2
 
4
3
  # This file is part of Fog::Proxmox.
@@ -1,4 +1,3 @@
1
- # frozen_string_literal: true
2
1
  # Copyright 2018 Tristan Robert
3
2
 
4
3
  # This file is part of Fog::Proxmox.
@@ -24,14 +23,11 @@ module Fog
24
23
  # class Real read_version request
25
24
  class Real
26
25
  def read_version
27
- response = request(
26
+ request(
28
27
  expects: [200],
29
28
  method: 'GET',
30
29
  path: 'version'
31
30
  )
32
- body = JSON.decode(response.body)
33
- data = body['data']
34
- data
35
31
  end
36
32
  end
37
33
 
@@ -1,4 +1,3 @@
1
- # frozen_string_literal: true
2
1
  # Copyright 2018 Tristan Robert
3
2
 
4
3
  # This file is part of Fog::Proxmox.
@@ -23,12 +22,12 @@ module Fog
23
22
  class Proxmox
24
23
  # class Real update_group request
25
24
  class Real
26
- def update_group(groupid, attributes)
25
+ def update_group(groupid, options)
27
26
  request(
28
27
  expects: [200],
29
28
  method: 'PUT',
30
29
  path: "access/groups/#{groupid}",
31
- body: URI.encode_www_form(attributes)
30
+ body: URI.encode_www_form(options)
32
31
  )
33
32
  end
34
33
  end
@@ -21,19 +21,19 @@
21
21
  module Fog
22
22
  module Identity
23
23
  class Proxmox
24
- # class Real add_permission request
24
+ # class Real update_permissions request
25
25
  class Real
26
- def add_permission(permission)
26
+ def update_permissions(body_params)
27
27
  request(
28
28
  expects: [200],
29
29
  method: 'PUT',
30
30
  path: 'access/acl',
31
- body: URI.encode_www_form(permission)
31
+ body: URI.encode_www_form(body_params)
32
32
  )
33
33
  end
34
34
  end
35
35
 
36
- # class Mock add_permission request
36
+ # class Mock update_permissions request
37
37
  class Mock
38
38
  end
39
39
  end
@@ -26,15 +26,13 @@
26
26
 
27
27
  # frozen_string_literal: true
28
28
 
29
- require 'fog/proxmox/models/model'
30
-
31
29
  module Fog
32
30
  module Network
33
31
  class Proxmox
34
32
  # class Network model
35
- class Network < Fog::Proxmox::Model
33
+ class Network < Fog::Model
36
34
  identity :iface
37
- attribute :node
35
+ attribute :node_id
38
36
  attribute :comments
39
37
  attribute :active
40
38
  attribute :autostart
@@ -53,27 +51,23 @@ module Fog
53
51
 
54
52
  TYPES = %w[bridge bond eth alias vlan OVSBridge OVSBond OVSPort OVSIntPort any_bridge].freeze
55
53
 
56
- def to_s
57
- identity
58
- end
59
-
60
- def create(attributes = {})
61
- requires :node
62
- path_params = { node: node }
63
- body_params = attributes
54
+ def save(options = {})
55
+ requires :node_id
56
+ path_params = { node: node_id }
57
+ body_params = options.merge(attributes.reject { |attribute| [:node_id].include? attribute })
64
58
  service.create_network(path_params, body_params)
65
59
  end
66
60
 
67
- def update(attributes = {})
68
- requires :node, :iface, :type
69
- path_params = { node: node, iface: iface }
70
- body_params = attributes.merge(type: type)
61
+ def update(options = {})
62
+ requires :node_id, :iface, :type
63
+ path_params = { node: node_id, iface: iface }
64
+ body_params = options.merge(type: type)
71
65
  service.update_network(path_params, body_params)
72
66
  end
73
67
 
74
68
  def destroy
75
- requires :node, :iface
76
- path_params = { node: node, iface: iface }
69
+ requires :node_id, :iface
70
+ path_params = { node: node_id, iface: iface }
77
71
  service.delete_network(path_params)
78
72
  end
79
73
  end
@@ -17,36 +17,30 @@
17
17
  # You should have received a copy of the GNU General Public License
18
18
  # along with Fog::Proxmox. If not, see <http://www.gnu.org/licenses/>.
19
19
 
20
- require 'fog/proxmox/models/collection'
21
20
  require 'fog/network/proxmox/models/node'
22
21
 
23
22
  module Fog
24
23
  module Network
25
24
  class Proxmox
26
25
  # class Networks Collection of nodes of cluster
27
- class Networks < Fog::Proxmox::Collection
26
+ class Networks < Fog::Collection
28
27
  model Fog::Network::Proxmox::Network
29
- attribute :node
28
+ attribute :node_id
30
29
 
31
30
  def new(attributes = {})
32
- requires :node
33
- super({ node: node }.merge(attributes))
31
+ requires :node_id
32
+ super({ node_id: node_id }.merge(attributes))
34
33
  end
35
34
 
36
- def all(options = {})
37
- requires :node
38
- path_params = { node: node }
39
- query_params = options
40
- load_response(service.list_networks(path_params, query_params), 'networks')
35
+ def all(filters = {})
36
+ requires :node_id
37
+ path_params = { node: node_id }
38
+ query_params = filters
39
+ load service.list_networks(path_params, query_params)
41
40
  end
42
41
 
43
- def find_by_id(id)
44
- cached_network = find { |network| network.iface == id }
45
- return cached_network if cached_network
46
- network_hash = service.get_network(id)
47
- Fog::Network::Proxmox::Network.new(
48
- network_hash.merge(service: service, node: node, iface: id)
49
- )
42
+ def get(id)
43
+ all.find { |network| network.identity === id }
50
44
  end
51
45
  end
52
46
  end
@@ -26,13 +26,11 @@
26
26
 
27
27
  # frozen_string_literal: true
28
28
 
29
- require 'fog/proxmox/models/model'
30
-
31
29
  module Fog
32
30
  module Network
33
31
  class Proxmox
34
32
  # class Node model of VMs
35
- class Node < Fog::Proxmox::Model
33
+ class Node < Fog::Model
36
34
  identity :node
37
35
  attribute :status
38
36
  attribute :wait
@@ -49,13 +47,13 @@ module Fog
49
47
  attribute :swap
50
48
  attribute :networks
51
49
 
52
- def to_s
53
- node
54
- end
55
-
56
- def networks
57
- @networks ||= Fog::Network::Proxmox::Networks.new(service: service,
58
- node: self)
50
+ def initialize(new_attributes = {})
51
+ prepare_service_value(new_attributes)
52
+ attributes[:node] = new_attributes['node'] unless new_attributes['node'].nil?
53
+ attributes[:node] = new_attributes[:node] unless new_attributes[:node].nil?
54
+ requires :node
55
+ initialize_networks
56
+ super(new_attributes)
59
57
  end
60
58
 
61
59
  def power(action)
@@ -64,6 +62,12 @@ module Fog
64
62
  raise Fog::Errors::Error, message unless action_known
65
63
  service.power_node({ node: node }, command: action)
66
64
  end
65
+
66
+ private
67
+
68
+ def initialize_networks
69
+ attributes[:networks] = Fog::Network::Proxmox::Networks.new(service: service, node_id: node)
70
+ end
67
71
  end
68
72
  end
69
73
  end
@@ -17,27 +17,21 @@
17
17
  # You should have received a copy of the GNU General Public License
18
18
  # along with Fog::Proxmox. If not, see <http://www.gnu.org/licenses/>.
19
19
 
20
- require 'fog/proxmox/models/collection'
21
20
  require 'fog/network/proxmox/models/node'
22
21
 
23
22
  module Fog
24
23
  module Network
25
24
  class Proxmox
26
25
  # class Nodes Collection of nodes of cluster
27
- class Nodes < Fog::Proxmox::Collection
26
+ class Nodes < Fog::Collection
28
27
  model Fog::Network::Proxmox::Node
29
28
 
30
- def all(_options = {})
31
- load_response(service.list_nodes, 'nodes')
29
+ def all
30
+ load service.list_nodes
32
31
  end
33
32
 
34
- def find_by_id(id)
35
- cached_node = find { |node| node.node == id }
36
- return cached_node if cached_node
37
- node_hash = service.get_node(id)
38
- Fog::Network::Proxmox::Node.new(
39
- node_hash.merge(service: service, node: id)
40
- )
33
+ def get(id)
34
+ all.find { |node| node.identity === id }
41
35
  end
42
36
  end
43
37
  end