我在stdout_lines中显示如下命令:
"stdout_lines": [
"Keystore type: jks",
"Keystore provider: SUN",
"",
"Your keystore contains 6 entries",
"",
"Alias name: alias1",
"Creation date: Oct 16, 2015",
"Entry type: PrivateKeyEntry",
"Certificate chain length: 1",
"Certificate[1]:",
"Owner: CN=*.example.com, O=Example, L=Some, ST=Where, C=DE",
"Issuer: CN=some issuer cert",
"Valid from: Wed Oct 14 02:00:00 CEST 2015 until: Thu Oct 18 14:00:00 CEST 2018",
"Signature algorithm name: SHA256withRSA",
"Subject Public Key Algorithm: 2048-bit RSA key",
"Version: 3",
"" ]
因此,从这样一个存储有多个证书的密钥库中,我想将信息提取到如下所示的字典列表中:
"keystore_values": [
{"Alias name": "alias1", "Owner": "CN=*.example.com",
"Valid until": "Thu Oct 18 14:00:00 CEST 2018" },
{"Alias name": "alias2", "Owner": "CN=*.example2.com",
"Valid until": "Thu Oct 18 14:00:00 CEST 2018" },
{"Alias name": "alias3", "Owner": "CN=*.example3.com",
"Valid until": "Thu Oct 18 14:00:00 CEST 2018" }]
现在,我想我应该使用regex_findall遍历“ stdout”,在其中定义所需的所有部分,然后也许可以将其压缩
答案 0 :(得分:1)
我对您的问题做了一些假设:
keytool -list -v
命令的输出,因为这就是它的样子。Ansible并不是真正用于复杂文本转换的好工具,这实际上就是您在这里所做的。我想提出两种不同的解决方案,都依靠某种外部工具来完成。
在此示例中,我们使用awk
从keytool
读取输出并生成JSON输出。
我已经将一些输出硬编码到该剧本中进行测试;显然,您可以在实践中将其替换为command
任务:
---
- hosts: localhost
gather_facts: false
vars:
storepass: secret
tasks:
- command: keytool -list -v -storepass {{ storepass }}
register: keytool
changed_when: false
- command:
args:
argv:
- "awk"
- "-F"
- ": "
- |
# this function prints out a single key as a JSON
# object
function print_key(key) {
if (not_first_key) print ","
not_first_key=1
print "{"
not_first_line=0
for (i in key) {
if (not_first_line) print ","
not_first_line=1
printf "\"%s\": \"%s\"\n", i, key[i]
}
print "}"
}
BEGIN {
split("", key)
print "["
}
# We recognize the start of a new key by the Alias name
# field. When we see it, we will (a) check if we have data
# for a prior key and print it out and then (b) reset the
# key array and start collecting new data.
/^Alias name/ {
if (length(key) > 0) {
print_key(key)
delete(key)
}
key["Alias name"] = $2
}
# The "Valid from" line requires special parsing.
/^Valid from/ {
key["Valid from"] = substr($2, 0, length($2)-6)
key["Valid until"] = $3
}
# Simple fields that we're interested in
/^(Owner|Issuer|Creation date)/ {
key[$1] = $2
}
END {
if (length(key) > 0) {
print_key(key)
}
print "]"
}
stdin: "{{ keytool.stdout }}"
register: keytool_json
changed_when: false
- set_fact:
key_list_1: "{{ keytool_json.stdout|from_json }}"
- debug:
var: key_list_1
运行上述剧本将产生:
TASK [debug] **********************************************************************************
ok: [localhost] => {
"key_list_1": [
{
"Alias name": "alias1",
"Creation date": "Apr 25, 2019",
"Issuer": "CN=Alice McHacker, OU=Unknown, O=Example Company, Inc., L=Boston, ST=MA, C=US",
"Owner": "CN=Alice McHacker, OU=Unknown, O=Example Company, Inc., L=Boston, ST=MA, C=US",
"Valid from": "Thu Apr 25 19:14:01 EDT 2019",
"Valid until": "Wed Jul 24 19:14:01 EDT 2019"
},
{
"Alias name": "alias2",
"Creation date": "Apr 25, 2019",
"Issuer": "CN=Mallory Root, OU=Unknown, O=Example Company, Inc., L=New York, ST=NY, C=US",
"Owner": "CN=Mallory Root, OU=Unknown, O=Example Company, Inc., L=New York, ST=NY, C=US",
"Valid from": "Thu Apr 25 19:17:03 EDT 2019",
"Valid until": "Wed Jul 24 19:17:03 EDT 2019"
}
]
}
...我认为它会生成所需的数据。
或者-可能更强大-您可以将逻辑移到自定义过滤器插件中。如果将以下内容放在filter_plugins/keys_to_list.py
中:
#!/usr/bin/python
def filter_keys_to_list(v):
key_list = []
key = {}
for line in v.splitlines():
# Just skip lines that don't look like a Key: Value line.
if ': ' not in line:
continue
# Same logic as the awk script: "Alias name" identifies the
# start of key data.
if line.startswith('Alias name'):
if key:
key_list.append(key)
key = {}
field, value = line.split(': ', 1)
if field in ['Alias name', 'Owner', 'Issuer', 'Creation date']:
key[field] = value
elif field == 'Valid from':
key['Valid from'], key['Valid until'] = value.split(' until: ')
if key:
key_list.append(key)
return key_list
class FilterModule(object):
filter_map = {
'keys_to_list': filter_keys_to_list,
}
def filters(self):
return self.filter_map
然后我们的剧本变得更加简单:
---
- hosts: localhost
gather_facts: false
vars:
storepass: secret
tasks:
- command: keytool -list -v -storepass {{ storepass }}
register: keytool
changed_when: false
- set_fact:
key_list_2: "{{ keytool.stdout|keys_to_list }}"
- debug:
var: key_list_2
这将产生相同的最终输出:
TASK [debug] **********************************************************************************
ok: [localhost] => {
"key_list_2": [
{
"Alias name": "alias1",
"Creation date": "Apr 25, 2019",
"Issuer": "CN=Lars Kellogg-Stedman, OU=Unknown, O=The Odd Bit, L=Boston, ST=MA, C=US",
"Owner": "CN=Lars Kellogg-Stedman, OU=Unknown, O=The Odd Bit, L=Boston, ST=MA, C=US",
"Valid from": "Thu Apr 25 19:14:01 EDT 2019",
"Valid until": "Wed Jul 24 19:14:01 EDT 2019"
},
{
"Alias name": "alias2",
"Creation date": "Apr 25, 2019",
"Issuer": "CN=Mallory Root, OU=Unknown, O=The Odd Bit, L=New York, ST=NY, C=US",
"Owner": "CN=Mallory Root, OU=Unknown, O=The Odd Bit, L=New York, ST=NY, C=US",
"Valid from": "Thu Apr 25 19:17:03 EDT 2019",
"Valid until": "Wed Jul 24 19:17:03 EDT 2019"
}
]
}