brainzlab 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 846a14213ec419ed826ce1868d3db7db1dd0394ba5b0207e1fd29269abb62e4e
4
- data.tar.gz: 4027020daca7bf736c1ed8e340729270ad7244eb9d1cc02cc4040eac05febbd4
3
+ metadata.gz: 32aa2fb43f88f30f3669b72c6ddc986ed19eee47992d5bbae1349938fd202e59
4
+ data.tar.gz: 22207e117166644641208f6031b534411adab7553732fd053e97d74650b98274
5
5
  SHA512:
6
- metadata.gz: 3439eb5e1f2c37972735cc44860ac16e7a5c7152895b5b61e525cb48130cff89acc5c33c140edf757e224348357a46afcb93c57bf0af7e56ae37161cb79b5066
7
- data.tar.gz: 67a99f59d1194fc76bd032010de1ddd19347ec8bff11be836f3958eb4c83201f3e6628a99a1b5d0658cb1620b4eb25be2c4892206760878d8b3c5d13973f7fab
6
+ metadata.gz: 78b6c3173b6f50859e9fd4c32a7b2805e120181809a97a56e4b403a897470dd2125ef4e85c2ecb81bfd1bf6c7714615f5586ec4e01bfd9540174d1a058c09a3d
7
+ data.tar.gz: 345f3d2c1486631b7d89b3f8cbd861459956f9963d712f533fc8fee094db53d603f8f3018f8cc813318203dee192240271704f2773d905c5056732e72347ceec
@@ -50,6 +50,7 @@ module BrainzLab
50
50
  :signal_enabled,
51
51
  :signal_url,
52
52
  :signal_api_key,
53
+ :signal_ingest_key,
53
54
  :signal_master_key,
54
55
  :signal_auto_provision,
55
56
  :vault_enabled,
@@ -228,6 +229,7 @@ module BrainzLab
228
229
  @signal_enabled = true
229
230
  @signal_url = ENV['SIGNAL_URL'] || detect_product_url('signal')
230
231
  @signal_api_key = ENV.fetch('SIGNAL_API_KEY', nil)
232
+ @signal_ingest_key = ENV.fetch('SIGNAL_INGEST_KEY', nil)
231
233
  @signal_master_key = ENV.fetch('SIGNAL_MASTER_KEY', nil)
232
234
  @signal_auto_provision = true
233
235
 
@@ -402,12 +404,12 @@ module BrainzLab
402
404
  end
403
405
 
404
406
  def signal_valid?
405
- key = signal_api_key || secret_key
407
+ key = signal_ingest_key || signal_api_key || secret_key
406
408
  !key.nil? && !key.empty?
407
409
  end
408
410
 
409
411
  def signal_auth_key
410
- signal_api_key || secret_key
412
+ signal_ingest_key || signal_api_key || secret_key
411
413
  end
412
414
 
413
415
  def vault_valid?
@@ -1,54 +1,114 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'net/http'
4
- require 'json'
5
4
  require 'uri'
5
+ require 'json'
6
+ require 'fileutils'
6
7
 
7
8
  module BrainzLab
8
9
  module Signal
9
10
  class Provisioner
11
+ CACHE_DIR = ENV.fetch('BRAINZLAB_CACHE_DIR') { File.join(Dir.home, '.brainzlab') }
12
+
10
13
  def initialize(config)
11
14
  @config = config
12
15
  end
13
16
 
14
17
  def ensure_project!
15
- return if @config.signal_api_key && !@config.signal_api_key.to_s.empty?
16
- return unless @config.signal_url && !@config.signal_url.to_s.empty?
17
- return unless @config.secret_key && !@config.secret_key.to_s.empty?
18
+ return unless should_provision?
19
+
20
+ # Try cached credentials first
21
+ if (cached = load_cached_credentials)
22
+ apply_credentials(cached)
23
+ return cached
24
+ end
18
25
 
19
- BrainzLab.debug_log('[Signal] Auto-provisioning project...')
20
- provision_project
26
+ # Provision new project
27
+ project = provision_project
28
+ return unless project
29
+
30
+ # Cache and apply credentials
31
+ cache_credentials(project)
32
+ apply_credentials(project)
33
+
34
+ project
21
35
  end
