# ebextensions-validator - [About](#about) - [Installation](#installation) - [Usage](#usage) - [Command line tool](#command-line-tool) - [Python package](#python-package) - [Validation rule](#validation-rule) - [allowlist format](#allowlist-format) - [.ebextensions-like YAML files with Regex](#ebextensions-like-yaml-files-with-regex) - [Non-.ebextensions YAML files with Regex](#non-ebextensions-yaml-files-with-regex) - [Examples](#examples) - [allowlist all](#allowlist-all) - [Empty file](#empty-file) - [Tips and Remarks](#tips-and-remarks) ## About ebextensions-validator is a tool which validates ebextensions configuration files against a provided allowlist. See https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/ebextensions.html for more information on the .ebextensions file format. Currently only YAML configuration files are supported. ## Installation ebextensions-validator can be installed using pip: ``` git clone <URL_TO_EBEXTENSIONS_VALIDATOR> ebextensions-validator pip install ./ebextenstions-validator ``` ## Usage ebextensions-validator is both a command line tool and a python library. Note that the command line tool is spelled `ebextensions-validator` with a hyphen, while the python package is `ebextensions_validator` with an underscore. ### Command line tool ``` usage: ebextensions-validator [-h] [-v] config_file allowlist_file Validate a config file from the .ebextensions directory against a allowlist of dictionaries positional arguments: config_file Config file from .ebextensions directory allowlist_file File which defines a allowlist of dictionaries. Regex can be used optional arguments: -h, --help show this help message and exit -v, --verbose Print information about not allowlisted configuration ``` ebextensions-validator parses the provided `config_file` and `allowlist_file`. It then validates the `config_file` against the `allowlist_file` Examples: * Validating a config file against a allowlist *successfully*: ``` ebextensions-validator path/to/.ebextensions/config_file.config path/to/allowlist.list Configuration is in allowlist ``` * Validating a config file against a allowlist *unsuccessfully*: ``` ebextensions-validator path/to/.ebextensions/config_file.config path/to/allowlist.list Configuration NOT in allowlist ``` * Validating a config file against a allowlist *unsuccessfully* with the *verbose* option: ``` ebextensions-validator path/to/.ebextensions/config_file.config path/to/allowlist.list -v * Dictionary ODict([('command1', ODict([('command', 'git commit -am "Comment"'), ('cwd', '/home/user/working/')]))]) is not in allowlist * Dictionary ODict([('command2', ODict([('command', 'ls'), ('cwd', '/home/user/working/')]))]) is not in allowlist Configuration NOT in allowlist ``` ### Python package To use ebextensions-validator from your own python projects, import the function `validate`: ``` from ebextensions_validator.validator import validate """ The function expects the path to a configuration file in yaml and the path to a allowlist file as described below. It returns True if the configuration is in the allowlist. It return False if the configuration is not in the allowlist. """ if validate("path/to/.ebextensions/config_file.config", "path/to/allowlist.list"): push_application_code() else: print("Configuration File not valid.") return ``` ## Validation rule Each dictionary in the validated configuration file must match a dictionary in the provided allowlist file. See the following section for some examples. ## allowlist format allowlists are defined as YAML files. Python-style regular expressions can be used in the allowlist files as well: Any key or value in the allowlist can be replaced by a regular expression. For more information on regular expressions in Python see https://docs.python.org/3/library/re.html **Note**: Regular expressions cannot be used in the * top level of the allowlist and * second level of the allowlist if the first level is `services`. See the "allowlist all" example below. ### .ebextensions-like YAML files with Regex .ebextensions configuration files (with regular expressions in the keys and values) can be used as allowlists. Let's see this example: ``` commands: .*: command: 'git commit .*' ``` This allowlist allows following configuration files: ``` commands: any_command_name: command: git commit -m "Any comment." ``` ``` commands: another_command_name: command: - git - commit - -m - This is another comment. ``` ``` commands: command_name_2: command: | git commit -m "This is a comment." git push ``` Since the linebreak and `git push` are all part of the `command` value, the `git commit .*` matches the whole block. Another example: ``` option_settings: - namespace: aws:elasticbeanstalk:container:tomcat:jvmoptions option_name: Xmx value: "[0-9]*m" - option_name: MYPARAMETER value: parametervalue ``` This allowlist allows following configuration files (see https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/ebextensions-optionsettings.html) ``` option_settings: - namespace: aws:elasticbeanstalk:container:tomcat:jvmoptions option_name: Xmx value: 256m ``` ``` option_settings: aws:elasticbeanstalk:container:tomcat:jvmoptions: Xmx: 256m aws:elasticbeanstalk:application:environment: MYPARAMETER: parametervalue ``` ### Non-.ebextensions YAML files with Regex Sometimes it is necessary to allow multiple different sets of configurations. Therefore, you can create a *list* *of dictionaries* in the allowlist. For example you want to allowlist multiple different command definitions: ``` commands: - .*: command: 'git commit -m .*$' cwd: /home/user/.* - .*: command: 'ls' cwd: /etc/.* ``` This allowlist allows following configuration files: ``` commands: git_in_working: command: 'git commit -m "This is a comment"' cwd: /home/user/working/ - ls_etc: command: 'ls' cwd: /etc/ ``` ``` commands: git_in_working: command: 'git commit -m "This is a comment"' cwd: /home/user/working/ ``` ``` commands: ls_etc: command: 'ls' cwd: /etc/ ``` The allowlist does ***not*** allow the following configuration file: ``` commands: git_in_working: command: 'git commit -m "This is a comment"' cwd: /home/user/working/ ls_etc: command: 'ls' cwd: /home/user/working/ ``` The dictionary `ls_etc` is not in any of the list of dictionaries in the allowlist under `commands` ## Examples See the files in `test_files/allowlist_files` for more examples. ### allowlist all This allowlist allows any valid .ebextensions configuration file ``` option_settings: .* packages: .* groups: .* users: .* sources: .* files: .* commands: .* services: sysvinit: .* container_commands: .* Resources: .* Outputs: .* ``` ### Empty file If you specify an empty file as allowlist, the validation will always return a non-valid configuration. ## Tips and Remarks * Be careful with wildcards! The following allowlist allows commands such as `git commit -m "Any comment." & execute_another_command` ``` commands: .*: command: 'git commit .*$' ``` This allowlist is better: ``` commands: .*: command: 'git commit ".*"$' ```