gorynich 1.1.1.148381 → 1.2.0.180668

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64b2a2381ebeca46d78d55e1c60ae743574cba05e521dab121f58b633ab7020e
4
- data.tar.gz: 83548d76917b9c7db035133e0131ec0dfe0934db80893d9e22cd7a7eaa8582c8
3
+ metadata.gz: bfa5eb9e2309dbcb2cf03355c6f5e138789f8fe9e2b3c7ab670de90d6d3ac55a
4
+ data.tar.gz: 4cff866be86f922c0ac2e008cec177e674ee3a28b4d884e501809740e9eb169d
5
5
  SHA512:
6
- metadata.gz: 438461a1fced07b637c5a582b7a058ec6bd79a541e69433a4a5907bfd71da7207803323b11dcffd409130669e438ddd81b4faff20a0c8538594d8fd6ec801dda
7
- data.tar.gz: 9c62f0ad4172188406b59151fc52fa9164fd5bc05cd4ea44134b5c3fa6e5ac2ef352f5c07c842328ba76fe750b9ab1c59d792c9cb4197291ab049c5999073aec
6
+ metadata.gz: 1ad533e8db97798dd44be95f527eff513f1b641a0f7bc90f6b4b7caed6ce2f104c1be1739233bc11ede063671f72634b988c56775c819dcf9276d0fbeb9341d0
7
+ data.tar.gz: 12464ea4be054bb26aa9c3f6934bbe1eadcb5cbc1573aabee6a13cae93b35b8aea1998113d0e485ef4c344f72e904ec5eaf3f5a44f8934ae44163ab14dd12f62
data/README.md CHANGED
@@ -16,7 +16,7 @@
16
16
 
