Merge pull request #757 from ferrarimarco/lint-kubeval

Lint with Kubeval and fixes
This commit is contained in:
Lukas Gravley 2020-09-22 08:47:41 -05:00 committed by GitHub
commit 9eb6c0e147
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 182 additions and 27 deletions

View file

@ -0,0 +1,19 @@
# Kubeval Test Cases
This folder holds the test cases for **Kubeval**.
## Additional Docs
No Additional information is needed for this test case.
## Good Test Cases
The test cases denoted: `LANGUAGE_good_FILE.EXTENSION` are all valid, and should pass successfully when linted.
- **Note:** They are linted utilizing the default linter rules.
## Bad Test Cases
The test cases denoted: `LANGUAGE_bad_FILE.EXTENSION` are **NOT** valid, and should trigger errors when linted.
- **Note:** They are linted utilizing the default linter rules.

View file

@ -0,0 +1,20 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 4
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image2: nginx:1.13.12
ports:
- containerPort: 80

View file

@ -0,0 +1,20 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 4
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.13.12
ports:
- containerPort: 80

View file

@ -71,7 +71,7 @@ jobs:
run: docker run -e RUN_LOCAL=true -e TEST_CASE_RUN=true -e OUTPUT_FORMAT=tap -e OUTPUT_FOLDER=${GITHUB_SHA} -e OUTPUT_DETAILS=detailed -v ${GITHUB_WORKSPACE}:/tmp/lint github/super-linter:${GITHUB_SHA}
#########################################
# Clean code base to run agaisnt it all #
# Clean code base to run against it all #
#########################################
- name: Clean Test code base for additional testing
shell: bash

View file

@ -18,6 +18,7 @@ FROM accurics/terrascan:d182f1c as terrascan
FROM hadolint/hadolint:latest-alpine as dockerfile-lint
FROM ghcr.io/assignuser/lintr-lib:0.1.2 as lintr-lib
FROM ghcr.io/assignuser/chktex-alpine:0.1.1 as chktex
FROM garethr/kubeval:0.15.0 as kubeval
##################
# Get base image #
@ -305,6 +306,11 @@ RUN R -e "install.packages(list.dirs('/home/r-library',recursive = FALSE), repos
COPY --from=chktex /usr/bin/chktex /usr/bin/
RUN cd ~ && touch .chktexrc
###################
# Install kubeval #
###################
COPY --from=kubeval /kubeval /usr/bin/
#################
# Install shfmt #
#################
@ -331,6 +337,7 @@ ENV ACTIONS_RUNNER_DEBUG=${ACTIONS_RUNNER_DEBUG} \
GITHUB_TOKEN=${GITHUB_TOKEN} \
GITHUB_WORKSPACE=${GITHUB_WORKSPACE} \
JAVASCRIPT_ES_CONFIG_FILE=${JAVASCRIPT_ES_CONFIG_FILE} \
KUBERNETES_DIRECTORY=${KUBERNETES_DIRECTORY} \
LINTER_RULES_PATH=${LINTER_RULES_PATH} \
LOG_FILE=${LOG_FILE} \
LOG_LEVEL=${LOG_LEVEL} \
@ -362,6 +369,7 @@ ENV ACTIONS_RUNNER_DEBUG=${ACTIONS_RUNNER_DEBUG} \
VALIDATE_JAVASCRIPT_ES=${VALIDATE_JAVASCRIPT_ES} \
VALIDATE_JAVASCRIPT_STANDARD=${VALIDATE_JAVASCRIPT_STANDARD} \
VALIDATE_JSON=${VALIDATE_JSON} \
VALIDATE_KUBERNETES_KUBEVAL=${VALIDATE_KUBERNETES_KUBEVAL} \
VALIDATE_KOTLIN=${VALIDATE_KOTLIN} \
VALIDATE_LATEX=${VALIDATE_LATEX} \
VALIDATE_LUA=${VALIDATE_LUA} \

