23andMe / Yamale

A schema and validator for YAML.
MIT License
680 stars 89 forks source link

Custom Validator with Include and Schema Validation #78

Closed nascimento closed 3 years ago

nascimento commented 4 years ago

Please, could you review this implementation?

I have a data with some keys thats need be checked before schema content.

schema

test_includes: environment(include('test_include_complex'))

---
test_include:
  custom: card()
  string: str()
  number: num(required=False)

test_include_complex:
  dev: include('test_include', required=False)
  stg: include('test_include', required=False)
  prd: include('test_include', required=False)

data

test_includes:
  dev:
    string: custom data - date
    custom: 10C

The CustomValidator needs validate if dev is a valida environment and after check if schema is ok.

mildebrandt commented 4 years ago

Hi, thanks for your interest in Yamle. Instead of validating keys within a custom validator, you can use the --strict option to deny elements that aren't defined in the schema. Using your example files, it would result in this:

$ yamale -s pr78.schema pr78.fail --strict
Validating /Users/chrism/workspace/Yamale/pr78.fail...

Error!
Schema: pr78.schema
Data file: /Users/chrism/workspace/Yamale/pr78.fail
Traceback (most recent call last):
  File "/Users/chrism/workspace/Yamale/yamale/command_line.py", line 29, in _validate
    yamale.validate(schema, data, strict)
  File "/Users/chrism/workspace/Yamale/yamale/yamale.py", line 40, in validate
    schema.validate(d, path, strict)
  File "/Users/chrism/workspace/Yamale/yamale/schema/schema.py", line 65, in validate
    raise ValueError(error_str)
ValueError: 
Error validating data /Users/chrism/workspace/Yamale/pr78.fail with schema pr78.schema
        test_includes.my_custom_env: Unexpected element

Would that work for you?

nascimento commented 4 years ago

Hi @mildebrandt , I tried to use --strict, but on my case environments are dynamically inputed on yaml and in same cases we are using environment prefix like prd_blue to determine what is the right env for deployment.

For more details, I am using yaml to determine a list of environments to deploy our app, we have many targets to deploy (for same environment) so a dynamic check is necessary to determine if environment i exists in a lista of valid_envs to get the rights access...


  def _is_valid(self, value):
    # Lista de targets configurados
    target_envs = value.keys()

    # Se não tiver nenhum ambiente configurado, retorna erro.
    if len(target_envs) == 0:
      return False

    # Valida se ambientes são validos.
    for env in target_envs:
      env = env.split('_')[0]
      if env != 'all' and env not in ENVIRONMENTS:
        self.env = env
        return False
    return True
nascimento commented 4 years ago

@mildebrandt what do you think abou this MR?

mildebrandt commented 4 years ago

Since December, one of the contributors has added support to validate the keys of a map. That seems useful in your use case: https://github.com/23andMe/Yamale#map---mapvalidators-keyvalidator