diff --git a/fog-proxmox.gemspec b/fog-proxmox.gemspec
index 9b49ba6..630eac6 100644
--- a/fog-proxmox.gemspec
+++ b/fog-proxmox.gemspec
@@ -39,7 +39,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'bundler', '~> 2.1'
spec.add_development_dependency 'bundler-audit', '~> 0.6'
- spec.add_development_dependency 'debase', '~> 0.2.2'
+ spec.add_development_dependency 'debase', '~> 0.2.5.beta1'
spec.add_development_dependency 'debride', '~> 1.8'
spec.add_development_dependency 'fasterer', '~> 0.3'
spec.add_development_dependency 'fastri', '~> 0.3'
diff --git a/lib/fog/proxmox.rb b/lib/fog/proxmox.rb
index 3c26983..5229e29 100644
--- a/lib/fog/proxmox.rb
+++ b/lib/fog/proxmox.rb
@@ -29,6 +29,7 @@ module Proxmox
autoload :Core, 'fog/proxmox/core'
autoload :Errors, 'fog/proxmox/errors'
autoload :Identity, 'fog/proxmox/identity'
+ autoload :Cluster, 'fog/proxmox/cluster'
autoload :Compute, 'fog/proxmox/compute'
autoload :Storage, 'fog/proxmox/storage'
autoload :Network, 'fog/proxmox/network'
@@ -36,6 +37,7 @@ module Proxmox
extend Fog::Provider
service(:identity, 'Identity')
+ service(:cluster, 'Cluster')
service(:compute, 'Compute')
service(:storage, 'Storage')
service(:network, 'Network')
diff --git a/lib/fog/proxmox/cluster.rb b/lib/fog/proxmox/cluster.rb
new file mode 100644
index 0000000..2c2e51e
--- /dev/null
+++ b/lib/fog/proxmox/cluster.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+
+# Copyright 2018 Tristan Robert
+
+# This file is part of Fog::Proxmox.
+
+# Fog::Proxmox is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# Fog::Proxmox is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with Fog::Proxmox. If not, see .
+
+require 'fog/proxmox/core'
+
+module Fog
+ module Proxmox
+ # Proxmox cluster service
+ class Cluster < Fog::Service
+ requires :proxmox_url, :proxmox_auth_method
+ recognizes :proxmox_token, :proxmox_tokenid, :proxmox_userid, :persistent, :proxmox_username, :proxmox_password
+
+ # Models
+ model_path 'fog/proxmox/cluster/models'
+ model :resource
+ collection :resources
+
+ # Requests
+ request_path 'fog/proxmox/cluster/requests'
+
+ # Manage nodes cluster
+ request :list_resources
+ request :get_nextid
+
+ # Mock class
+ class Mock
+ attr_reader :config
+
+ def initialize(options = {})
+ @proxmox_uri = URI.parse(options[:proxmox_url])
+ @proxmox_auth_method = options[:proxmox_auth_method]
+ @proxmox_tokenid = options[:proxmox_tokenid]
+ @proxmox_userid = options[:proxmox_userid]
+ @proxmox_username = options[:proxmox_username]
+ @proxmox_password = options[:proxmox_password]
+ @proxmox_token = options[:proxmox_token]
+ @proxmox_path = @proxmox_uri.path
+ @config = options
+ end
+ end
+
+ # Real class
+ class Real
+ include Fog::Proxmox::Core
+
+ def self.not_found_class
+ Fog::Proxmox::Cluster::NotFound
+ end
+
+ def config
+ self
+ end
+
+ def config_service?
+ true
+ end
+
+ private
+
+ def configure(source)
+ source.instance_variables.each do |v|
+ instance_variable_set(v, source.instance_variable_get(v))
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/fog/proxmox/cluster/models/resource.rb b/lib/fog/proxmox/cluster/models/resource.rb
new file mode 100644
index 0000000..9769b84
--- /dev/null
+++ b/lib/fog/proxmox/cluster/models/resource.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+# Copyright 2018 Tristan Robert
+
+# This file is part of Fog::Proxmox.
+
+# Fog::Proxmox is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# Fog::Proxmox is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with Fog::Proxmox. If not, see .
+
+# frozen_string_literal: true
+
+require 'fog/proxmox/hash'
+
+module Fog
+ module Proxmox
+ class Cluster
+ # class Disk model
+ class Resource < Fog::Model
+ identity :id
+
+ attribute :name
+ attribute :type
+ attribute :node
+
+ # generic
+ attribute :maxdisk
+
+ # vm/lxc specific
+ attribute :vmid
+ attribute :status
+ attribute :uptime
+ attribute :template
+ # resources are written in bytes, proxmox displays gibibytes
+ attribute :maxcpu
+ attribute :maxmem
+
+ # storage specific
+ attribute :content
+ attribute :shared
+ attribute :storage
+
+ def is_template?
+ template === 1
+ end
+
+ def to_s
+ Fog::Proxmox::Hash.flatten(attributes)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/fog/proxmox/cluster/models/resources.rb b/lib/fog/proxmox/cluster/models/resources.rb
new file mode 100644
index 0000000..6948262
--- /dev/null
+++ b/lib/fog/proxmox/cluster/models/resources.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+# Copyright 2018 Tristan Robert
+
+# This file is part of Fog::Proxmox.
+
+# Fog::Proxmox is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# Fog::Proxmox is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with Fog::Proxmox. If not, see .
+
+require 'fog/proxmox/cluster/models/resource'
+
+module Fog
+ module Proxmox
+ class Cluster
+ # class Disks Collection of disk
+ class Resources < Fog::Collection
+ model Fog::Proxmox::Cluster::Resource
+
+ def all
+ load service.list_resources
+ end
+
+ def get(id)
+ all.find { |resource| resource.identity === id }
+ end
+
+ def by_type(type)
+ all.select { |resource| resource.type === type }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/fog/proxmox/cluster/requests/get_nextid.rb b/lib/fog/proxmox/cluster/requests/get_nextid.rb
new file mode 100644
index 0000000..6c81720
--- /dev/null
+++ b/lib/fog/proxmox/cluster/requests/get_nextid.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+# Copyright 2018 Tristan Robert
+
+# This file is part of Fog::Proxmox.
+
+# Fog::Proxmox is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# Fog::Proxmox is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with Fog::Proxmox. If not, see .
+
+module Fog
+ module Proxmox
+ class Cluster
+ # class Real get_nextid request
+ class Real
+ def get_nextid(vmid = nil)
+ query = "vmid=#{vmid}" unless vmid.nil?
+ request(
+ expects: [200],
+ method: 'GET',
+ path: 'cluster/nextid',
+ query: query || ''
+ )
+ end
+ end
+
+ # class Mock get_nextid request
+ class Mock
+ def get_nextid(vmid = nil)
+ return "4002" unless vmid
+
+ vmid.to_s
+ end
+ end
+ end
+ end
+end
diff --git a/lib/fog/proxmox/cluster/requests/list_resources.rb b/lib/fog/proxmox/cluster/requests/list_resources.rb
new file mode 100644
index 0000000..1231e3a
--- /dev/null
+++ b/lib/fog/proxmox/cluster/requests/list_resources.rb
@@ -0,0 +1,104 @@
+# frozen_string_literal: true
+
+# Copyright 2018 Tristan Robert
+
+# This file is part of Fog::Proxmox.
+
+# Fog::Proxmox is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# Fog::Proxmox is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with Fog::Proxmox. If not, see .
+
+module Fog
+ module Proxmox
+ class Cluster
+ # class Real get_vnc request
+ class Real
+ def list_resources(resource_type = '')
+ query = resource_type.blank? ? '' : "type=#{resource_type}"
+ request(
+ expects: [200],
+ method: 'GET',
+ path: 'cluster/resources',
+ query: query || ''
+ )
+ end
+
+ def list_qemu_resources
+ list_vm_resources.select { |vm| vm['type'] == 'qemu' }
+ end
+
+ def list_lxc_resources
+ list_vm_resources.select { |vm| vm['type'] == 'lxc' }
+ end
+
+ def list_vm_resources
+ list_resources('vm')
+ end
+
+ def list_storage_resources
+ list_resources('storage')
+ end
+ end
+
+ # class Mock get_vnc request
+ class Mock
+ def list_resources(resource_type)
+ case resource_type
+ when 'qemu'
+ list_qemu_resources
+ when 'lxc'
+ list_lxc_resources
+ when 'storage'
+ list_storage_resources
+ else
+ (list_qemu_resources + list_lxc_resources + list_storage_resources)
+ end
+ end
+
+ def list_qemu_resources
+ [
+ {
+ 'node' => 'pve',
+ 'type' => 'qemu',
+ 'vmid' => '100'
+ }
+ ]
+ end
+
+ def list_lxc_resources
+ [
+ {
+ 'node' => 'pve',
+ 'type' => 'lxc',
+ 'vmid' => '101'
+ }
+ ]
+ end
+
+ def list_storage_resources # rubocop:disable Metrics/MethodLength
+ [
+ {
+ 'node' => 'pve',
+ 'type' => 'storage',
+ 'storage' => 'local'
+ },
+ {
+ 'node' => 'pve',
+ 'type' => 'storage',
+ 'storage' => 'local'
+ }
+ ]
+ end
+ end
+ end
+ end
+end
diff --git a/lib/fog/proxmox/compute/models/storage.rb b/lib/fog/proxmox/compute/models/storage.rb
index 16423ef..e8618cf 100644
--- a/lib/fog/proxmox/compute/models/storage.rb
+++ b/lib/fog/proxmox/compute/models/storage.rb
@@ -3,14 +3,6 @@
# This file is part of Fog::Proxmox.
-# Fog::Proxmox is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-# Copyright 2018 Tristan Robert
-
-# This file is part of Fog::Proxmox.
-
# Fog::Proxmox is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
diff --git a/spec/cluster_spec.rb b/spec/cluster_spec.rb
new file mode 100644
index 0000000..4c2b041
--- /dev/null
+++ b/spec/cluster_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+# Copyright 2018 Tristan Robert
+
+# This file is part of Fog::Proxmox.
+
+# Fog::Proxmox is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# Fog::Proxmox is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with Fog::Proxmox. If not, see .
+
+require 'spec_helper'
+require_relative './proxmox_vcr'
+
+describe Fog::Proxmox::Cluster do
+ before :all do
+ @proxmox_vcr = ProxmoxVCR.new(
+ vcr_directory: 'spec/fixtures/proxmox/cluster',
+ service_class: Fog::Proxmox::Cluster
+ )
+ @service = @proxmox_vcr.service
+ @proxmox_url = @proxmox_vcr.url
+ @username = @proxmox_vcr.username
+ @password = @proxmox_vcr.password
+ @tokenid = @proxmox_vcr.tokenid
+ @token = @proxmox_vcr.token
+ end
+
+ it 'Manage Clusters' do
+ VCR.use_cassette('cluster') do
+ # List all resources
+ resources = @service.resources.all
+ _(resources).wont_be_nil
+ _(resources).wont_be_empty
+ _(resources.size).must_equal 4
+ # List all resources of type qemu
+ qemu_resources = @service.resources.by_type('qemu')
+ _(qemu_resources).wont_be_nil
+ _(qemu_resources).wont_be_empty
+ _(qemu_resources.size).must_equal 1
+ end
+ end
+end
diff --git a/spec/fixtures/proxmox/cluster/cluster.yml b/spec/fixtures/proxmox/cluster/cluster.yml
new file mode 100644
index 0000000..bcde7ad
--- /dev/null
+++ b/spec/fixtures/proxmox/cluster/cluster.yml
@@ -0,0 +1,40 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: https://192.168.56.101:8006/api2/json/cluster/resources
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - fog-core/2.2.3
+ Cookie:
+ - PVEAuthCookie=PVE:root@pam:5FBE5F93::J4UGO/cW6NJLxU0fQy8AnxuJhKDkIa+ZLBLUIxlXYO3Nb1ocZ15jqoPl0EEOQpI2sohhmtGYo9bptqaPPH48rmaNKzIUtHjDAg/c425GgbhkSo2jYVeCWcTTEC+nDskOiMkjdE4HIiFLpk71IMEP93hGWJ4+mnUxOLfHsRDodWdJXoGoBlxiUBu0zirFLXR60i6WCK2oX82nPYXRJbsl4VRLYcOkYXnnfaUxYgOL0veZhKRcAWlVRKQ7/lkdG1iu3XlOvEeynqcT2xHs+Z158zALA+ZzAEQ6GYdvFFKr/xR57Kd8hfOhRumKx5EaDfdeYkZP/8ZVH48tEbTXrOEQHg==
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - max-age=0
+ Connection:
+ - Keep-Alive
+ Date:
+ - Wed, 25 Nov 2020 13:43:47 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - pve-api-daemon/3.0
+ Content-Length:
+ - '209'
+ Content-Type:
+ - application/json;charset=UTF-8
+ Expires:
+ - Wed, 25 Nov 2020 13:43:47 GMT
+ body:
+ encoding: ASCII-8BIT
+ string: '{"data":[{"cpu":0.486288911006624,"disk":6172704768,"id":"node/pve","level":"b","maxcpu":32,"maxdisk":773845024768,"maxmem":134936813568,"mem":114900549632,"node":"pve","status":"online","type":"node","uptime":6909898},{"cpu":0.00538129953557645,"disk":1983594496,"diskread":0,"diskwrite":0,"id":"qemu/105","maxcpu":4,"maxdisk":34573647872,"maxmem":17179869184,"mem":0,"name":"test01","netin":0,"netout":0,"node":"pve","status":"stopped","template":0,"type":"qemu","uptime":0,"vmid":100},{"cpu":0.00538129953557645,"disk":1983594496,"diskread":10794659840,"diskwrite":45429886976,"id":"lxc/101","maxcpu":1,"maxdisk":8350298112,"maxmem":2147483648,"mem":116183040,"name":"test02","netin":2258649906,"netout":9957850155,"node":"pve","status":"running","template":0,"type":"lxc","uptime":6907061,"vmid":101},{"content":"vztmpl,iso,backup","disk":5444206592,"id":"storage/pve/local","maxdisk":773845024768,"node":"pve","plugintype":"dir","shared":0,"status":"available","storage":"local","type":"storage"},{"content":"images,rootdir","disk":6525668992656,"id":"storage/pve/storage","maxdisk":31831680352256,"node":"pve","plugintype":"zfspool","shared":0,"status":"available","storage":"storage","type":"storage"}]}'
+ http_version:
+ recorded_at: Wed, 25 Nov 2020 13:43:48 GMT
+recorded_with: VCR 4.0.0
diff --git a/spec/fixtures/proxmox/cluster/common_auth.yml b/spec/fixtures/proxmox/cluster/common_auth.yml
new file mode 100644
index 0000000..e9e1ad4
--- /dev/null
+++ b/spec/fixtures/proxmox/cluster/common_auth.yml
@@ -0,0 +1,40 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://192.168.56.101:8006/api2/json/access/ticket
+ body:
+ encoding: US-ASCII
+ string: username=root%40pam&password=proxmox01
+ headers:
+ User-Agent:
+ - fog-core/2.2.3
+ Accept:
+ - application/json
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - max-age=0
+ Connection:
+ - close, Keep-Alive
+ Date:
+ - Wed, 25 Nov 2020 13:43:47 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - pve-api-daemon/3.0
+ Content-Length:
+ - '1167'
+ Content-Type:
+ - application/json;charset=UTF-8
+ Expires:
+ - Wed, 25 Nov 2020 13:43:47 GMT
+ body:
+ encoding: ASCII-8BIT
+ string: '{"data":{"CSRFPreventionToken":"5FBE5F93:tNCo7nHYIIdA46RVo8yPQg9ZcbtzibFl3lhAwDPkSqc","ticket":"PVE:root@pam:5FBE5F93::J4UGO/cW6NJLxU0fQy8AnxuJhKDkIa+ZLBLUIxlXYO3Nb1ocZ15jqoPl0EEOQpI2sohhmtGYo9bptqaPPH48rmaNKzIUtHjDAg/c425GgbhkSo2jYVeCWcTTEC+nDskOiMkjdE4HIiFLpk71IMEP93hGWJ4+mnUxOLfHsRDodWdJXoGoBlxiUBu0zirFLXR60i6WCK2oX82nPYXRJbsl4VRLYcOkYXnnfaUxYgOL0veZhKRcAWlVRKQ7/lkdG1iu3XlOvEeynqcT2xHs+Z158zALA+ZzAEQ6GYdvFFKr/xR57Kd8hfOhRumKx5EaDfdeYkZP/8ZVH48tEbTXrOEQHg==","cap":{"nodes":{"Sys.Console":1,"Sys.Audit":1,"Sys.PowerMgmt":1,"Permissions.Modify":1,"Sys.Modify":1,"Sys.Syslog":1},"access":{"Group.Allocate":1,"Permissions.Modify":1,"User.Modify":1},"dc":{"Sys.Audit":1},"vms":{"VM.Config.HWType":1,"VM.Migrate":1,"VM.Snapshot.Rollback":1,"VM.Config.Memory":1,"VM.Config.Disk":1,"VM.PowerMgmt":1,"VM.Monitor":1,"VM.Backup":1,"VM.Audit":1,"VM.Config.CDROM":1,"VM.Config.Network":1,"Permissions.Modify":1,"VM.Clone":1,"VM.Allocate":1,"VM.Config.CPU":1,"VM.Console":1,"VM.Config.Options":1,"VM.Snapshot":1},"storage":{"Datastore.Allocate":1,"Permissions.Modify":1,"Datastore.Audit":1,"Datastore.AllocateSpace":1,"Datastore.AllocateTemplate":1}},"username":"root@pam"}}'
+ http_version:
+ recorded_at: Wed, 25 Nov 2020 13:43:48 GMT
+recorded_with: VCR 4.0.0