From 77a7ba8e8a8e2cd4d8e62068e5155865c1029f6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C4=81vis=20Mos=C4=81ns?= Date: Wed, 9 Oct 2024 17:55:41 +0300 Subject: [PATCH] Implement `Storage#upload()` request --- lib/fog/proxmox/core.rb | 2 +- lib/fog/proxmox/storage.rb | 51 +++++++++++++++++++++- lib/fog/proxmox/storage/requests/upload.rb | 45 +++++++++++++++++++ 3 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 lib/fog/proxmox/storage/requests/upload.rb diff --git a/lib/fog/proxmox/core.rb b/lib/fog/proxmox/core.rb index 2807936..879ee8c 100644 --- a/lib/fog/proxmox/core.rb +++ b/lib/fog/proxmox/core.rb @@ -93,7 +93,7 @@ def request(params) authenticate! if expired? request_options = params.merge(path: "#{@path}/#{params[:path]}", headers: @auth_token.headers( - params[:method], params.respond_to?(:headers) ? params[:headers] : {}, {} + params[:method], {}, params.key?(:headers) ? params[:headers] : {} )) response = @connection.request(request_options) rescue Excon::Errors::Unauthorized => e diff --git a/lib/fog/proxmox/storage.rb b/lib/fog/proxmox/storage.rb index 9eb98aa..446cec1 100644 --- a/lib/fog/proxmox/storage.rb +++ b/lib/fog/proxmox/storage.rb @@ -22,8 +22,57 @@ module Fog module Proxmox # Procmox storage service class Storage < 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/storage' + model_path 'fog/proxmox/storage/models' + + request_path 'fog/proxmox/storage/requests' + + request :upload + + # 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::Storage::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/storage/requests/upload.rb b/lib/fog/proxmox/storage/requests/upload.rb new file mode 100644 index 0000000..49d571b --- /dev/null +++ b/lib/fog/proxmox/storage/requests/upload.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'securerandom' + +module Fog + module Proxmox + class Storage + # class Real upload + class Real + def upload(path_params, body_params) + node = path_params[:node] + storage = path_params[:storage] + body, content_type = self.class.build_formdata(body_params) + request( + expects: [200], + method: 'POST', + path: "nodes/#{node}/storage/#{storage}/upload", + body: body, + headers: { 'Content-Type' => content_type } + ) + end + + private + def self.build_formdata(body_params) + boundary = '-' * 30 + SecureRandom.hex(15) + + body = "--#{boundary}" + Excon::CR_NL + body << 'Content-Disposition: form-data; name="content"' << Excon::CR_NL << Excon::CR_NL + body << body_params[:content] << Excon::CR_NL + body << "--#{boundary}" << Excon::CR_NL + body << %{Content-Disposition: form-data; name="filename"; filename="#{body_params[:filename]}"} << Excon::CR_NL + body << "Content-Type: " << (body_params[:content_type] || 'application/octet-stream') << Excon::CR_NL << Excon::CR_NL + body << body_params[:file].read << Excon::CR_NL + body << "--#{boundary}--" << Excon::CR_NL + + [body, %{multipart/form-data; boundary=#{boundary}}] + end + end + + # class Mock upload + class Mock + end + end + end +end