Puppet Function: conjur::secret
- Defined in:
- lib/puppet/functions/conjur/secret.rb
- Function type:
- Ruby 4.x API
Overview
Function to retrieve a Conjur secret
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/puppet/functions/conjur/secret.rb', line 12 Puppet::Functions.create_function :'conjur::secret' do # @param variable_id Conjur variable ID that you want the value of. # @param options Optional parameter specifying server identity overrides # The following keys are supported in the options hash: # - appliance_url: The URL of the Conjur instance. # - account: Name of the Conjur account that contains this variable. # - authn_login: The identity you are using to authenticate to the Conjur instance. # - authn_api_key: The API key of the identity you are using to authenticate with (must be Sensitive type). # - cert_file: The absolute path to CA certificate chain for the Conjur instance on the agent. This variable overrides `ssl_certificate`. # - ssl_certificate: The _raw_ PEM-encoded x509 CA certificate chain for the Conjur instance. Overwritten by the contents read from `cert_file` when it is present. # - version: Conjur API version, defaults to 5. # @return [Sensitive] Value of the Conjur variable. # @example Agent-based identity invocation # Deferred(conjur::secret, ['production/postgres/password']) # @example Server-based identity invocation # $sslcert = @("EOT") # -----BEGIN CERTIFICATE----- # ... # -----END CERTIFICATE----- # |-EOT # # $dbpass = Deferred(conjur::secret, ['production/postgres/password', { # appliance_url => "https://my.conjur.org", # account => "myaccount", # authn_login => "host/myhost", # authn_api_key => Sensitive("2z9mndg1950gcx1mcrs6w18bwnp028dqkmc34vj8gh2p500ny1qk8n"), # ssl_certificate => $sslcert # }]) dispatch :with_credentials do required_param 'String', :variable_id optional_param 'Hash', :options return_type 'Sensitive' end def authentication_path(account, login) ['authn', account, login, 'authenticate'] .map(&URI.method(:encode_www_form_component)).join('/') end # Authenticates against a Conjur server returning the API token def authenticate(url, ssl_certificate, account, authn_login, authn_api_key) Conjur::PuppetModule::HTTP.post( url, authentication_path(account, authn_login), ssl_certificate, authn_api_key.unwrap, ) end # Fetches a variable from Conjur def get_variable(url, ssl_certificate, account, variable_id, token) secrets_path = [ 'secrets', URI.encode_www_form_component(account), 'variable', ERB::Util.url_encode(variable_id), ].join('/') Conjur::PuppetModule::HTTP.get( url, secrets_path, ssl_certificate, token, ) end def with_credentials(id, = {}) # If we got an options hash, it may be frozen so we make a copy that is not since # we will be modifying it opts = .dup if opts['authn_api_key'] raise "Value of 'authn_api_key' must be wrapped in 'Sensitive()'!" \ unless opts['authn_api_key'].is_a? Puppet::Pops::Types::PSensitiveType::Sensitive end opts['version'] ||= 5 # If we didn't get any config from the server, assume it's on the agent if opts['appliance_url'].nil? || opts['appliance_url'].empty? config = Conjur::PuppetModule::Config.load raise 'Conjur configuration not found on system' if config.empty? creds = Conjur::PuppetModule::Identity.load(config) raise 'Conjur identity not found on system' unless creds # Overwrite values in the options hash with the ones from the agent. We may at # some point want to support partial overwrite of only the set values. ['appliance_url', 'account', 'ssl_certificate', 'version'].each do |key| opts[key] = config[key] end opts['authn_login'], authn_api_key = creds opts['authn_api_key'] = Puppet::Pops::Types::PSensitiveType::Sensitive.new(authn_api_key) end # If cert_file is set, use it to override ssl_certificate if opts['cert_file'] raise "Cert file '#{opts['cert_file']}' cannot be found!" unless File.file?(opts['cert_file']) opts['ssl_certificate'] = File.read opts['cert_file'] end Puppet.debug('Instantiating Conjur client...') Puppet.debug('Fetching Conjur token') token = authenticate(opts['appliance_url'], opts['ssl_certificate'], opts['account'], opts['authn_login'], opts['authn_api_key']) Puppet.info('Conjur token retrieved') Puppet.debug("Fetching Conjur secret '#{id}'...") secret = get_variable(opts['appliance_url'], opts['ssl_certificate'], opts['account'], id, token) Puppet.info("Conjur secret #{id} retrieved") Puppet::Pops::Types::PSensitiveType::Sensitive.new(secret) end end |