Ansible:在数组中查找字符串并从数组中返回字符串

Ansible:在数组中查找字符串并从数组中返回字符串,ansible,Ansible,我正在编写一个剧本,它接受用户输入,以确定该文件是否存在于目录中 这就是我目前所拥有的 -名称:加密文件 主机:本地主机 连接:本地 变量: 工作目录:“{{playbook_dir}}” enc_文件:[] 我的文件:共享配置 任务: -名称:获取所有解密的.yaml文件 查找: 路径:“{{working_directory}}” 模式:'*.yaml' 递归:是的 排除:“*.enc.yaml,decrypt.yaml,encrypt_all.yaml,encrypt_file.yaml”

我正在编写一个剧本,它接受用户输入,以确定该文件是否存在于目录中

这就是我目前所拥有的

-名称:加密文件
主机:本地主机
连接:本地
变量:
工作目录:“{{playbook_dir}}”
enc_文件:[]
我的文件:共享配置
任务:
-名称:获取所有解密的.yaml文件
查找:
路径:“{{working_directory}}”
模式:'*.yaml'
递归:是的
排除:“*.enc.yaml,decrypt.yaml,encrypt_all.yaml,encrypt_file.yaml”
注册:文件
-名称:将解密文件添加到数组
设定事实:
enc_文件:“{enc_文件+[item.path | basename]}”
循环:“{files.files}}”
没有日志:正确
-调试:
msg:“{{enc_files}}”
当:“{enc_files | lower}}”中的“{my_file | lower}}”
我似乎无法开始工作的是,如果文件名而不是扩展名存在,它会查找。如果有,我想返回扩展名为的文件,以便处理它

这是我当前的树:

├── 自述文件
├── 数据库
│   └── postgres_config.enc.yaml
├── 解密.yaml
├── 加密所有.yaml
├── 加密_file.yaml
├── 红外线
│   ├── infra_config.enc.yaml
│   └── infra_config.yaml
├── 中间件
│   ├── 中间件\u config.enc.yaml
│   └── 中间件_config.yaml
├── 服务
│   ├── 日志\服务\配置.enc.yaml
│   ├── 日志\服务\配置.yaml
│
├── 共享
│   ├── 共享_config.enc.yaml
│   └── shared_config.yaml

我想做的是让用户输入
shared\u config
shared\u config.yaml
并返回
shared\u config.yaml
,这样我就可以加密该文件了。我还试图找出一种方法,他们可以在输入中传递
共享配置(以及任何其他可能的输入,但我可以稍后自己尝试解决)。

我想我不会这样做(例如,列出所有文件,然后查找用户输入是否与某个文件匹配)

我可能更愿意采用另一种方式:获取用户的输入,然后确定相应的文件确实存在

然后,您只需使用Jinja过滤器和Python字符串操作,即可按照预期的路径转换用户输入


下面是一个提议的剧本,有优点也有缺点

好处:

  • 它将处理由空格分隔的多个路径块
    some path
    将给出
    some/some\u path.yaml
  • 它应该足够健壮,可以更正错误的多个空格:
    some path
    将给出
    some/some\u path.yaml
  • 它还接受下划线
    some\u path
    将给出
    some/some\u path.yaml
  • 它应该足够健壮,可以更正错误的多下划线:
    some\uu路径
    将给出
    some/some\u路径。yaml
  • 以及下划线和空格的混合
    some path_here multispace\uuuuu multi下划线
    将给出
    some/some path_here\u multispace\u multi下划线。yaml
  • 它可以使用或不使用用户输入中指定的扩展名
  • 它应该对横向路径攻击具有一定的弹性
陷阱:

  • 但是它不能处理最后一个单词和扩展名之间的空格,因为它会带来太多的下划线:
    some path.yaml
    将给出
    some/some\u path.yaml

因此,这里是所说的剧本:

-主机:所有
收集事实:不
变量提示:
-名称:文件名
提示:您需要哪个解密文件?
二等兵:没有
学前任务:
-设定事实:
fqn:“{chunk.0~'/'~chunk|join('''u')如果chunk | length>1,则为其他chunk | join(''u')}”
变量:
块:{{((如果file.endswith('.yaml')则为file,否则为file ~'.yaml')|替换(''u'','').split()}
文件:{{file_name | trim}}
-断言:
即:
-fqn是一个文件
-不是fqn.startswith('.')#我只是想限制横向路径攻击
-不是fqn.startswith(“/”)#我只是想限制横向路径攻击
-“'enc'!=fqn.split('.')[-2]”此选项可防止访问加密文件
msg:“{{fqn}}不是一个文件”
任务:
-调试:
msg:“现在,对位于`{fqn}}`的文件`{fqn | basename}}`执行您最喜欢的操作,因为我确信它存在”
下面是两个运行它的示例:

  • 使用正确的用户输入:
    您需要哪个解密文件?:中间件配置
    播放[全部]*********************************************************************
    任务[设置事实]****************************************************************
    确定:[本地主机]
    任务[断言]******************************************************************
    确定:[localhost]=>changed=false
    msg:所有断言都通过了
    任务[调试]*******************************************************************
    确定:[本地主机]=>
    msg:现在,在“middleware/middleware\u config.yaml”中使用“middleware\u config.yaml”文件做你最喜欢的事情,因为我确信它存在
    重演*********************************************************************
    localhost:确定=3更改=0无法访问=0失败=0跳过=0获救=0忽略=0
    
  • 用户输入错误时:
    您需要哪个解密文件?:中间件配置
    播放[全部]*********************************************************************
    任务[设置事实]****************************************************************
    确定:[本地主机]
    任务[断言]******************************************************************
    致命:[localhost]:失败!=>已更改=f