Ansible 计算两个变量之间的天数(一个是集合变量,另一个是事实变量)

Ansible 计算两个变量之间的天数(一个是集合变量,另一个是事实变量),ansible,yaml,jinja2,Ansible,Yaml,Jinja2,我一直在疯狂地四处寻找解决方案,但到目前为止我一直没有成功:计算库存变量和可解释事实之间的天数 当我手动设置这两个变量时,我没有问题,这两个变量都被识别为一个日期,我可以从那里像这样工作:(这是预期的输出) 在两个手动设置的变量之间工作的任务: --- -主机:本地主机 变量: 上一次日期:2020-12-01 当前日期:2020-12-31 任务: -名称:上一个日期调试 调试: 味精: -“上一个日期:{{上一个日期}” -“prev_日期类型:{{prev_日期|类型_调试}” -名称:c

我一直在疯狂地四处寻找解决方案,但到目前为止我一直没有成功:计算库存变量和可解释事实之间的天数

当我手动设置这两个变量时,我没有问题,这两个变量都被识别为一个日期,我可以从那里像这样工作:(这是预期的输出)

在两个手动设置的变量之间工作的任务:

---
-主机:本地主机
变量:
上一次日期:2020-12-01
当前日期:2020-12-31
任务:
-名称:上一个日期调试
调试:
味精:
-“上一个日期:{{上一个日期}”
-“prev_日期类型:{{prev_日期|类型_调试}”
-名称:cur_date debug
调试:
味精:
-“当前日期:{{cur_date}”
-“cur_日期类型:{{cur_日期|类型_调试}”
#这是我想得到的输出,但我想从动态源(事实或shell通过寄存器)获得cur_date
-名称:计算上一个日期和当前日期之间的天数(预期结果)
调试:
msg:“天数={{(当前日期-上一个日期).days}”
工作产出:

TASK [prev_date debug] *************************************************************************************************************************************************
Thursday 31 December 2020  12:55:28 +0100 (0:00:00.227)       0:00:00.227 *****
ok: [localhost] => {
    "msg": [
        "prev_date: 2020-12-01",
        "prev_date type: date"
    ]
}

TASK [cur_date debug] **************************************************************************************************************************************************
Thursday 31 December 2020  12:55:29 +0100 (0:00:00.249)       0:00:00.476 *****
ok: [localhost] => {
    "msg": [
        "cur_date: 2020-12-31",
        "cur_date type: date"
    ]
}

TASK [Calculate number of days between prev_date and cur_date (intended result)] ***************************************************************************************
Thursday 31 December 2020  12:55:29 +0100 (0:00:00.144)       0:00:00.621 *****
ok: [localhost] => {
    "msg": "Number of days = 30"
}
现在,由于变量类型的原因,我想使用ansible事实动态获取每次运行的当前日期(
ansible\u date\u time.date

复制错误的任务示例

-name:ansible\u date\u time.date的值和类型
调试:
味精:
-“ansible_date_time.date:{{{ansible_date_time.date}}”
-“ansible_date_time.date类型:{{{ansible_date_time.date{124; type_debug}}”
#由于在ansible\u date\u time.date上条件不工作且属性不是日期,因此失败
-名称:计算ansible\u date\u time.date之间的天数
调试:
味精:
-“天数={{(ansible_date_time.date-prev_date).days}”
我得到以下输出和错误:

TASK [New source ansible fact date] ************************************************************************************************************************************
Thursday 31 December 2020  13:06:41 +0100 (0:00:00.143)       0:00:00.741 *****
ok: [localhost] => {
    "msg": [
        "ansible_date_time.date: 2020-12-31",
        "ansible_date_time.date type: AnsibleUnsafeText"
    ]
}

TASK [Calculate number of days between ansible_date_time.date] *********************************************************************************************************
Thursday 31 December 2020  13:06:41 +0100 (0:00:00.150)       0:00:00.892 *****
fatal: [localhost]: FAILED! => {"msg": "Unexpected templating type error occurred on (Number of days = {{ (ansible_date_time.date - prev_date).days }}): unsupported operand type(s) for -: 'AnsibleUnsafeText' and 'datetime.date'"}

我试图用
ansible\u date\u time.date
创建一个新变量,但如果可能的话,我无法将其转换为
datetime.date

下面的任务完成了这项工作

-调试:
msg:“天数=
{{((ansible_date_time.date | to_datetime(“%Y-%m-%d”)-
(上一个日期~'00:00:00')到|日期时间)).days}”

ansible\u date\u time。date
是一个字符串,因此必须将其转换为
日期
日期时间

令人惊讶的是,Ansible没有任何方法可以立即将字符串转换为
date
,但您可以使用将其转换为
datetime

然后,由于
prev_date
包含
date
而不是
datetime
,因此可以通过Python的
datetime
函数将刚刚创建的
datetime
转换为
date

所以剧本应该是:

-主机:所有
任务:
-调试:
msg:{((ansible_date_time.date | to_datetime(“%Y-%m-%d”)).date()-prev_date.days}
变量:
上一次日期:2020-12-01
这将提供:

播放[全部]*******************************************************************************************************
任务[收集事实]*******************************************************************************************
确定:[本地主机]
任务[调试]*****************************************************************************************************
确定:[本地主机]=>{
“msg”:“30”
}
重演*******************************************************************************************************
localhost:确定=2更改=0无法访问=0失败=0跳过=0获救=0忽略=0

看到这一点,我以类似的
prev|u date | string | to_datetime
结束。从我测试的
(prev_date~'00:00:00')到_datetime
正在进行一个隐式字符串转换,这一点得到了以下事实的支持:您的代码片段也可以进行
(prev_date~'')到_datetime
该死的,我尝试了这么多组合,花了这么多时间在这方面。是的,ansible是有限的,并且没有提供一种将str转换为date的方法,这是一段时间后才发现的。我也尝试过使用to_datetime,但我错过了语法中的“.date()”。这是我希望得到的最优雅的答案,谢谢你,伙计。@Geoffrey如果你发现“开箱即用”的ansible对于你的任何需求都是有限的,那么创建你自己的自定义过滤器(或任何其他类型的插件)就非常简单了在这里,您可以触手可及地获得python的所有功能。=>