module Legion::Crypt::ClusterSecret

Public Instance Methods

cluster_secret()
Alias for: from_settings
cluster_secret_timeout() click to toggle source
# File lib/legion/crypt/cluster_secret.rb, line 97
def cluster_secret_timeout
  Legion::Settings[:crypt][:cluster_secret_timeout] || 5
end
cs() click to toggle source
# File lib/legion/crypt/cluster_secret.rb, line 109
def cs
  @cs ||= Digest::SHA256.digest(find_cluster_secret)
rescue StandardError => e
  Legion::Logging.error e.message
  Legion::Logging.error e.backtrace[0..10]
end
find_cluster_secret() click to toggle source
# File lib/legion/crypt/cluster_secret.rb, line 6
def find_cluster_secret
  %i[from_settings from_vault from_transport generate_secure_random].each do |method|
    result = send(method)
    next if result.nil?

    unless validate_hex(result)
      Legion::Logging.warn("Legion::Crypt.#{method} gave a value but it isn't a valid hex")
      next
    end

    set_cluster_secret(result, method != :from_vault)
    return result
  end
  return unless only_member?

  key = generate_secure_random
  set_cluster_secret(key)
  key
end
force_cluster_secret() click to toggle source
# File lib/legion/crypt/cluster_secret.rb, line 67
def force_cluster_secret
  Legion::Settings[:crypt][:force_cluster_secret] || true
end
from_settings() click to toggle source
# File lib/legion/crypt/cluster_secret.rb, line 37
def from_settings
  Legion::Settings[:crypt][:cluster_secret]
end
Also aliased as: cluster_secret
from_transport() click to toggle source
# File lib/legion/crypt/cluster_secret.rb, line 42
def from_transport # rubocop:disable Metrics/AbcSize
  return nil unless Legion::Settings[:transport][:connected]

  require 'legion/transport/messages/request_cluster_secret'
  Legion::Logging.info 'Requesting cluster secret via public key'
  Legion::Logging.warn 'cluster_secret already set but we are requesting a new value' unless from_settings.nil?
  start = Time.now
  Legion::Transport::Messages::RequestClusterSecret.new.publish
  sleep_time = 0.001
  until !Legion::Settings[:crypt][:cluster_secret].nil? || (Time.now - start) > cluster_secret_timeout
    sleep(sleep_time)
    sleep_time *= 2 unless sleep_time > 0.5
  end

  unless from_settings.nil?
    Legion::Logging.info "Received cluster secret in #{((Time.new - start) * 1000.0).round}ms"
    from_settings
  end

  Legion::Logging.error 'Cluster secret is still unknown!'
rescue StandardError => e
  Legion::Logging.error e.message
  Legion::Logging.error e.backtrace[0..10]
end
from_vault() click to toggle source
# File lib/legion/crypt/cluster_secret.rb, line 26
def from_vault
  return nil unless method_defined? :get
  return nil unless Legion::Settings[:crypt][:vault][:read_cluster_secret]
  return nil unless Legion::Settings[:crypt][:vault][:connected]
  return nil unless Legion::Crypt.exist?('crypt')

  get('crypt')[:cluster_secret]
rescue StandardError
  nil
end
generate_secure_random(length = secret_length) click to toggle source
# File lib/legion/crypt/cluster_secret.rb, line 105
def generate_secure_random(length = secret_length)
  SecureRandom.hex(length)
end
only_member?() click to toggle source
# File lib/legion/crypt/cluster_secret.rb, line 75
def only_member?
  Legion::Transport::Queue.new('node.crypt', passive: true).consumer_count.zero?
rescue StandardError
  nil
end
push_cs_to_vault() click to toggle source
# File lib/legion/crypt/cluster_secret.rb, line 90
def push_cs_to_vault
  return false unless Legion::Settings[:crypt][:vault][:connected] && Legion::Settings[:crypt][:cluster_secret]

  Legion::Logging.info 'Pushing Cluster Secret to Vault'
  Legion::Crypt.write('cluster', secret: Legion::Settings[:crypt][:cluster_secret])
end
secret_length() click to toggle source
# File lib/legion/crypt/cluster_secret.rb, line 101
def secret_length
  Legion::Settings[:crypt][:cluster_lenth] || 32
end
set_cluster_secret(value, push_to_vault = true) click to toggle source
# File lib/legion/crypt/cluster_secret.rb, line 81
def set_cluster_secret(value, push_to_vault = true) # rubocop:disable Style/OptionalBooleanParameter
  raise TypeError unless value.to_i(32).to_s(32) == value.downcase

  Legion::Settings[:crypt][:cs_encrypt_ready] = true
  push_cs_to_vault if push_to_vault && settings_push_vault

  Legion::Settings[:crypt][:cluster_secret] = value
end
settings_push_vault() click to toggle source
# File lib/legion/crypt/cluster_secret.rb, line 71
def settings_push_vault
  Legion::Settings[:crypt][:vault][:push_cs_to_vault] || true
end
validate_hex(value, length = secret_length) click to toggle source
# File lib/legion/crypt/cluster_secret.rb, line 116
def validate_hex(value, length = secret_length)
  value.to_i(length).to_s(length) == value.downcase
end