22
36
 
23
37
  private
24
38
 
39
+ def should_provision?
40
+ return false unless @config.signal_auto_provision
41
+ return false unless @config.app_name.to_s.strip.length.positive?
42
+ # Only skip if signal_api_key is already set
43
+ return false if @config.signal_api_key.to_s.strip.length.positive?
44
+ return false unless @config.signal_master_key.to_s.strip.length.positive?
45
+
46
+ true
47
+ end
48
+
25
49
  def provision_project
26
50
  uri = URI.parse("#{@config.signal_url}/api/v1/projects/provision")
51
+ request = Net::HTTP::Post.new(uri)
52
+ request['Content-Type'] = 'application/json'
53
+ request['X-Master-Key'] = @config.signal_master_key
54
+ request['User-Agent'] = "brainzlab-sdk-ruby/#{BrainzLab::VERSION}"
55
+ request.body = JSON.generate({ name: @config.app_name })
56
+
57
+ response = execute(uri, request)
58
+ return nil unless response.is_a?(Net::HTTPSuccess)
59
+
60
+ JSON.parse(response.body, symbolize_names: true)
61
+ rescue StandardError => e
62
+ log_error("Failed to provision Signal project: #{e.message}")
63
+ nil
64
+ end
65
+
66
+ def load_cached_credentials
67
+ path = cache_file_path
68
+ return nil unless File.exist?(path)
69
+
70
+ data = JSON.parse(File.read(path), symbolize_names: true)
71
+
72
+ # Validate cached data has required keys
73
+ return nil unless data[:api_key] || data[:ingest_key]
74
+
75
+ data
76
+ rescue StandardError => e
77
+ log_error("Failed to load cached Signal credentials: #{e.message}")
78
+ nil
79
+ end
80
+
81
+ def cache_credentials(project)
82
+ FileUtils.mkdir_p(CACHE_DIR)
83
+ File.write(cache_file_path, JSON.generate(project))
84
+ rescue StandardError => e
85
+ log_error("Failed to cache Signal credentials: #{e.message}")
86
+ end
87
+
88
+ def cache_file_path
89
+ File.join(CACHE_DIR, "#{@config.app_name}.signal.json")
90
+ end
91
+
92
+ def apply_credentials(project)
93
+ @config.signal_api_key = project[:api_key]
94
+ @config.signal_ingest_key = project[:ingest_key]
95
+
96
+ # Also set service name from app_name if not already set
97
+ @config.service ||= @config.app_name
98
+ end
99
+
100
+ def execute(uri, request)
27
101
  http = Net::HTTP.new(uri.host, uri.port)
28
102
  http.use_ssl = uri.scheme == 'https'
29
- http.open_timeout = 10
30
- http.read_timeout = 30
103
+ http.open_timeout = 5
104
+ http.read_timeout = 10
105
+ http.request(request)
106
+ end
31
107
 
32
- request = Net::HTTP::Post.new(uri.path)
33
- request['Content-Type'] = 'application/json'
34
- request['Authorization'] = "Bearer #{@config.secret_key}"
35
- request['User-Agent'] = "brainzlab-sdk/#{BrainzLab::VERSION}"
36
- request.body = {
37
- name: @config.service || 'default',
38
- environment: @config.environment
39
- }.to_json
40
-
41
- response = http.request(request)
42
-
43
- if response.is_a?(Net::HTTPSuccess)
44
- data = JSON.parse(response.body)
45
- @config.signal_api_key = data['api_key']
46
- BrainzLab.debug_log('[Signal] Project provisioned successfully')
47
- else
48
- BrainzLab.debug_log("[Signal] Provisioning failed: #{response.code} - #{response.body}")
49
- end
50
- rescue StandardError => e
51
- BrainzLab.debug_log("[Signal] Provisioning error: #{e.message}")
108
+ def log_error(message)
109
+ return unless @config.logger
110
+
111
+ @config.logger.error("[BrainzLab::Signal] #{message}")
52
112
  end
53
113
  end
54
114
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BrainzLab
4
- VERSION = '0.1.8'
4
+ VERSION = '0.1.9'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brainzlab
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brainz Lab