oxsecurity / megalinter

🦙 MegaLinter analyzes 50 languages, 22 formats, 21 tooling formats, excessive copy-pastes, spelling mistakes and security issues in your repository sources with a GitHub Action, other CI tools or locally.
https://megalinter.io
GNU Affero General Public License v3.0
1.8k stars 215 forks source link

Set env var via PRE_COMMAND #3708

Open ncalteen opened 2 days ago

ncalteen commented 2 days ago

Heyo!

Is there a way to set a different environment variable used by MegaLinter during a PRE_COMMAND step? I have a use case where I'd like to run MegaLinter on repositories containing multiple Helm charts used by an ArgoCD application. The directory structure looks something like this:

.
├── charts
│   ├── app-1
│   │   ├── Chart.yaml
│   │   ├── templates
│   │   │   ├── deployment.yaml
│   │   │   └── service.yaml
│   │   └── values.yaml
│   ├── app-2
│   │   ├── Chart.yaml
│   │   ├── templates
│   │   │   ├── deployment.yaml
│   │   │   └── service.yaml
│   │   └── values.yaml
│   └── app-3
│       ├── Chart.yaml
│       ├── templates
│       │   ├── deployment.yaml
│       │   └── service.yaml
│       └── values.yaml
└── envs
    ├── dev
    │   ├── app-1.yaml
    │   ├── app-2.yaml
    │   ├── app-3.yaml
    │   └── values.yaml
    ├── qa
    │   ├── app-1.yaml
    │   ├── app-2.yaml
    │   ├── app-3.yaml
    │   └── values.yaml
    └── prod
        ├── app-1.yaml
        ├── app-2.yaml
        ├── app-3.yaml
        └── values.yaml

By default, it looks like the KUBERNETES_HELM linter isn't finding a Chart.yaml at the root of the repo, so it is being skipped.

[Activation] KUBERNETES_HELM has been set inactive, as none of these files has been found: ['Chart.yml', 'Chart.yaml']
[Activation] KUBERNETES_KUBESCAPE has been set inactive, as none of these files has been found: ['Chart.yml', 'Chart.yaml']

So to handle that, I've just been setting KUBERNETES_DIRECTORY to the path for the first app, charts/app-1. At that point, though, I run into two other issues:

Ideally, I'd like to be able to pass separate sets of values files for each chart, but for now I've been trying to do something like the following:

  1. Get the list of charts (charts/app-1, charts/app-2, and charts/app-3)
  2. Get the list of dev values files (envs/dev/app-1.yaml, envs/dev/app-2.yaml, envs/dev/app-3.yaml, envs/dev/values.yaml)
  3. Pass these as arguments via KUBERNETES_HELM_ARGUMENTS

I'd like to be able to scale this across a number of repositories, and generate the arguments at runtime (the lists of apps may change pretty often). I tried setting this up via KUBERNETES_HELM_PRE_COMMANDS, but it doesn't look like it allows me to override the KUBERNETES_HELM_ARGUMENTS value sent to the container.

KUBERNETES_HELM_PRE_COMMANDS:
  - command: |
      KUBERNETES_HELM_ARGUMENTS=""
      KUBERNETES_HELM_CHARTS=""
      for file in $(find /tmp/lint/charts -path "**/values.yaml" -type f); do
        KUBERNETES_HELM_CHARTS="$KUBERNETES_HELM_CHARTS $(dirname $file)"
        KUBERNETES_HELM_ARGUMENTS="$KUBERNETES_HELM_ARGUMENTS -f $file"
      done
      for file in $(find /tmp/lint/envs -path "**/dev/*.yaml" -type f); do
        KUBERNETES_HELM_ARGUMENTS="$KUBERNETES_HELM_ARGUMENTS -f $file"
      done
      export KUBERNETES_HELM_ARGUMENTS="$KUBERNETES_HELM_CHARTS $KUBERNETES_HELM_ARGUMENTS"
    secured: false

# Result: /tmp/lint/charts/app-1 /tmp/lint/charts/app-2 /tmp/lint/charts/app-3 -f /tmp/lint/envs/dev/app-1.yaml -f /tmp/lint/envs/dev/app-2.yaml -f /tmp/lint/envs/dev/app-3.yaml -f /tmp/lint/envs/dev/values.yaml

Is there another way I should go about this? I'm thinking just moving this to a separate script that is run before MegaLinter, but it'd be nice to be able to keep it all in .mega-linter.yml :)