Ansible-lint 自定义规则与正则匹配

1 投票
2 回答
34 浏览
提问于 2025-04-13 17:11

我想用 Ansible-lint 来检查我的 yaml 文件中的子网格式是否正确。

正确的格式: 10.10.10.0/32

错误的格式: 10.10.10.0 /32

我创建了一个自定义规则:

from ansiblelint import AnsibleLintRule
 import re

 class CheckCustomPattern(AnsibleLintRule):
     id = 'CUSTOM005'
     shortdesc = 'Check if pattern "\\s\/[1-3][0-9]" is found'
     description = 'This rule checks if the pattern "\\s\/[1-3][0-9]" is found in any file.'
     severity = 'HIGH'
     tags = ['files']

     def match(self, file, text):
         with open(file['path'], 'r') as file_content:
             content = file_content.read()
             if re.search(r'\s\/[1-3][0-9]', content):
                 return True
         return False

我已经在一个测试工具上检查过这个正则表达式,它是正确的。

但是当我运行它的时候,它却匹配了所有的 IP 地址,包括那些正确的地址。甚至还匹配了一些不是 IP 地址的内容,比如像 [ TCP UDP ICMP ] 这样的随机字符串。我在测试工具上检查过正则表达式的语法,确实是正确的。

我不太确定我漏掉了什么。

2 个回答

1

我最后是这样解决的。我用了一个内置的规则,然后根据我的需求进行了修改。

from ansiblelint import AnsibleLintRule
import re


class checkSubnetPattern(AnsibleLintRule):
    id = 'checkSubet'
    shortdesc = 'Check if the subnet has a space in it between the net and mask'
    description = 'This rule checks if if subnet has a space in it in any file.'
    severity = 'HIGH'
    tags = ['files']

    variable_syntax = re.compile(r"\s\/[1-3][0-9]")

    def match(self, file, line):
        if not self.variable_syntax.search(line):
            return
        return id
2

这其实是很正常的:你在加载整个文件并检查整个文件。你应该逐行处理这个文件里的内容。虽然我已经很多年没写过简单的Python代码了,但我可以给你一个非常简单的示例:

# playbook.yaml
---
- hosts: localhost
  connection: local
  gather_facts: false
  tasks:
    - debug:
        msg: '10.10.10.0/32'

    - debug:
        msg: '10.10.10.0 /32'

    - debug:
        msg: '10.10.10.0  /32'

    - debug:
        msg: '[ TCP UDP ICMP ]'
# match.py
import re

with open('playbook.yaml', 'r') as file_content:
    content = file_content.read()
    incorrect_subnet_spacing_regex = r'\s\/[1-3][0-9]'
    for index, line in enumerate(content.split('\n')):
        match = re.search(incorrect_subnet_spacing_regex, line)
        if match:
            print(f'Incorrect subnet at line {index}, position {match.start()}: {line}')

对于这个示例文件,上面的代码会产生以下结果:

Alexanders-Mini:78189854 alexander$ python3 match.py 
Incorrect subnet at line 9, position 24:         msg: '10.10.10.0 /32'
Incorrect subnet at line 12, position 25:         msg: '10.10.10.0  /32'

我会调整一下正则表达式,因为在斜杠后面可能会加一个空格,比如说。

撰写回答