View file

@ -62,6 +62,7 @@ Developers on **GitHub** can call the **GitHub Action** to lint their code base
| **Java** | [checkstyle](https://checkstyle.org) |
| **JavaScript** | [eslint](https://eslint.org/) / [standard js](https://standardjs.com/) |
| **JSON** | [jsonlint](https://github.com/zaach/jsonlint) |
| **Kubeval** | [kubeval](https://github.com/instrumenta/kubeval) |
| **Kotlin** | [ktlint](https://github.com/pinterest/ktlint) |
| **LaTeX** | [ChkTex](https://www.nongnu.org/chktex/) |
| **Lua** | [luacheck](https://github.com/luarocks/luacheck) |
@ -198,7 +199,7 @@ But if you wish to select or exclude specific linters, we give you full control
| **ENV VAR** | **Default Value** | **Notes** |
| --------------------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **ACTIONS_RUNNER_DEBUG** | `false` | Flag to enable additional information about the linter, versions, and additional output. |
| **ANSIBLE_DIRECTORY** | `/ansible` | Flag to set the root directory for Ansible file location(s). |
| **ANSIBLE_DIRECTORY** | `/ansible` | Flag to set the root directory for Ansible file location(s), relative to `DEFAULT_WORKSPACE`. |
| **CSS_FILE_NAME** | `.stylelintrc.json` | Filename for [Stylelint configuration](https://github.com/stylelint/stylelint) (ex: `.stylelintrc.yml`, `.stylelintrc.yaml`) |
| **DEFAULT_BRANCH** | `master` | The name of the repository default branch. |
| **DEFAULT_WORKSPACE** | `/tmp/lint` | The location containing files to lint if you are running locally. |
@ -208,6 +209,7 @@ But if you wish to select or exclude specific linters, we give you full control
| **FILTER_REGEX_EXCLUDE** | `none` | Regular expression defining which files will be excluded from linting (ex: `.*src/test.*`) |
| **FILTER_REGEX_INCLUDE** | `all` | Regular expression defining which files will be processed by linters (ex: `.*src/.*`) |
| **JAVASCRIPT_ES_CONFIG_FILE** | `.eslintrc.yml` | Filename for [eslint configuration](https://eslint.org/docs/user-guide/configuring#configuration-file-formats) (ex: `.eslintrc.yml`, `.eslintrc.json`) |
| **KUBERNETES_DIRECTORY** | `/kubernetes` | The path to the root directory for Kubernetes descriptors, relative to `DEFAULT_WORKSPACE`. |
| **LINTER_RULES_PATH** | `.github/linters` | Directory for all linter configuration rules. |
| **LOG_FILE** | `super-linter.log` | The file name for outputting logs. All output is sent to the log file regardless of `LOG_LEVEL`. |
| **LOG_LEVEL** | `VERBOSE` | How much output the script will generate to the console. One of `VERBOSE`, `DEBUG` or `TRACE`. |
@ -246,6 +248,7 @@ But if you wish to select or exclude specific linters, we give you full control
| **VALIDATE_JSON** | `true` | Flag to enable or disable the linting process of the JSON language. |
| **VALIDATE_JSX** | `true` | Flag to enable or disable the linting process for jsx files (Utilizing: eslint) |
| **VALIDATE_KOTLIN** | `true` | Flag to enable or disable the linting process of the Kotlin language. |
| **VALIDATE_KUBERNETES_KUBEVAL** | `true` | Flag to enable or disable the linting process of Kubernetes descriptors with Kubeval |
| **VALIDATE_LATEX** | `true` | Flag to enable or disable the linting process of the LaTeX language. |
| **VALIDATE_LUA** | `true` | Flag to enable or disable the linting process of the language. |
| **VALIDATE_MD** | `true` | Flag to enable or disable the linting process of the Markdown language. |

View file

@ -33,6 +33,7 @@ For some linters it is also possible to override rules on a case by case level w
- [JavaScript eslint](#javascript-eslint)
- [JavaScript standard](#javascript-standard)
- [JSON](#json)
- [Kubeval](#kubeval)
- [Kotlin](#kotlin)
- [LaTeX](#latex)
- [Lua](#lua)
@ -605,6 +606,16 @@ import package.b.*
---
## Kubernetes
- [kubeval](https://github.com/instrumenta/kubeval)
### Kubeval
- There is no top level _configuration file_ available at this time
---
## LaTeX
- [ChkTex](https://www.nongnu.org/chktex/)

View file

@ -591,6 +591,16 @@ function BuildFileList() {
READ_ONLY_CHANGE_FLAG=1
fi
############################################
# Check if the file is Kubernetes template #
############################################
if DetectKubernetesFile "${FILE}"; then
################################
# Append the file to the array #
################################
FILE_ARRAY_KUBERNETES+=("${FILE}")
fi
########################################################################
# We have something that we need to try to check file type another way #
########################################################################

View file

@ -142,7 +142,7 @@ YAML_LINTER_RULES="${DEFAULT_RULES_LOCATION}/${YAML_FILE_NAME}" # Path to the ya
#############################
LANGUAGE_ARRAY=('ANSIBLE' 'ARM' 'BASH' 'BASH_EXEC' 'CLOUDFORMATION' 'CLOJURE' 'COFFEESCRIPT' 'CSHARP' 'CSS'
'DART' 'DOCKERFILE' 'DOCKERFILE_HADOLINT' 'EDITORCONFIG' 'ENV' 'GO' 'GROOVY' 'HTML'
'JAVA' 'JAVASCRIPT_ES' 'JAVASCRIPT_STANDARD' 'JSON' 'JSX' 'KOTLIN' 'LATEX' 'LUA' 'MARKDOWN'
'JAVA' 'JAVASCRIPT_ES' 'JAVASCRIPT_STANDARD' 'JSON' 'JSX' 'KUBERNETES_KUBEVAL' 'KOTLIN' 'LATEX' 'LUA' 'MARKDOWN'
'OPENAPI' 'PERL' 'PHP_BUILTIN' 'PHP_PHPCS' 'PHP_PHPSTAN' 'PHP_PSALM' 'POWERSHELL'
'PROTOBUF' 'PYTHON_BLACK' 'PYTHON_PYLINT' 'PYTHON_FLAKE8' 'R' 'RAKU' 'RUBY' 'SHELL_SHFMT' 'STATES' 'SQL' 'TERRAFORM'
'TERRAFORM_TERRASCAN' 'TSX' 'TYPESCRIPT_ES' 'TYPESCRIPT_STANDARD' 'XML' 'YAML')
@ -166,6 +166,7 @@ GITHUB_RUN_ID="${GITHUB_RUN_ID}" # GitHub RU
GITHUB_SHA="${GITHUB_SHA}" # GitHub sha from the commit
GITHUB_TOKEN="${GITHUB_TOKEN}" # GitHub Token passed from environment
GITHUB_WORKSPACE="${GITHUB_WORKSPACE}" # Github Workspace
KUBERNETES_DIRECTORY="${KUBERNETES_DIRECTORY}" # Kubernetes directory
LOG_FILE="${LOG_FILE:-super-linter.log}" # Default log file name (located in GITHUB_WORKSPACE folder)
LOG_LEVEL="${LOG_LEVEL:-VERBOSE}" # Default log level (VERBOSE, DEBUG, TRACE)
MULTI_STATUS="${MULTI_STATUS:-true}" # Multiple status are created for each check ran
@ -193,6 +194,7 @@ VALIDATE_JAVASCRIPT_ES="${VALIDATE_JAVASCRIPT_ES}" # Boolean t
VALIDATE_JAVASCRIPT_STANDARD="${VALIDATE_JAVASCRIPT_STANDARD}" # Boolean to validate language
VALIDATE_JSON="${VALIDATE_JSON}" # Boolean to validate language
VALIDATE_JSX="${VALIDATE_JSX}" # Boolean to validate language
VALIDATE_KUBERNETES_KUBEVAL="${VALIDATE_KUBERNETES_KUBEVAL}" # Boolean to validate language
VALIDATE_KOTLIN="${VALIDATE_KOTLIN}" # Boolean to validate language
VALIDATE_LATEX="${VALIDATE_LATEX}" # Boolean to validate language
VALIDATE_LUA="${VALIDATE_LUA}" # Boolean to validate language
@ -265,8 +267,6 @@ READ_ONLY_CHANGE_FLAG=0 # Flag set to 1 if files
export READ_ONLY_CHANGE_FLAG # Workaround SC2034
TEST_CASE_FOLDER='.automation/test' # Folder for test cases we should always ignore
export TEST_CASE_FOLDER # Workaround SC2034
DEFAULT_ANSIBLE_DIRECTORY="${GITHUB_WORKSPACE}/ansible" # Default Ansible Directory
export DEFAULT_ANSIBLE_DIRECTORY # Workaround SC2034
WARNING_ARRAY_TEST=() # Array of warning linters that did not have an expected test result.
export WARNING_ARRAY_TEST # Workaround SC2034
@ -276,7 +276,6 @@ export WARNING_ARRAY_TEST # Workaround SC2034
OUTPUT_FORMAT="${OUTPUT_FORMAT}" # Output format to be generated. Default none
OUTPUT_FOLDER="${OUTPUT_FOLDER:-super-linter.report}" # Folder where the reports are generated. Default super-linter.report
OUTPUT_DETAILS="${OUTPUT_DETAILS:-simpler}" # What level of details. (simpler or detailed). Default simpler
REPORT_OUTPUT_FOLDER="${GITHUB_WORKSPACE}/${OUTPUT_FOLDER}" # Location for the report folder
##########################
# Array of changed files #
@ -299,6 +298,7 @@ FILE_ARRAY_JAVASCRIPT_ES=() # Array of files to check
FILE_ARRAY_JAVASCRIPT_STANDARD=() # Array of files to check
FILE_ARRAY_JSON=() # Array of files to check
FILE_ARRAY_JSX=() # Array of files to check
FILE_ARRAY_KUBERNETES=()
FILE_ARRAY_KOTLIN=() # Array of files to check
FILE_ARRAY_LATEX=() # Array of files to check
FILE_ARRAY_LUA=() # Array of files to check
@ -373,6 +373,8 @@ ERRORS_FOUND_JSON=0 # Count of errors found
export ERRORS_FOUND_JSON # Workaround SC2034
ERRORS_FOUND_JSX=0 # Count of errors found
export ERRORS_FOUND_JSX # Workaround SC2034
ERRORS_FOUND_KUBERNETES_KUBEVAL=0 # Count of errors found
export ERRORS_FOUND_KUBERNETES_KUBEVAL
ERRORS_FOUND_KOTLIN=0 # Count of errors found
export ERRORS_FOUND_KOTLIN # Workaround SC2034
ERRORS_FOUND_LATEX=0 # Count of errors found
@ -740,6 +742,24 @@ DetectCloudFormationFile() {
return 1
}
################################################################################
#### Function DetectKubernetesFile #########################################
DetectKubernetesFile() {
################
# Pull in Vars #
################
FILE="${1}" # File that we need to validate
debug "Checking if ${FILE} is a Kubernetes descriptor..."
if grep -q -E '(apiVersion):' "${FILE}" >/dev/null; then
debug "${FILE} is a Kubernetes descriptor"
return 0
fi
debug "${FILE} is NOT a Kubernetes descriptor"
return 1
}
################################################################################
#### Function DetectAWSStatesFIle ##############################################
DetectAWSStatesFIle() {
################
@ -1222,6 +1242,15 @@ fi
# needed to connect back and update checks
GetGitHubVars
########################################################
# Initialize variables that depend on GitHub variables #
########################################################
DEFAULT_ANSIBLE_DIRECTORY="${GITHUB_WORKSPACE}/ansible" # Default Ansible Directory
export DEFAULT_ANSIBLE_DIRECTORY # Workaround SC2034
DEFAULT_KUBERNETES_DIRECTORY="${GITHUB_WORKSPACE}/kubernetes" # Default Kubernetes Directory
export DEFAULT_KUBERNETES_DIRECTORY # Workaround SC2034
REPORT_OUTPUT_FOLDER="${GITHUB_WORKSPACE}/${OUTPUT_FOLDER}" # Location for the report folder
#########################################
# Get the languages we need to validate #
#########################################
@ -1632,6 +1661,37 @@ if [ "${VALIDATE_KOTLIN}" == "true" ]; then
LintCodebase "KOTLIN" "ktlint" "ktlint" ".*\.\(kt\|kts\)\$" "${FILTER_REGEX_INCLUDE}" "${FILTER_REGEX_EXCLUDE}" "${FILE_ARRAY_KOTLIN[@]}"
fi
##############################
# KUBERNETES Kubeval LINTING #
##############################
if [ "${VALIDATE_KUBERNETES_KUBEVAL}" == "true" ]; then
if [ -d "${KUBERNETES_DIRECTORY}" ]; then
if [ "${VALIDATE_ALL_CODEBASE}" == "true" ]; then
###############################################################################
# Set the file seperator to newline to allow for grabbing objects with spaces #
###############################################################################
IFS=$'\n'
mapfile -t LIST_FILES < <(find "${KUBERNETES_DIRECTORY}" -path "*/node_modules" -prune -o -type f -regex ".*\.\(yml\|yaml\|json\)\$" 2>&1)
for FILE in "${LIST_FILES[@]}"; do
if DetectKubernetesFile "${FILE}"; then
FILE_ARRAY_KUBERNETES+=("${FILE}")
fi
done
###########################
# Set IFS back to default #
###########################
IFS="${DEFAULT_IFS}"
fi
LintCodebase "KUBERNETES_KUBEVAL" "kubeval" "kubeval --strict" ".*\.\(yml\|yaml\|json\)\$" "${FILTER_REGEX_INCLUDE}" "${FILTER_REGEX_EXCLUDE}" "${FILE_ARRAY_KUBERNETES[@]}"
else
warn "No Kubernetes directory found at:[${KUBERNETES_DIRECTORY}]"
debug "skipping Kubeval lint"
fi
fi
#################
# LATEX LINTING #
#################

View file

@ -23,7 +23,7 @@ ARM_TTK_PSD1='/usr/bin/arm-ttk' # Powershell var
#######################################
LINTER_ARRAY=('ansible-lint' 'arm-ttk' 'asl-validator' 'bash-exec' 'black' 'cfn-lint' 'checkstyle' 'chktex' 'clj-kondo' 'coffeelint'
'dotnet-format' 'dart' 'dockerfilelint' 'dotenv-linter' 'editorconfig-checker' 'eslint' 'flake8' 'golangci-lint'
'hadolint' 'htmlhint' 'jsonlint' 'ktlint' 'lintr' 'lua' 'markdownlint' 'npm-groovy-lint' 'perl' 'protolint'
'hadolint' 'htmlhint' 'jsonlint' 'kubeval' 'ktlint' 'lintr' 'lua' 'markdownlint' 'npm-groovy-lint' 'perl' 'protolint'
'pwsh' 'pylint' 'raku' 'rubocop' 'shellcheck' 'shfmt' 'spectral' 'standard' 'stylelint' 'sql-lint'
'terrascan' 'tflint' 'xmllint' 'yamllint')

View file

@ -123,6 +123,7 @@ function GetValidationInfo() {
if [ -z "${ANSIBLE_DIRECTORY}" ]; then
# No Value, need to default
ANSIBLE_DIRECTORY="${DEFAULT_ANSIBLE_DIRECTORY}"
debug "Setting Ansible directory to the default: ${DEFAULT_ANSIBLE_DIRECTORY}"
else
# Check if first char is '/'
if [[ ${ANSIBLE_DIRECTORY:0:1} == "/" ]]; then
@ -133,6 +134,27 @@ function GetValidationInfo() {
TEMP_ANSIBLE_DIRECTORY="${GITHUB_WORKSPACE}/${ANSIBLE_DIRECTORY}"
# Set the value
ANSIBLE_DIRECTORY="${TEMP_ANSIBLE_DIRECTORY}"
debug "Setting Ansible directory to: ${ANSIBLE_DIRECTORY}"
fi
#################################
# Validate Kubernetes Directory #
#################################
if [ -z "${KUBERNETES_DIRECTORY}" ]; then
# No Value, need to default
KUBERNETES_DIRECTORY="${DEFAULT_KUBERNETES_DIRECTORY}"
debug "Setting Kubernetes directory to the default: ${DEFAULT_KUBERNETES_DIRECTORY}"
else
# Check if first char is '/'
if [[ ${KUBERNETES_DIRECTORY:0:1} == "/" ]]; then
# Remove first char
KUBERNETES_DIRECTORY="${KUBERNETES_DIRECTORY:1}"
fi
# Need to give it full path
TEMP_KUBERNETES_DIRECTORY="${GITHUB_WORKSPACE}/${KUBERNETES_DIRECTORY}"
# Set the value
KUBERNETES_DIRECTORY="${TEMP_KUBERNETES_DIRECTORY}"
debug "Setting Kubernetes directory to: ${KUBERNETES_DIRECTORY}"
fi
###############################

View file

@ -706,6 +706,7 @@ function RunTestCases() {
TestCodebase "JAVASCRIPT_ES" "eslint" "eslint --no-eslintrc -c ${JAVASCRIPT_LINTER_RULES}" ".*\.\(js\)\$" "javascript"
TestCodebase "JAVASCRIPT_STANDARD" "standard" "standard ${JAVASCRIPT_STANDARD_LINTER_RULES}" ".*\.\(js\)\$" "javascript"
TestCodebase "JSON" "jsonlint" "jsonlint" ".*\.\(json\)\$" "json"
TestCodebase "KUBERNETES_KUBEVAL" "kubeval" "kubeval --strict" ".*\.\(yml\|yaml\)\$" "kubeval"
TestCodebase "KOTLIN" "ktlint" "ktlint" ".*\.\(kt\|kts\)\$" "kotlin"
TestCodebase "LATEX" "chktex" "chktex -q -l ${LATEX_LINTER_RULES}" ".*\.\(tex\)\$" "latex"
TestCodebase "LUA" "lua" "luacheck" ".*\.\(lua\)\$" "lua"
@ -807,26 +808,7 @@ function LintAnsibleFiles() {
#################################
# Get list of all files to lint #
#################################
mapfile -t LIST_FILES < <(ls "${ANSIBLE_DIRECTORY}"/*.{yaml,yml} 2>&1)
###############################################################
# Set the list to empty if only MD and TXT files were changed #
###############################################################
# No need to run the full ansible checks on read only file changes
if [ "${READ_ONLY_CHANGE_FLAG}" -eq 0 ]; then
##########################
# Set the array to empty #
##########################
LIST_FILES=()
###################################
# Send message that were skipping #
###################################
debug "- Skipping Ansible lint run as file(s) that were modified were read only..."
############################
# Create flag to skip loop #
############################
SKIP_FLAG=1
fi
mapfile -t LIST_FILES < <(find "${ANSIBLE_DIRECTORY}" -path "*/node_modules" -prune -o -type f -regex ".*\.\(yml\|yaml\|json\)\$" 2>&1)
####################################
# Check if we have data to look at #