Add linter for passing pkgs as list
This patch adds a new linter that ensures packages are being passed as a list rather than using with_items. It also adds a test for the new linter and adds the test to the existing linter CI job script. Change-Id: Iffd7284fb1c7cc41df2a4e271821e51bb274c3a3
This commit is contained in:
parent
6e5b1d6a30
commit
580aa54b98
81
ansible-lint/PassListToPackageModules.py
Executable file
81
ansible-lint/PassListToPackageModules.py
Executable file
@ -0,0 +1,81 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# Copyright 2017, Rackspace US, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
"""Ansible linter for passing packages as list to package modules."""
|
||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from ansiblelint import AnsibleLintRule, RulesCollection, Runner
|
||||||
|
|
||||||
|
TEST_PLAYBOOK_DIR = "{}/test/".format(
|
||||||
|
os.path.dirname(os.path.realpath(__file__))
|
||||||
|
)
|
||||||
|
PACKAGE_MODULES = [
|
||||||
|
'apt',
|
||||||
|
'dnf',
|
||||||
|
'package',
|
||||||
|
'pip',
|
||||||
|
'yum',
|
||||||
|
'zypper'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def is_package_action(task):
|
||||||
|
"""Test if task is using a package module."""
|
||||||
|
return task['action']['__ansible_module__'] in PACKAGE_MODULES
|
||||||
|
|
||||||
|
|
||||||
|
class PassListToPackageModules(AnsibleLintRule):
|
||||||
|
"""Ansible linter for passing packages as list to package modules."""
|
||||||
|
id = 'OSA0002'
|
||||||
|
shortdesc = 'Pass packages as a list to package modules'
|
||||||
|
description = (
|
||||||
|
"When passing multiple packages to a package module, pass the "
|
||||||
|
"packages as a list rather than using 'with_items'. This provides a "
|
||||||
|
"performance boost for deployments."
|
||||||
|
)
|
||||||
|
tags = ['performance']
|
||||||
|
|
||||||
|
def matchtask(self, file, task):
|
||||||
|
"""Search the task for our concerns."""
|
||||||
|
return is_package_action(task) and 'with_items' in task
|
||||||
|
|
||||||
|
|
||||||
|
class TestPassListToPackageModules(unittest.TestCase):
|
||||||
|
"""Test the PassListToPackageModules lint rule."""
|
||||||
|
collection = RulesCollection()
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
"""Set up the linter testing."""
|
||||||
|
self.collection.register(PassListToPackageModules())
|
||||||
|
|
||||||
|
def test_file_positive(self):
|
||||||
|
"""A valid playbook should pass the linter."""
|
||||||
|
playbook = '{}/package_module_pass_list.yml'.format(
|
||||||
|
TEST_PLAYBOOK_DIR
|
||||||
|
)
|
||||||
|
runner = Runner(self.collection, playbook, [], [], [])
|
||||||
|
self.assertEqual([], runner.run())
|
||||||
|
|
||||||
|
def test_file_negative(self):
|
||||||
|
"""An invalid playbook should fail the linter."""
|
||||||
|
playbook = '{}/package_module_with_items.yml'.format(
|
||||||
|
TEST_PLAYBOOK_DIR
|
||||||
|
)
|
||||||
|
runner = Runner(self.collection, playbook, [], [], [])
|
||||||
|
self.assertNotEqual([], runner.run())
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
27
ansible-lint/test/package_module_pass_list.yml
Normal file
27
ansible-lint/test/package_module_pass_list.yml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# Copyright 2017, Rackspace US, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
---
|
||||||
|
|
||||||
|
- hosts: all
|
||||||
|
vars:
|
||||||
|
packages_to_install:
|
||||||
|
- bash
|
||||||
|
- tmux
|
||||||
|
- vim
|
||||||
|
tasks:
|
||||||
|
|
||||||
|
- name: Install packages using a list
|
||||||
|
package:
|
||||||
|
name: "{{ packages_to_install }}"
|
||||||
|
state: present
|
28
ansible-lint/test/package_module_with_items.yml
Normal file
28
ansible-lint/test/package_module_with_items.yml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# Copyright 2017, Rackspace US, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
---
|
||||||
|
|
||||||
|
- hosts: all
|
||||||
|
vars:
|
||||||
|
packages_to_install:
|
||||||
|
- bash
|
||||||
|
- tmux
|
||||||
|
- vim
|
||||||
|
tasks:
|
||||||
|
|
||||||
|
- name: Install packages using with_items
|
||||||
|
package:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: present
|
||||||
|
with_items: "{{ packages_to_install }}"
|
@ -36,5 +36,8 @@ export COMMON_TESTS_PATH="${WORKING_DIR}/tests/common"
|
|||||||
# Ensure that the Ansible environment is properly prepared
|
# Ensure that the Ansible environment is properly prepared
|
||||||
source "${COMMON_TESTS_PATH}/test-ansible-env-prep.sh"
|
source "${COMMON_TESTS_PATH}/test-ansible-env-prep.sh"
|
||||||
|
|
||||||
|
# Run linter tests
|
||||||
|
python -m unittest discover -s ${WORKING_DIR}/ansible-lint/ -p "*.py"
|
||||||
|
|
||||||
# Execute ansible-lint
|
# Execute ansible-lint
|
||||||
ansible-lint ${WORKING_DIR} -R -r ${WORKING_DIR}/ansible-lint/
|
ansible-lint ${WORKING_DIR} -R -r ${WORKING_DIR}/ansible-lint/
|
||||||
|
Loading…
Reference in New Issue
Block a user