Skip to content

Commit

Permalink
Disallow non-unique instance names for platforms (ansible#1775)
Browse files Browse the repository at this point in the history
If we do not put this validation in place then Molecule does key merging
on the Python layer and the end-user can end with less instances than
they might hope for without knowing why.

References:

  pyeve/cerberus#467

Signed-off-by: Luke Murphy <[email protected]>
  • Loading branch information
decentral1se authored Mar 4, 2019
1 parent cb53404 commit 97b3ae9
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
20 changes: 18 additions & 2 deletions molecule/model/schema_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.

import collections
import copy
import functools
import re

import cerberus
import cerberus.errors

from molecule import interpolation
from molecule import util
from molecule import interpolation, util


def coerce_env(env, keep_string, v):
Expand Down Expand Up @@ -269,6 +269,8 @@ def pre_validate_base_schema(env, keep_string):
'name': {
'type': 'string',
'required': True,
'unique': # https://github.com/pyeve/cerberus/issues/467
True,
},
'groups': {
'type': 'list',
Expand Down Expand Up @@ -944,6 +946,20 @@ class Validator(cerberus.Validator):
def __init__(self, *args, **kwargs):
super(Validator, self).__init__(*args, **kwargs)

def _validate_unique(self, unique, field, value):
"""Ensure value uniqueness.
The rule's arguments are validated against this schema:
{'type': 'boolean'}
"""
if unique:
root_key = self.schema_path[0]
data = (doc[field] for doc in self.root_document[root_key])
for key, count in collections.Counter(data).items():
if count > 1:
msg = "'{}' is not unique".format(key)
self._error(field, msg)

def _validate_disallowed(self, disallowed, field, value):
""" Readonly but with a custom error.
Expand Down
22 changes: 22 additions & 0 deletions test/unit/model/v2/test_platforms_section.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,28 @@ def test_platforms_docker(_config):
assert {} == schema_v2.validate(_config)


@pytest.mark.parametrize(
'_config', ['_model_platforms_docker_section_data'], indirect=True)
def test_platforms_unique_names(_config):
instance_name = _config['platforms'][0]['name']
_config['platforms'] += [{
'name': instance_name # duplicate platform name
}]

expected_validation_errors = {
'platforms': [{
0: [{
'name': ["'{}' is not unique".format(instance_name)]
}],
1: [{
'name': ["'{}' is not unique".format(instance_name)]
}]
}]
}

assert expected_validation_errors == schema_v2.validate(_config)


@pytest.fixture
def _model_platforms_docker_errors_section_data():
return {
Expand Down

0 comments on commit 97b3ae9

Please sign in to comment.