Skip to content

Commit d612dce

Browse files
committed
feat: StorageCliClient refactored to support different cli providers
- factory init removed since no need different provider classes anymore - all logic moved into init method
1 parent 70105a4 commit d612dce

File tree

5 files changed

+292
-380
lines changed

5 files changed

+292
-380
lines changed

lib/cloud_controller/blobstore/client_provider.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
require 'cloud_controller/blobstore/webdav/dav_client'
66
require 'cloud_controller/blobstore/safe_delete_client'
77
require 'cloud_controller/blobstore/storage_cli/storage_cli_client'
8-
require 'cloud_controller/blobstore/storage_cli/azure_storage_cli_client'
98
require 'google/apis/errors'
109

1110
module CloudController
@@ -72,7 +71,7 @@ def provide_webdav(options, directory_key, root_dir)
7271
end
7372

7473
def provide_storage_cli(options, directory_key, root_dir, resource_type)
75-
client = StorageCliClient.build(
74+
client = StorageCliClient.new(
7675
directory_key: directory_key,
7776
resource_type: resource_type,
7877
root_dir: root_dir,

lib/cloud_controller/blobstore/storage_cli/azure_storage_cli_client.rb

Lines changed: 0 additions & 11 deletions
This file was deleted.

lib/cloud_controller/blobstore/storage_cli/storage_cli_client.rb

Lines changed: 56 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -4,100 +4,79 @@
44
require 'fileutils'
55
require 'cloud_controller/blobstore/base_client'
66
require 'cloud_controller/blobstore/storage_cli/storage_cli_blob'
7-
87
module CloudController
98
module Blobstore
109
class StorageCliClient < BaseClient
1110
attr_reader :root_dir, :min_size, :max_size
1211

13-
@registry = {}
14-
15-
class << self
16-
attr_reader :registry
17-
18-
def register(provider, klass)
19-
registry[provider.to_s] = klass
20-
end
21-
22-
def build(directory_key:, root_dir:, resource_type: nil, min_size: nil, max_size: nil)
23-
raise 'Missing resource_type' if resource_type.nil?
24-
25-
cfg = fetch_config(resource_type)
26-
provider = cfg['provider']
27-
28-
key = provider.to_s
29-
impl_class = registry[key] || registry[key.downcase] || registry[key.upcase]
30-
raise "No storage CLI client registered for provider #{provider}" unless impl_class
31-
32-
impl_class.new(provider: provider, directory_key: directory_key, root_dir: root_dir, resource_type: resource_type, min_size: min_size, max_size: max_size,
33-
config_path: config_path_for(resource_type))
34-
end
35-
36-
RESOURCE_TYPE_KEYS = {
37-
'droplets' => :storage_cli_config_file_droplets,
38-
'buildpack_cache' => :storage_cli_config_file_droplets,
39-
'buildpacks' => :storage_cli_config_file_buildpacks,
40-
'packages' => :storage_cli_config_file_packages,
41-
'resource_pool' => :storage_cli_config_file_resource_pool
42-
}.freeze
12+
RESOURCE_TYPE_KEYS = {
13+
'droplets' => :storage_cli_config_file_droplets,
14+
'buildpack_cache' => :storage_cli_config_file_droplets,
15+
'buildpacks' => :storage_cli_config_file_buildpacks,
16+
'packages' => :storage_cli_config_file_packages,
17+
'resource_pool' => :storage_cli_config_file_resource_pool
18+
}.freeze
4319

44-
def fetch_config(resource_type)
45-
path = config_path_for(resource_type)
46-
validate_config_path!(path)
20+
PROVIDER_TO_STORAGE_CLI_STORAGETYPE = {
21+
'AzureRM' => 'azurebs',
22+
'aliyun' => 'alioss',
23+
'AWS' => 's3',
24+
'webdav' => 'dav',
25+
'Google' => 'gcs'
26+
}.freeze
4727

48-
json = fetch_json(path)
49-
validate_json_object!(json, path)
50-
validate_required_keys!(json, path)
28+
IMPLEMENTED_PROVIDERS = %w[AzureRM aliyun].freeze
5129

52-
json
53-
end
30+
def initialize(directory_key:, resource_type:, root_dir:, min_size: nil, max_size: nil)
31+
raise 'Missing resource_type' if resource_type.nil?
5432

55-
def config_path_for(resource_type)
56-
normalized = resource_type.to_s
57-
key = RESOURCE_TYPE_KEYS.fetch(normalized) do
58-
raise BlobstoreError.new("Unknown resource_type: #{resource_type}")
59-
end
60-
VCAP::CloudController::Config.config.get(key)
61-
end
33+
cfg = fetch_config(resource_type)
34+
@provider = cfg['provider'].to_s
35+
raise BlobstoreError.new('No provider specified in config file') if @provider.empty?
36+
raise "Unimplemented provider: #{@provider}, implemented ones are: #{IMPLEMENTED_PROVIDERS.join(', ')}" unless IMPLEMENTED_PROVIDERS.include?(@provider)
6237

63-
def fetch_json(path)
64-
Oj.load(File.read(path))
65-
rescue Oj::ParseError, EncodingError => e
66-
raise BlobstoreError.new("Failed to parse storage-cli JSON at #{path}: #{e.message}")
67-
end
38+
@cli_path = cli_path
39+
@config_file = config_path_for(resource_type)
40+
@directory_key = directory_key
41+
@resource_type = resource_type.to_s
42+
@root_dir = root_dir
43+
@min_size = min_size || 0
44+
@max_size = max_size
45+
@storage_type = PROVIDER_TO_STORAGE_CLI_STORAGETYPE[@provider]
46+
logger.info('storage_cli_config_selected', resource_type: @resource_type, provider: @provider, path: @config_file)
47+
end
6848

69-
def validate_config_path!(path)
70-
return if path && File.file?(path) && File.readable?(path)
49+
def fetch_config(resource_type)
50+
path = config_path_for(resource_type)
51+
validate_config_path!(path)
7152

72-
raise BlobstoreError.new("Storage-cli config file not found or not readable at: #{path.inspect}")
73-
end
53+
json = fetch_json(path)
54+
validate_json_object!(json, path)
55+
json
56+
end
7457

75-
def validate_json_object!(json, path)
76-
raise BlobstoreError.new("Config at #{path} must be a JSON object") unless json.is_a?(Hash)
58+
def config_path_for(resource_type)
59+
normalized = resource_type.to_s
60+
key = RESOURCE_TYPE_KEYS.fetch(normalized) do
61+
raise BlobstoreError.new("Unknown resource_type: #{resource_type}")
7762
end
63+
VCAP::CloudController::Config.config.get(key)
64+
end
7865

79-
def validate_required_keys!(json, path)
80-
provider = json['provider'].to_s.strip
81-
raise BlobstoreError.new("No provider specified in config file: #{path.inspect}") if provider.empty?
66+
def fetch_json(path)
67+
Oj.load(File.read(path))
68+
rescue Oj::ParseError, EncodingError => e
69+
raise BlobstoreError.new("Failed to parse storage-cli JSON at #{path}: #{e.message}")
70+
end
8271

83-
required = %w[account_key account_name container_name environment]
84-
missing = required.reject { |k| json.key?(k) && !json[k].to_s.strip.empty? }
85-
return if missing.empty?
72+
def validate_config_path!(path)
73+
return if path && File.file?(path) && File.readable?(path)
8674

87-
raise BlobstoreError.new("Missing required keys in #{path}: #{missing.join(', ')}")
88-
end
75+
raise BlobstoreError.new("Storage-cli config file not found or not readable at: #{path.inspect}")
8976
end
9077

91-
def initialize(provider:, directory_key:, resource_type:, root_dir:, config_path:, min_size: nil, max_size: nil)
92-
@cli_path = cli_path
93-
@directory_key = directory_key
94-
@resource_type = resource_type.to_s
95-
@root_dir = root_dir
96-
@min_size = min_size || 0
97-
@max_size = max_size
98-
@provider = provider
99-
@config_file = config_path
100-
logger.info('storage_cli_config_selected', resource_type: @resource_type, path: @config_file)
78+
def validate_json_object!(json, path)
79+
raise BlobstoreError.new("Config at #{path} must be a JSON object") unless json.is_a?(Hash)
10180
end
10281

10382
def local?
@@ -192,7 +171,7 @@ def run_cli(command, *args, allow_exit_code_three: false)
192171
logger.info("[storage_cli_client] Running storage-cli: #{@cli_path} -c #{@config_file} #{command} #{args.join(' ')}")
193172

194173
begin
195-
stdout, stderr, status = Open3.capture3(@cli_path, '-c', @config_file, command, *args)
174+
stdout, stderr, status = Open3.capture3(@cli_path, '-s', @storage_type, '-c', @config_file, command, *args)
196175
rescue StandardError => e
197176
raise BlobstoreError.new(e.inspect)
198177
end
@@ -224,7 +203,7 @@ def properties(key)
224203
end
225204

226205
def cli_path
227-
raise NotImplementedError
206+
ENV['STORAGE_CLI_PATH'] || '/var/vcap/packages/storage-cli/bin/storage-cli'
228207
end
229208

230209
def build_config(connection_config)

0 commit comments

Comments
 (0)