workato-connector-sdk 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.md +20 -0
- data/README.md +1093 -0
- data/exe/workato +5 -0
- data/lib/workato/cli/edit_command.rb +71 -0
- data/lib/workato/cli/exec_command.rb +191 -0
- data/lib/workato/cli/generate_command.rb +105 -0
- data/lib/workato/cli/generators/connector_generator.rb +94 -0
- data/lib/workato/cli/generators/master_key_generator.rb +56 -0
- data/lib/workato/cli/main.rb +142 -0
- data/lib/workato/cli/push_command.rb +208 -0
- data/lib/workato/connector/sdk/account_properties.rb +60 -0
- data/lib/workato/connector/sdk/action.rb +88 -0
- data/lib/workato/connector/sdk/block_invocation_refinements.rb +30 -0
- data/lib/workato/connector/sdk/connector.rb +230 -0
- data/lib/workato/connector/sdk/dsl/account_property.rb +15 -0
- data/lib/workato/connector/sdk/dsl/call.rb +17 -0
- data/lib/workato/connector/sdk/dsl/error.rb +15 -0
- data/lib/workato/connector/sdk/dsl/http.rb +60 -0
- data/lib/workato/connector/sdk/dsl/lookup_table.rb +15 -0
- data/lib/workato/connector/sdk/dsl/time.rb +21 -0
- data/lib/workato/connector/sdk/dsl/workato_code_lib.rb +105 -0
- data/lib/workato/connector/sdk/dsl/workato_schema.rb +15 -0
- data/lib/workato/connector/sdk/dsl.rb +46 -0
- data/lib/workato/connector/sdk/errors.rb +30 -0
- data/lib/workato/connector/sdk/lookup_tables.rb +62 -0
- data/lib/workato/connector/sdk/object_definitions.rb +74 -0
- data/lib/workato/connector/sdk/operation.rb +217 -0
- data/lib/workato/connector/sdk/request.rb +399 -0
- data/lib/workato/connector/sdk/settings.rb +130 -0
- data/lib/workato/connector/sdk/summarize.rb +61 -0
- data/lib/workato/connector/sdk/trigger.rb +96 -0
- data/lib/workato/connector/sdk/version.rb +9 -0
- data/lib/workato/connector/sdk/workato_schemas.rb +37 -0
- data/lib/workato/connector/sdk/xml.rb +35 -0
- data/lib/workato/connector/sdk.rb +58 -0
- data/lib/workato/extension/array.rb +124 -0
- data/lib/workato/extension/case_sensitive_headers.rb +51 -0
- data/lib/workato/extension/currency.rb +15 -0
- data/lib/workato/extension/date.rb +14 -0
- data/lib/workato/extension/enumerable.rb +55 -0
- data/lib/workato/extension/extra_chain_cert.rb +40 -0
- data/lib/workato/extension/hash.rb +13 -0
- data/lib/workato/extension/integer.rb +17 -0
- data/lib/workato/extension/nil_class.rb +17 -0
- data/lib/workato/extension/object.rb +38 -0
- data/lib/workato/extension/phone.rb +14 -0
- data/lib/workato/extension/string.rb +268 -0
- data/lib/workato/extension/symbol.rb +13 -0
- data/lib/workato/extension/time.rb +13 -0
- data/lib/workato/testing/vcr_encrypted_cassette_serializer.rb +38 -0
- data/lib/workato/testing/vcr_multipart_body_matcher.rb +32 -0
- data/lib/workato-connector-sdk.rb +3 -0
- data/templates/.rspec.erb +3 -0
- data/templates/Gemfile.erb +10 -0
- data/templates/connector.rb.erb +37 -0
- data/templates/spec/action_spec.rb.erb +36 -0
- data/templates/spec/connector_spec.rb.erb +18 -0
- data/templates/spec/method_spec.rb.erb +13 -0
- data/templates/spec/object_definition_spec.rb.erb +18 -0
- data/templates/spec/pick_list_spec.rb.erb +13 -0
- data/templates/spec/spec_helper.rb.erb +38 -0
- data/templates/spec/trigger_spec.rb.erb +61 -0
- metadata +372 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Workato
|
4
|
+
module CLI
|
5
|
+
module Generators
|
6
|
+
class MasterKeyGenerator < Thor::Group
|
7
|
+
include Thor::Actions
|
8
|
+
|
9
|
+
no_commands do
|
10
|
+
def call(key_path = Workato::Connector::Sdk::DEFAULT_MASTER_KEY_PATH)
|
11
|
+
create_key_file(key_path)
|
12
|
+
ignore_key_file(key_path)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_key_file(key_path = Workato::Connector::Sdk::DEFAULT_MASTER_KEY_PATH)
|
17
|
+
raise "#{key_path} already exists" if File.exist?(key_path)
|
18
|
+
|
19
|
+
key = ActiveSupport::EncryptedFile.generate_key
|
20
|
+
|
21
|
+
say "Adding #{key_path} to store the encryption key: #{key}"
|
22
|
+
say ''
|
23
|
+
say 'Save this in a password manager your team can access.'
|
24
|
+
say "Don't store the file in a public place, make sure you're sharing it privately."
|
25
|
+
say ''
|
26
|
+
say 'If you lose the key, no one, including you, can access anything encrypted with it.'
|
27
|
+
|
28
|
+
say ''
|
29
|
+
|
30
|
+
File.open(key_path, 'w') do |f|
|
31
|
+
f.write(key)
|
32
|
+
f.chmod 0o600
|
33
|
+
end
|
34
|
+
|
35
|
+
say ''
|
36
|
+
end
|
37
|
+
|
38
|
+
def ignore_key_file(key_path = Workato::Connector::Sdk::DEFAULT_MASTER_KEY_PATH)
|
39
|
+
ignore = [' ', "/#{key_path}", ' '].join("\n")
|
40
|
+
if File.exist?('.gitignore')
|
41
|
+
unless File.read('.gitignore').include?(ignore)
|
42
|
+
say "Ignoring #{key_path} so it won't end up in Git history:"
|
43
|
+
say ''
|
44
|
+
append_to_file '.gitignore', ignore
|
45
|
+
say ''
|
46
|
+
end
|
47
|
+
else
|
48
|
+
say "IMPORTANT: Don't commit #{key_path}. Add this to your ignore file:"
|
49
|
+
say ignore, :on_green
|
50
|
+
say ''
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
require 'workato/connector/sdk'
|
5
|
+
require_relative './exec_command'
|
6
|
+
require_relative './edit_command'
|
7
|
+
require_relative './generate_command'
|
8
|
+
require_relative './push_command'
|
9
|
+
require_relative './generators/connector_generator'
|
10
|
+
require_relative './generators/master_key_generator'
|
11
|
+
|
12
|
+
module Workato
|
13
|
+
module CLI
|
14
|
+
class Main < Thor
|
15
|
+
class_option :verbose, type: :boolean
|
16
|
+
|
17
|
+
desc 'exec <PATH>', 'Execute connector defined block'
|
18
|
+
long_desc <<~HELP
|
19
|
+
The 'workato exec' executes connector's lambda block at <PATH>.
|
20
|
+
Lambda's parameters can be provided if needed, see options part.
|
21
|
+
|
22
|
+
Example:
|
23
|
+
|
24
|
+
workato exec actions.foo.execute # This executes execute block of foo action
|
25
|
+
|
26
|
+
workato exec triggers.bar.poll # This executes poll block of bar action
|
27
|
+
|
28
|
+
workato exec methods.bazz --args=input.json # This executes methods with params from input.json
|
29
|
+
HELP
|
30
|
+
|
31
|
+
method_option :connector, type: :string, aliases: '-c', desc: 'Path to connector source code',
|
32
|
+
lazy_default: Workato::Connector::Sdk::DEFAULT_CONNECTOR_PATH
|
33
|
+
method_option :settings, type: :string, aliases: '-s',
|
34
|
+
desc: 'Path to plain or encrypted file with connection configs, '\
|
35
|
+
'passwords, tokens, secrets etc',
|
36
|
+
lazy_default: Workato::Connector::Sdk::DEFAULT_ENCRYPTED_SETTINGS_PATH
|
37
|
+
method_option :connection, type: :string, aliases: '-n',
|
38
|
+
desc: 'Connection name if settings file contains multiple settings'
|
39
|
+
method_option :key, type: :string, aliases: '-k',
|
40
|
+
lazy_default: Workato::Connector::Sdk::DEFAULT_MASTER_KEY_PATH,
|
41
|
+
desc: 'Path to file with encrypt/decrypt key. '\
|
42
|
+
"NOTE: key from #{Workato::Connector::Sdk::DEFAULT_MASTER_KEY_ENV} has higher priority"
|
43
|
+
method_option :input, type: :string, aliases: '-i', desc: 'Path to file with input JSON'
|
44
|
+
method_option :closure, type: :string, desc: 'Path to file with next poll closure JSON'
|
45
|
+
method_option :args, type: :string, aliases: '-a', desc: 'Path to file with method arguments JSON'
|
46
|
+
method_option :extended_input_schema, type: :string,
|
47
|
+
desc: 'Path to file with extended input schema definition JSON'
|
48
|
+
method_option :extended_output_schema, type: :string,
|
49
|
+
desc: 'Path to file with extended output schema definition JSON'
|
50
|
+
method_option :config_fields, type: :string, desc: 'Path to file with config fields JSON'
|
51
|
+
method_option :webhook_payload, type: :string, aliases: '-w', desc: 'Path to file with webhook payload JSON'
|
52
|
+
method_option :webhook_params, type: :string, desc: 'Path to file with webhook params JSON'
|
53
|
+
method_option :webhook_headers, type: :string, desc: 'Path to file with webhook headers JSON'
|
54
|
+
method_option :webhook_url, type: :string, desc: 'Webhook URL for automatic webhook subscription'
|
55
|
+
method_option :output, type: :string, aliases: '-o', desc: 'Write output to JSON file'
|
56
|
+
|
57
|
+
method_option :debug, type: :boolean
|
58
|
+
|
59
|
+
def exec(path)
|
60
|
+
ExecCommand.new(
|
61
|
+
path: path,
|
62
|
+
options: options
|
63
|
+
).call
|
64
|
+
end
|
65
|
+
|
66
|
+
desc 'edit <PATH>', 'Edit encrypted file, e.g. settings.yaml.enc'
|
67
|
+
|
68
|
+
method_option :key, type: :string, aliases: '-k',
|
69
|
+
lazy_default: Workato::Connector::Sdk::DEFAULT_MASTER_KEY_PATH,
|
70
|
+
desc: 'Path to file with encrypt/decrypt key. '\
|
71
|
+
"NOTE: key from #{Workato::Connector::Sdk::DEFAULT_MASTER_KEY_ENV} has higher priority"
|
72
|
+
|
73
|
+
def edit(path)
|
74
|
+
EditCommand.new(
|
75
|
+
path: path,
|
76
|
+
options: options
|
77
|
+
).call
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.exit_on_failure?
|
81
|
+
true
|
82
|
+
end
|
83
|
+
|
84
|
+
long_desc <<~HELP
|
85
|
+
The 'workato new' command creates a new Workato connector with a default
|
86
|
+
directory structure and configuration at the path you specify.
|
87
|
+
|
88
|
+
Example:
|
89
|
+
workato new ~/dev/workato/random
|
90
|
+
|
91
|
+
This generates a skeletal custom connector in ~/dev/workato/random.
|
92
|
+
HELP
|
93
|
+
register(Generators::ConnectorGenerator, 'new', 'new <CONNECTOR_PATH>', 'Inits new connector folder')
|
94
|
+
|
95
|
+
desc 'generate <SUBCOMMAND>', 'Generates code from template'
|
96
|
+
subcommand('generate', GenerateCommand)
|
97
|
+
|
98
|
+
desc 'push <FOLDER>', "Upload and release connector's code"
|
99
|
+
method_option :title,
|
100
|
+
type: :string,
|
101
|
+
aliases: '-t',
|
102
|
+
desc: 'Connector title on the Workato Platform'
|
103
|
+
method_option :description,
|
104
|
+
type: :string,
|
105
|
+
aliases: '-d',
|
106
|
+
desc: 'Path to connector description: Markdown or plain text'
|
107
|
+
method_option :logo,
|
108
|
+
type: :string,
|
109
|
+
aliases: '-l',
|
110
|
+
desc: 'Path to connector logo: png or jpeg file'
|
111
|
+
method_option :notes,
|
112
|
+
type: :string,
|
113
|
+
aliases: '-n',
|
114
|
+
desc: 'Release notes'
|
115
|
+
method_option :connector,
|
116
|
+
type: :string,
|
117
|
+
aliases: '-c',
|
118
|
+
desc: 'Path to connector source code',
|
119
|
+
lazy_default: Workato::Connector::Sdk::DEFAULT_CONNECTOR_PATH
|
120
|
+
method_option :api_email,
|
121
|
+
type: :string,
|
122
|
+
desc: 'Email for accessing Workato API or '\
|
123
|
+
"set #{Workato::CLI::PushCommand::WORKATO_API_EMAIL_ENV} env"
|
124
|
+
method_option :api_token,
|
125
|
+
type: :string,
|
126
|
+
desc: 'Token for accessing Workato API or ' \
|
127
|
+
"set #{Workato::CLI::PushCommand::WORKATO_API_TOKEN_ENV} env"
|
128
|
+
method_option :environment,
|
129
|
+
type: :string,
|
130
|
+
enum: Workato::CLI::PushCommand::ENVIRONMENTS.keys,
|
131
|
+
default: 'live',
|
132
|
+
desc: 'Server to push connector code to'
|
133
|
+
|
134
|
+
def push(folder)
|
135
|
+
PushCommand.new(
|
136
|
+
folder: folder,
|
137
|
+
options: options
|
138
|
+
).call
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'uri'
|
4
|
+
require 'ruby-progressbar'
|
5
|
+
require 'zip'
|
6
|
+
|
7
|
+
module Workato
|
8
|
+
module CLI
|
9
|
+
class PushCommand
|
10
|
+
include Thor::Shell
|
11
|
+
|
12
|
+
WORKATO_API_TOKEN_ENV = 'WORKATO_API_TOKEN'
|
13
|
+
WORKATO_API_EMAIL_ENV = 'WORKATO_API_EMAIL'
|
14
|
+
|
15
|
+
ENVIRONMENTS = {
|
16
|
+
'preview' => 'https://app.preview.workato.com',
|
17
|
+
'preview-eu' => 'https://app.preview.eu.workato.com',
|
18
|
+
'live' => 'https://app.workato.com',
|
19
|
+
'live-eu' => 'https://app.eu.workato.com'
|
20
|
+
}.freeze
|
21
|
+
|
22
|
+
API_IMPORT_PATH = '/api/packages/import'
|
23
|
+
API_PACKAGE_PATH = '/api/packages'
|
24
|
+
IMPORT_IN_PROGRESS = 'in_progress'
|
25
|
+
|
26
|
+
DEFAULT_LOGO_PATH = 'logo.png'
|
27
|
+
DEFAULT_README_PATH = 'README.md'
|
28
|
+
PACKAGE_ENTRY_NAME = 'connector.custom_adapter'
|
29
|
+
|
30
|
+
AWAIT_IMPORT_SLEEP_INTERVAL = 15 # seconds
|
31
|
+
AWAIT_IMPORT_TIMEOUT_INTERVAL = 120 # seconds
|
32
|
+
|
33
|
+
def initialize(folder:, options:)
|
34
|
+
@folder_id = folder
|
35
|
+
@options = options
|
36
|
+
@api_base_url = ENVIRONMENTS.fetch(options[:environment])
|
37
|
+
@api_email = options[:api_email] || ENV[WORKATO_API_EMAIL_ENV]
|
38
|
+
@api_token = options[:api_token] || ENV[WORKATO_API_TOKEN_ENV]
|
39
|
+
end
|
40
|
+
|
41
|
+
def call
|
42
|
+
zip_file = build_package
|
43
|
+
say_status :success, 'Build package' if verbose?
|
44
|
+
|
45
|
+
import_id = import_package(zip_file)
|
46
|
+
say_status :success, 'Upload package' if verbose?
|
47
|
+
say_status :waiting, 'Process package' if verbose?
|
48
|
+
|
49
|
+
result = await_import(import_id)
|
50
|
+
if result.fetch('status') == 'failed'
|
51
|
+
say result.fetch('error').gsub("#{PACKAGE_ENTRY_NAME}.json: ", '')
|
52
|
+
else
|
53
|
+
say "Connector was successfully uploaded to #{api_base_url}"
|
54
|
+
end
|
55
|
+
rescue StandardError => e
|
56
|
+
say e.message
|
57
|
+
ensure
|
58
|
+
zip_file&.close(true)
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
attr_reader :options,
|
64
|
+
:folder_id,
|
65
|
+
:api_token,
|
66
|
+
:api_email,
|
67
|
+
:api_base_url
|
68
|
+
|
69
|
+
def verbose?
|
70
|
+
@options[:verbose]
|
71
|
+
end
|
72
|
+
|
73
|
+
def notes
|
74
|
+
options[:notes].presence || loop do
|
75
|
+
answer = ask('Please add release notes:')
|
76
|
+
break answer if answer.present?
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def build_package
|
81
|
+
zip_file = Tempfile.new(['connector', '.zip'])
|
82
|
+
|
83
|
+
::Zip::OutputStream.open(zip_file.path) { |_| 'no-op' }
|
84
|
+
::Zip::File.open(zip_file.path, ::Zip::File::CREATE) do |archive|
|
85
|
+
add_connector(archive)
|
86
|
+
add_manifest(archive)
|
87
|
+
add_logo(archive)
|
88
|
+
end
|
89
|
+
|
90
|
+
zip_file
|
91
|
+
end
|
92
|
+
|
93
|
+
def add_connector(archive)
|
94
|
+
archive.get_output_stream("#{PACKAGE_ENTRY_NAME}.rb") do |f|
|
95
|
+
f.write(File.read(options[:connector] || Workato::Connector::Sdk::DEFAULT_CONNECTOR_PATH))
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def add_manifest(archive)
|
100
|
+
archive.get_output_stream("#{PACKAGE_ENTRY_NAME}.json") do |f|
|
101
|
+
f.write(JSON.pretty_generate(metadata))
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def add_logo(archive)
|
106
|
+
return unless logo
|
107
|
+
|
108
|
+
archive.get_output_stream("#{PACKAGE_ENTRY_NAME}#{logo[:extname]}") do |f|
|
109
|
+
f.write(logo[:content])
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def import_package(zip_file)
|
114
|
+
url = "#{api_base_url}#{API_IMPORT_PATH}/#{folder_id}"
|
115
|
+
response = RestClient.post(
|
116
|
+
url,
|
117
|
+
File.open(zip_file.path),
|
118
|
+
auth_headers.merge(
|
119
|
+
'Content-Type' => 'application/zip'
|
120
|
+
)
|
121
|
+
)
|
122
|
+
JSON.parse(response.body).fetch('id')
|
123
|
+
rescue RestClient::NotFound
|
124
|
+
raise "Can't find folder with ID=#{folder_id}"
|
125
|
+
rescue RestClient::BadRequest => e
|
126
|
+
message = JSON.parse(e.response.body).fetch('error')
|
127
|
+
raise "Failed to upload connector: #{message}"
|
128
|
+
end
|
129
|
+
|
130
|
+
def await_import(import_id)
|
131
|
+
url = "#{api_base_url}#{API_PACKAGE_PATH}/#{import_id}"
|
132
|
+
Timeout.timeout(AWAIT_IMPORT_TIMEOUT_INTERVAL) do
|
133
|
+
loop do
|
134
|
+
response = RestClient.get(url, auth_headers)
|
135
|
+
|
136
|
+
json = JSON.parse(response.body)
|
137
|
+
break json if json.fetch('status') != IMPORT_IN_PROGRESS
|
138
|
+
|
139
|
+
sleep(AWAIT_IMPORT_SLEEP_INTERVAL)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
rescue Timeout::Error
|
143
|
+
raise 'Failed to wait import result. Go to Imports in Workato UI to see the push result'
|
144
|
+
end
|
145
|
+
|
146
|
+
def logo
|
147
|
+
return @logo if defined?(@logo)
|
148
|
+
|
149
|
+
path = (options.key?(:logo) && options[:logo]) ||
|
150
|
+
(File.exist?(DEFAULT_LOGO_PATH) && DEFAULT_LOGO_PATH)
|
151
|
+
return @logo = nil unless path
|
152
|
+
|
153
|
+
extname = File.extname(path).downcase
|
154
|
+
@logo = {
|
155
|
+
extname: extname,
|
156
|
+
content: File.read(path),
|
157
|
+
content_type: extname == '.png' ? 'image/png' : 'image/jpeg'
|
158
|
+
}
|
159
|
+
end
|
160
|
+
|
161
|
+
def metadata
|
162
|
+
{
|
163
|
+
title: title,
|
164
|
+
description: description,
|
165
|
+
note: notes
|
166
|
+
}.tap do |meta|
|
167
|
+
if logo
|
168
|
+
meta[:logo_file_name] = 'data'
|
169
|
+
meta[:logo_content_type] = logo[:content_type]
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def title
|
175
|
+
options[:title].presence || connector.title.presence || loop do
|
176
|
+
answer = ask('Please provide title of the connector:')
|
177
|
+
break answer if answer.present?
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def description
|
182
|
+
(options[:description].presence && File.read(options[:description])) ||
|
183
|
+
(File.exist?(DEFAULT_README_PATH) && File.read(DEFAULT_README_PATH)) ||
|
184
|
+
nil
|
185
|
+
end
|
186
|
+
|
187
|
+
def connector
|
188
|
+
@connector ||= Workato::Connector::Sdk::Connector.from_file(
|
189
|
+
options[:connector] || Workato::Connector::Sdk::DEFAULT_CONNECTOR_PATH
|
190
|
+
)
|
191
|
+
end
|
192
|
+
|
193
|
+
def auth_headers
|
194
|
+
{
|
195
|
+
'x-user-email' => api_email,
|
196
|
+
'x-user-token' => api_token
|
197
|
+
}
|
198
|
+
end
|
199
|
+
|
200
|
+
private_constant :IMPORT_IN_PROGRESS,
|
201
|
+
:API_IMPORT_PATH,
|
202
|
+
:API_PACKAGE_PATH,
|
203
|
+
:PACKAGE_ENTRY_NAME,
|
204
|
+
:AWAIT_IMPORT_SLEEP_INTERVAL,
|
205
|
+
:AWAIT_IMPORT_TIMEOUT_INTERVAL
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'csv'
|
4
|
+
require 'erb'
|
5
|
+
require 'singleton'
|
6
|
+
|
7
|
+
module Workato
|
8
|
+
module Connector
|
9
|
+
module Sdk
|
10
|
+
class AccountProperties
|
11
|
+
include Singleton
|
12
|
+
|
13
|
+
def self.from_yaml(path = DEFAULT_ACCOUNT_PROPERTIES_PATH)
|
14
|
+
File.open(path) do |f|
|
15
|
+
instance.load_data(YAML.safe_load(ERB.new(f.read).result, [::Symbol]).to_hash)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.from_encrypted_yaml(path = DEFAULT_ENCRYPTED_ACCOUNT_PROPERTIES_PATH, key_path = nil)
|
20
|
+
load_data(
|
21
|
+
ActiveSupport::EncryptedConfiguration.new(
|
22
|
+
config_path: path,
|
23
|
+
key_path: key_path || DEFAULT_MASTER_KEY_PATH,
|
24
|
+
env_key: DEFAULT_MASTER_KEY_ENV,
|
25
|
+
raise_if_missing_key: true
|
26
|
+
).config
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.from_csv(path = './account_properties.csv')
|
31
|
+
props = CSV.foreach(path, headers: true, return_headers: false).map do |row|
|
32
|
+
[row[0], row[1]]
|
33
|
+
end.to_h
|
34
|
+
instance.load_data(props)
|
35
|
+
end
|
36
|
+
|
37
|
+
class << self
|
38
|
+
delegate :load_data,
|
39
|
+
:get,
|
40
|
+
:put,
|
41
|
+
to: :instance
|
42
|
+
end
|
43
|
+
|
44
|
+
def get(key)
|
45
|
+
@data ||= {}
|
46
|
+
@data[key.to_s]
|
47
|
+
end
|
48
|
+
|
49
|
+
def put(key, value)
|
50
|
+
@data ||= {}
|
51
|
+
@data[key.to_s] = value.to_s
|
52
|
+
end
|
53
|
+
|
54
|
+
def load_data(props = {})
|
55
|
+
props.each { |k, v| put(k, v) }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|