| The problem I have with using covert_to in lookup_options is that is completely falls down in a case like this:
class duo ( |
Struct[{ |
Optional['duo'] => Struct[{ |
Optional['host'] => Optional[String], |
Optional['ikey'] => Optional[Sensitive[String]], |
Optional['skey'] => Optional[Sensitive[String]], |
Optional['groups'] => Optional[Variant[String, Array[String]]], |
Optional['failmode'] => Optional[Enum['safe', 'secure']], |
Optional['pushinfo'] => Optional[Variant[Boolean, Enum['yes', 'no']]], |
Optional['http_proxy'] => Optional[String], |
Optional['autopush'] => Optional[Variant[Boolean, Enum['yes', 'no']]], |
Optional['prompts'] => Optional[Integer[1,default]], |
Optional['fallback_local_ip'] => Optional[Variant[Boolean, Enum['yes', 'no']]], |
Optional['send_gecos'] => Optional[Variant[Boolean, Enum['yes', 'no']]], |
}] |
}] $pam_duo_conf = {}, |
)
|
We want to use the duo::pam_duo_conf parameter in a template file, like so:
; |
; This is the /etc/duo/pam_duo.conf. |
; |
; This file is managed by the Puppet duo module. The contents of this file |
; come from the duo::pam_duo_conf parameter. |
; |
<% if @pam_duo_conf.length > 0 -%> |
<% @pam_duo_conf.sort.each do |section, settings| -%> |
|
[<%= section %>] |
|
<% settings.sort.each do |setting, value| -%> |
<% if value.is_a?(TrueClass) -%> |
<%= setting %> = yes |
<% elsif value.is_a?(FalseClass) -%> |
<%= setting %> = no |
<% elsif value.respond_to?('each') -%> |
<%= setting %> = <%= value.join(',') %> |
<% else -%> |
<%= setting %> = <%= value %> |
<% end -%> |
<% end -%> |
<% end -%> |
<% else -%> |
|
; The duo::pam_duo_conf parameter was empty. |
<% end -%>
|
But of course, this fails:
Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Evaluation Error: Error while evaluating a Method call, Class[Duo]: |
parameter 'pam_duo_conf' entry 'duo' entry 'ikey' expects a value of type Undef or Sensitive[String], got String |
parameter 'pam_duo_conf' entry 'duo' entry 'skey' expects a value of type Undef or Sensitive[String], got String (file: /etc/puppetlabs/code/environments/production/modules/classifier/manifests/init.pp, line: 254, column: 32) on node lx-hamachi.sei.cmu.edu
|
So yes, I fully support having Sensitive[String] match String and cast it to Sensitive[String]. Alternatively, I would also support permitting manual casting. E.g.:
Cast[String, Sensitive] $foo = ''
|
Meaning, this will match either String or Sensitive[String], but if it matches String, it will wrap that String type in Sensitive, so that $foo will always be of type Sensitive[String]. The advantage of a manual cast is that it permits module authors to distinguish between "I expect this value to already be of type Sensitive because it's being generated by a function that should return a Sensitive type" versus "this value may originate from a source (e.g., ACPL) that lacks the Sensitive type and therefore I want to manually cast it to Sensitive if it is not already so." |