17
17
  `Gorynich` - это гем для реализации [мультитенантности](https://ru.wikipedia.org/wiki/Мультиарендность) (мультиарендности) в Ruby on Rails приложении. Позволяет обеспечить строгую изоляцию данных в нескольких СУБД, поддерживаемых в ActiveRecord.
18
18
 
19
- Поскольку мультитенантное приложение тесно связано с разделением данных, которые в свою очередь могут находиться в разных источниках (СУБД, S3, Redis и пр.), а также с их обработкой в разных подсистемах (ActiveJob, ActionCable), мы выбрали название ["Горыныч"](https://ru.wikipedia.org/wiki/Змей_Горыныч), чтобы подчеркнуть ~многоголовость~ многогранность интеграций.
19
+ Поскольку мультитенантное приложение тесно связано с разделением данных, которые в свою очередь могут находиться в разных источниках (СУБД, S3, Redis и пр.), а также с их обработкой в разных подсистемах (ActiveJob, ActionCable), мы выбрали название ["Горыныч"](https://ru.wikipedia.org/wiki/Змей_Горыныч), чтобы подчеркнуть ~многоголовость~ многогранность интеграций.
20
20
 
21
21
  ---
22
22
 
@@ -66,14 +66,14 @@ gem 'gorynich'
66
66
  ```sh
67
67
  bundle install # для установки гема / gem installation
68
68
 
69
- rails generate gorynich:install # для добавления шаблонов конфигурации / install configuration templates
69
+ rails generate gorynich:install # для добавления шаблонов конфигурации / install configuration templates
70
70
  ```
71
71
 
72
72
  ## Что такое тенант? / What tenant is?
73
73
 
74
74
  Тенант (в данном случае) - это активное подключение к СУБД, а также доступный в любом месте объект `Gorynich::Current`, в котором находятся параметры текущего тенанта. К нему можно обратиться в любом месте.
75
75
 
76
- ---
76
+ ---
77
77
 
78
78
  In this case tenant is an active connection to the DBMS, as well as a `Gorynich::Current` object available anywhere, which contains the parameters of the current tenant. You can refer to it anywhere, for example when sending emails:
79
79
 
@@ -94,7 +94,7 @@ end
94
94
 
95
95
  Например, при отправке писем изнутри ActiveJob использование выглядит так:
96
96
 
97
- ---
97
+ ---
98
98
 
99
99
  Before request processing [Gorynich::Rack::RackMiddleware](./lib/gorynich/head/rack_middleware.rb) ActiveRecord connection switching to apropriate database. Additional tenant properties available in any part of application through [ActiveSupport::CurrentAttributes](https://api.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html) as `Gorynich::Current` instance. ActionCable, ActiveJob and other "heads" also uses `Gorynich::Current` to store context and evaluate it later.
100
100
 
@@ -130,19 +130,21 @@ end
130
130
 
131
131
  ## Использование / Usage
132
132
 
133
- ### Настройка источника данных / Configuration source
133
+ ### Настройка источника данных / Configuration source
134
134
 
135
- Для использования необходимо в файле `config/application.rb` добавить источник данных. Сейчас доступны 2 источника:
135
+ Для использования необходимо в файле `config/application.rb` добавить источник данных. Сейчас доступны 3 источника:
136
136
 
137
137
  ---
138
138
 
139
- Now you need to select configuration source in `config/application.rb`. Yuo can choose from 2 source types now:
139
+ Now you need to select configuration source in `config/application.rb`. Yuo can choose from 3 source types now:
140
140
 
141
141
 
142
142
  ```ruby
143
143
  Gorynich::Fetchers::File.new(file_path: [FILE_PATH]) # из файла / from file
144
144
 
145
145
  Gorynich::Fetchers::Consul.new(storage: [CONSUL_KEY], **options) # из консула / from consul (options - from Dimplomat gem https://github.com/WeAreFarmGeek/diplomat)
146
+
147
+ Gorynich::Fetchers::ConsulSecure.new(storage: [CONSUL_KEY], file_path: [FILE_PATH], **options) # из консула с сохранением в файл (при недоступности консула будет читать из файла) / from consul with saving to a file (if unavailable, consul will read from the file) (options - from Dimplomat gem https://github.com/WeAreFarmGeek/diplomat)
146
148
  ```
147
149
 
148
150
  Пример / Example:
@@ -214,7 +216,7 @@ TENANT=tenant rails gc # default tenant name id 'default'
214
216
 
215
217
  Для создания статичного файла `database.yml` из источника данных (Fetcher) используйте:
216
218
 
217
- ---
219
+ ---
218
220
 
219
221
  For static `database.yml` generation from configured source (Fetcher) use:
220
222
 
@@ -228,7 +230,7 @@ rails gc:db:prepare
228
230
 
229
231
  Первый, самый простой способ работы, подходящий для локальной разработки, это статическая генерация `database.yml`.
230
232
 
231
- ---
233
+ ---
232
234
 
233
235
  First and most simple using of Gorynich handy for local development is static `database.yml` generation.
234
236
 
@@ -240,7 +242,7 @@ rails gc:db:prepare
240
242
 
241
243
  2. Полуавтоматический режим / Semi-automated mode
242
244
 
243
- Второй вариант - это создание конфигурации `database.yml` при старте Rails приложения - данные будут прочитаны из настроенного источника. В этом случае конфигурация СУБД может изменяться только при перезапуске приложения, но остальные настройки, такие как привязка тенантов к доменам и secrets, будут подхватываться "на лету" непосредственно во время работы приложения. Rake-задачи `db:create`, `db:migrate` работают для всех тенантов на момент запуска.
245
+ Второй вариант - это создание конфигурации `database.yml` при старте Rails приложения - данные будут прочитаны из настроенного источника. В этом случае конфигурация СУБД может изменяться только при перезапуске приложения, но остальные настройки, такие как привязка тенантов к доменам и secrets, будут подхватываться "на лету" непосредственно во время работы приложения. Rake-задачи `db:create`, `db:migrate` работают для всех тенантов на момент запуска.
244
246
 
245
247
  ---
246
248
 
@@ -353,7 +355,7 @@ config.telegram_updates_controller.session_store = :redis_cache_store, {
353
355
  }
354
356
  ```
355
357
 
356
- ### Shrine
358
+ ### Shrine
357
359
 
358
360
  ```ruby
359
361
  #lib/shrine/plugins/tenant_location.rb
@@ -1,5 +1,6 @@
1
1
  require_relative 'fetchers/file'
2
2
  require_relative 'fetchers/consul'
3
+ require_relative 'fetchers/consul_secure'
3
4
 
4
5
  module Gorynich
5
6
  class Fetcher
@@ -32,7 +33,7 @@ module Gorynich
32
33
  elsif @fetcher.is_a?(Array)
33
34
  result = {}
34
35
  @fetcher.each do |f|
35
- result =
36
+ result =
36
37
  begin
37
38
  f.fetch
38
39
  rescue ::StandardError
@@ -0,0 +1,38 @@
1
+ module Gorynich
2
+ module Fetchers
3
+ class ConsulSecure
4
+ attr_reader :storage, :file_path, :consul_opts
5
+
6
+ def initialize(storage:, file_path:, **opts)
7
+ @storage = storage
8
+ @file_path = file_path
9
+ @consul_opts = opts
10
+ end
11
+
12
+ def fetch
13
+ cfg = Consul.new(storage: storage, **consul_opts).fetch
14
+ return from_file if cfg.empty?
15
+
16
+ save_to_file(cfg)
17
+
18
+ cfg
19
+ rescue ::StandardError
20
+ from_file
21
+ end
22
+
23
+ private
24
+
25
+ def save_to_file(cfg)
26
+ envs = ::Dir.glob(::Rails.root.join('config/environments/*.rb').to_s).map { |f| ::File.basename(f, '.rb') }
27
+
28
+ ::File.open(file_path, 'w') do |f|
29
+ f << cfg.deep_transform_keys(&:downcase).select { |k, _v| envs.include?(k) }.to_yaml.gsub('---', '')
30
+ end
31
+ end
32
+
33
+ def from_file
34
+ File.new(file_path: file_path).fetch
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,3 +1,3 @@
1
1
  module Gorynich
2
- VERSION = '1.1.1'
2
+ VERSION = '1.2.0'
3
3
  end
@@ -0,0 +1,45 @@
1
+ RSpec.describe Gorynich::Fetchers::ConsulSecure do
2
+ let(:storage) { Faker::Lorem.word }
3
+ let(:file_path) { "#{RSPEC_ROOT}/fixtures/fetchers/file_config.yml" }
4
+ let(:file_like_object) { double("file like object") }
5
+
6
+ context '#fetch' do
7
+ let(:consul_host) { Faker::Internet.url }
8
+ let(:consul_opts) { { http_addr: consul_host } }
9
+
10
+ def consul_request(response, code = 200)
11
+ stub_request(:get, "#{consul_host}/v1/kv/#{storage}?recurse=true")
12
+ .to_return(
13
+ status: code,
14
+ body: response
15
+ )
16
+ end
17
+
18
+ subject { described_class.new(storage: storage, file_path: file_path, **consul_opts) }
19
+
20
+ describe 'when consul return data' do
21
+ let(:response) { [{ 'Key' => "#{storage}/test_key", 'Value' => Base64.encode64('test') }].to_json }
22
+
23
+ before(:each) do
24
+ consul_request(response)
25
+ end
26
+
27
+ it do
28
+ allow(File).to receive(:open).with(file_path, 'w').and_return(file_like_object)
29
+ expect(subject.fetch).to eq({ 'test_key' => 'test' })
30
+ end
31
+ end
32
+
33
+ describe 'when http error' do
34
+ before(:each) do
35
+ consul_request([], 500)
36
+ end
37
+
38
+ it do
39
+ result = subject.fetch
40
+ expect(result.class).to eq(Hash)
41
+ expect(result).to include('development', 'test')
42
+ end
43
+ end
44
+ end
45
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gorynich
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1.148381
4
+ version: 1.2.0.180668
5
5
  platform: ruby
6
6
  authors:
7
7
  - Poliev Alexey
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-06-05 00:00:00.000000000 Z
12
+ date: 2023-08-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: diplomat
@@ -286,6 +286,7 @@ files:
286
286
  - lib/gorynich/engine.rb
287
287
  - lib/gorynich/fetcher.rb
288
288
  - lib/gorynich/fetchers/consul.rb
289
+ - lib/gorynich/fetchers/consul_secure.rb
289
290
  - lib/gorynich/fetchers/file.rb
290
291
  - lib/gorynich/head.rb
291
292
  - lib/gorynich/head/action_cable.rb
@@ -358,6 +359,7 @@ files:
358
359
  - spec/fixtures/test_database.yml
359
360
  - spec/lib/gorynich/config_spec.rb
360
361
  - spec/lib/gorynich/fetcher_spec.rb
362
+ - spec/lib/gorynich/fetchers/consul_secure_spec.rb
361
363
  - spec/lib/gorynich/fetchers/consul_spec.rb
362
364
  - spec/lib/gorynich/fetchers/file_spec.rb
363
365
  - spec/lib/gorynich/version_spec.rb
@@ -450,6 +452,7 @@ test_files:
450
452
  - spec/fixtures/test_database.yml
451
453
  - spec/lib/gorynich/config_spec.rb
452
454
  - spec/lib/gorynich/fetcher_spec.rb
455
+ - spec/lib/gorynich/fetchers/consul_secure_spec.rb
453
456
  - spec/lib/gorynich/fetchers/consul_spec.rb
454
457
  - spec/lib/gorynich/fetchers/file_spec.rb
455
458
  - spec/lib/gorynich/version_spec.rb