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
|
||||
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
|
||||
ansible-lint ${WORKING_DIR} -R -r ${WORKING_DIR}/ansible-lint/
|
||||
|
Loading…
Reference in New Issue
Block a user