Class: HybridPlatformsConductor::HpcPlugins::SecretsReader::Keepass

Inherits:
SecretsReader show all
Includes:
Credentials, SafeMerge
Defined in:
lib/hybrid_platforms_conductor/hpc_plugins/secrets_reader/keepass.rb

Overview

Get secrets from a KeePass database

Defined Under Namespace

Modules: ConfigDSLExtension

Constant Summary

Constants included from LoggerHelpers

LoggerHelpers::LEVELS_MODIFIERS, LoggerHelpers::LEVELS_TO_STDERR

Instance Method Summary collapse

Methods included from Credentials

#with_credentials_for

Methods included from SafeMerge

#safe_merge

Methods inherited from SecretsReader

#initialize

Methods inherited from Plugin

extend_config_dsl_with, #initialize, valid?

Methods included from LoggerHelpers

#err, #init_loggers, #log_component=, #log_debug?, #log_level=, #out, #section, #set_loggers_format, #stderr_device, #stderr_device=, #stderr_displayed?, #stdout_device, #stdout_device=, #stdout_displayed?, #stdouts_to_s, #with_progress_bar

Constructor Details

This class inherits a constructor from HybridPlatformsConductor::SecretsReader

Instance Method Details

#secrets_for(node, service) ⇒ Object

Return secrets for a given service to be deployed on a node.

API
  • This method is mandatory

API
  • The following API components are accessible:

  • *@config* (Config): Main configuration API.

  • *@cmd_runner* (CmdRunner): Command Runner API.

  • *@nodes_handler* (NodesHandler): Nodes handler API.

Parameters
  • node (String): Node to be deployed

  • service (String): Service to be deployed

Result
  • Hash: The secrets



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/hybrid_platforms_conductor/hpc_plugins/secrets_reader/keepass.rb', line 78

def secrets_for(node, service)
  secrets = {}
  # As we are dealing with global secrets, cache the reading for performance between nodes and services.
  # Keep secrets cache grouped by URL/ID
  @secrets = {} unless defined?(@secrets)
  @nodes_handler.select_confs_for_node(node, @config.keepass_secrets).each do |keepass_secrets_info|
    secret_id = "#{keepass_secrets_info[:database]}:#{keepass_secrets_info[:group_path].join('/')}"
    unless @secrets.key?(secret_id)
      raise 'Missing KPScript configuration. Please use use_kpscript_from to set it.' if @config.kpscript.nil?

      with_credentials_for(:keepass, resource: keepass_secrets_info[:database]) do |_user, password|
        Tempfile.create('hpc_keepass') do |xml_file|
          key_file = ENV['hpc_key_file_for_keepass']
          password_enc = ENV['hpc_password_enc_for_keepass']
          keepass_credentials = {}
          keepass_credentials[:password] = password.to_unprotected if password
          keepass_credentials[:password_enc] = password_enc if password_enc
          keepass_credentials[:key_file] = key_file if key_file
          KeepassKpscript.
            use(@config.kpscript, debug: log_debug?).
            open(keepass_secrets_info[:database], **keepass_credentials).
            export('KeePass XML (2.x)', xml_file.path, group_path: keepass_secrets_info[:group_path].empty? ? nil : keepass_secrets_info[:group_path])
          @secrets[secret_id] = parse_xml_secrets(Nokogiri::XML(xml_file).at_xpath('KeePassFile/Root/Group'))
        end
      end
    end
    conflicting_path = safe_merge(secrets, @secrets[secret_id])
    raise "Secret set at path #{conflicting_path.join('->')} by #{keepass_secrets_info[:database]}#{keepass_secrets_info[:group_path].empty? ? '' : " from group #{keepass_secrets_info[:group_path].join('/')}"} for service #{service} on node #{node} has conflicting values (#{log_debug? ? "#{@secrets[secret_id].dig(*conflicting_path)} != #{secrets.dig(*conflicting_path)}" : 'set debug for value details'})." unless conflicting_path.nil?
  end
  secrets
end