Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added binary based support for kustomize v2 and v3 #988

Merged
merged 11 commits into from
Aug 22, 2021
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ Terrascan is a static code analyzer for Infrastructure as Code. Terrascan allows

## Key features
* 500+ Policies for security best practices
* Scanning of Terraform (HCL2)
* Scanning of Kubernetes (JSON/YAML), Helm v3, and Kustomize v3
* Scanning of Dockerfiles
* Support for AWS, Azure, GCP, Kubernetes, Dockerfiles, and GitHub
* Scanning of [Terraform](https://runterrascan.io/docs/usage/command_line_mode/#scanning-current-directory-containing-terraform-files-for-aws-resources) (HCL2)
* Scanning of [Kubernetes](https://runterrascan.io/docs/usage/command_line_mode/#scanning-for-a-specific-iac-provider) (JSON/YAML), [Helm](https://runterrascan.io/docs/usage/command_line_mode/#scanning-a-helm-chart) v3, and [Kustomize](https://runterrascan.io/docs/usage/command_line_mode/#scanning-a-kustomize-chart)
* Scanning of [Dockerfiles](https://runterrascan.io/docs/usage/command_line_mode/#scanning-a-dockerfile)
* Support for [AWS](https://runterrascan.io/docs/policies/aws/), [Azure](https://runterrascan.io/docs/policies/azure/), [GCP](https://runterrascan.io/docs/policies/gcp/), [Kubernetes](https://runterrascan.io/docs/policies/k8s/), [Dockerfile](https://runterrascan.io/docs/policies/docker/), and [GitHub](https://runterrascan.io/docs/policies/github/)
* Integrates with docker image vulnerability scanning for AWS, Azure, GCP container registries.

## Quick Start
Expand Down
16 changes: 15 additions & 1 deletion docs/usage/command_line_mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,20 @@ $ terrascan scan -i kustomize

This command looks for a `kustomization.yaml` file in the current directory and scans rendered .yaml or .yml template files.

Terrascan considers Kustomize v4 as the default version. Other supported versions (v2 and v3) of Kustomize could be scanned by specifying --iac-version flag as follows:

```
$ terrascan scan -i kustomize --iac-version v2
```

Scanning v2 and v3 requires the corresponding Kustomize binary and the path to the binary must be specified in the `KUSTOMIZE_<VERSION>` ENV variable.

e.g: For --iac-version v2, we need to have:

KUSTOMIZE_V2=path/to/kustomize/v2/binary

To install Kustomize one can use [this script](https://github.com/accurics/terrascan/tree/master/scripts/install_kustomize.sh)

A specific directory to scan can be specified using the `-d` flag. The Kustomize IaC provider does not support scanning of individual files using the `-f` flag.

### Scanning a Dockerfile
Expand Down Expand Up @@ -288,7 +302,7 @@ Flags:
-d, --iac-dir string path to a directory containing one or more IaC files (default ".")
-f, --iac-file string path to a single IaC file
-i, --iac-type string iac type (arm, cft, docker, helm, k8s, kustomize, terraform, tfplan)
--iac-version string iac version (arm: v1, cft: v1, docker: v1, helm: v3, k8s: v1, kustomize: v3, terraform: v12, v13, v14, v15, tfplan: v1)
--iac-version string iac version (arm: v1, cft: v1, docker: v1, helm: v3, k8s: v1, kustomize: v2, v3, v4, terraform: v12, v13, v14, v15, tfplan: v1)
--non-recursive do not scan directories and modules recursively
-p, --policy-path stringArray policy path directory
-t, --policy-type strings policy type (all, aws, azure, gcp, github, k8s) (default [all])
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,6 @@ require (
k8s.io/apimachinery v0.21.0
k8s.io/client-go v10.0.0+incompatible
modernc.org/sqlite v1.11.1
sigs.k8s.io/kustomize/api v0.8.5
sigs.k8s.io/kustomize/api v0.8.11
sigs.k8s.io/kustomize/kyaml v0.11.0
)
23 changes: 18 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -486,8 +486,9 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs=
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
Expand Down Expand Up @@ -571,7 +572,6 @@ github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsd
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/spec v0.19.5 h1:Xm0Ao53uqnk9QE/LlYV5DEU09UAgpliA85QoT9LzqPw=
github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
Expand Down Expand Up @@ -755,8 +755,9 @@ github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I=
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
github.com/googleapis/gnostic v0.5.1 h1:A8Yhf6EtqTv9RMsU6MQTyrtV1TjWlR6xU9BsZIwuTCM=
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
github.com/gookit/color v1.2.4/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg=
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
github.com/gophercloud/gophercloud v0.6.1-0.20191122030953-d8ac278c1c9d/go.mod h1:ozGNgr9KYOVATV5jsgHl/ceCDXGuguqOZAzoQ/2vcNM=
Expand Down Expand Up @@ -1369,6 +1370,7 @@ github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfD
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
Expand Down Expand Up @@ -2050,6 +2052,7 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
Expand Down Expand Up @@ -2106,6 +2109,10 @@ k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=
k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e h1:KLHHjkdQFomZy8+06csTWZ0m1343QqxZhR2LJ1OxCYM=
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e h1:KLHHjkdQFomZy8+06csTWZ0m1343QqxZhR2LJ1OxCYM=
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
k8s.io/kubectl v0.21.0/go.mod h1:EU37NukZRXn1TpAkMUoy8Z/B2u6wjHDS4aInsDzVvks=
k8s.io/kubernetes v1.11.10/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
Expand Down Expand Up @@ -2161,17 +2168,23 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
sigs.k8s.io/kustomize/api v0.8.5 h1:bfCXGXDAbFbb/Jv5AhMj2BB8a5VAJuuQ5/KU69WtDjQ=
sigs.k8s.io/kustomize/api v0.8.5/go.mod h1:M377apnKT5ZHJS++6H4rQoCHmWtt6qTpp3mbe7p6OLY=
sigs.k8s.io/kustomize/api v0.8.11 h1:LzQzlq6Z023b+mBtc6v72N2mSHYmN8x7ssgbf/hv0H8=
sigs.k8s.io/kustomize/api v0.8.11 h1:LzQzlq6Z023b+mBtc6v72N2mSHYmN8x7ssgbf/hv0H8=
sigs.k8s.io/kustomize/api v0.8.11/go.mod h1:a77Ls36JdfCWojpUqR6m60pdGY1AYFix4AH83nJtY1g=
sigs.k8s.io/kustomize/api v0.8.11/go.mod h1:a77Ls36JdfCWojpUqR6m60pdGY1AYFix4AH83nJtY1g=
sigs.k8s.io/kustomize/cmd/config v0.9.7/go.mod h1:MvXCpHs77cfyxRmCNUQjIqCmZyYsbn5PyQpWiq44nW0=
sigs.k8s.io/kustomize/kustomize/v4 v4.0.5/go.mod h1:C7rYla7sI8EnxHE/xEhRBSHMNfcL91fx0uKmUlUhrBk=
sigs.k8s.io/kustomize/kyaml v0.10.15 h1:dSLgG78KyaxN4HylPXdK+7zB3k7sW6q3IcCmcfKA+aI=
sigs.k8s.io/kustomize/kyaml v0.10.15/go.mod h1:mlQFagmkm1P+W4lZJbJ/yaxMd8PqMRSC4cPcfUVt5Hg=
sigs.k8s.io/kustomize/kyaml v0.11.0 h1:9KhiCPKaVyuPcgOLJXkvytOvjMJLoxpjodiycb4gHsA=
sigs.k8s.io/kustomize/kyaml v0.11.0/go.mod h1:GNMwjim4Ypgp/MueD3zXHLRJEjz7RvtPae0AwlvEMFM=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU=
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18=
sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8=
sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
Expand Down
6 changes: 6 additions & 0 deletions pkg/iac-providers/kustomize.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,24 @@ package iacprovider
import (
"reflect"

kustomizev2 "github.com/accurics/terrascan/pkg/iac-providers/kustomize/v2"
kustomizev3 "github.com/accurics/terrascan/pkg/iac-providers/kustomize/v3"
kustomizev4 "github.com/accurics/terrascan/pkg/iac-providers/kustomize/v4"
)

// kustomize specific constants
const (
kustomize supportedIacType = "kustomize"
kustomizeV4 supportedIacVersion = "v4"
kustomizeV3 supportedIacVersion = "v3"
kustomizeV2 supportedIacVersion = "v2"
kustomizeDefaultIacVersion = kustomizeV4
)

// register kustomize as an IaC provider with terrascan
func init() {
// register iac provider
RegisterIacProvider(kustomize, kustomizeV4, kustomizeDefaultIacVersion, reflect.TypeOf(kustomizev4.KustomizeV4{}))
RegisterIacProvider(kustomize, kustomizeV3, kustomizeDefaultIacVersion, reflect.TypeOf(kustomizev3.KustomizeV3{}))
RegisterIacProvider(kustomize, kustomizeV2, kustomizeDefaultIacVersion, reflect.TypeOf(kustomizev2.KustomizeV2{}))
}
180 changes: 180 additions & 0 deletions pkg/iac-providers/kustomize/commons/load-dir.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/*
Copyright (C) 2020 Accurics, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package commons

import (
"bytes"
"fmt"
"os"
"os/exec"
"path/filepath"

k8sv1 "github.com/accurics/terrascan/pkg/iac-providers/kubernetes/v1"
"github.com/accurics/terrascan/pkg/iac-providers/output"
"github.com/accurics/terrascan/pkg/results"
"github.com/accurics/terrascan/pkg/utils"
"github.com/hashicorp/go-multierror"
"go.uber.org/zap"
"sigs.k8s.io/kustomize/api/krusty"
"sigs.k8s.io/kustomize/kyaml/filesys"
)

const (
kustomizedirectory string = "kustomization"
iacSearchError string = "error while searching for iac files"
strRootDir string = "root dir"
)

var (
kustomizeErrMessage = "error from kustomization. error : %v"
)

// NewKustomizeDirectoryLoader creates a new kustomizeDirectoryLoader
func NewKustomizeDirectoryLoader(absRootDir string, options map[string]interface{}, useKustomizeBinary bool, version string) KustomizeDirectoryLoader {
kustomizeDirectoryLoader := KustomizeDirectoryLoader{
absRootDir: absRootDir,
options: options,
useKustomizeBinary: useKustomizeBinary,
version: version,
}

return kustomizeDirectoryLoader
}

// LoadIacDir loads the kustomize directory and returns the ResourceConfig mapping which is evaluated by the policy engine
func (t KustomizeDirectoryLoader) LoadIacDir() (output.AllResourceConfigs, error) {

allResourcesConfig := make(map[string][]output.ResourceConfig)

files, err := utils.FindFilesBySuffixInDir(t.absRootDir, KustomizeFileNames())
if err != nil {
zap.S().Debug(iacSearchError, zap.String(strRootDir, t.absRootDir), zap.Error(err))
return allResourcesConfig, multierror.Append(t.errIacLoadDirs, results.DirScanErr{IacType: "kustomize", Directory: t.absRootDir, ErrMessage: err.Error()})
}

if len(files) == 0 {
errMsg := fmt.Sprintf("kustomization.y(a)ml file not found in the directory %s", t.absRootDir)
zap.S().Debug(iacSearchError, zap.String(strRootDir, t.absRootDir), zap.Error(err))
return allResourcesConfig, multierror.Append(t.errIacLoadDirs, results.DirScanErr{IacType: "kustomize", Directory: t.absRootDir, ErrMessage: errMsg})
}

if len(files) > 1 {
errMsg := fmt.Sprintf("multiple kustomization.y(a)ml found in the directory %s", t.absRootDir)
zap.S().Debug(iacSearchError, zap.String(strRootDir, t.absRootDir), zap.Error(err))
return allResourcesConfig, multierror.Append(t.errIacLoadDirs, results.DirScanErr{IacType: "kustomize", Directory: t.absRootDir, ErrMessage: errMsg})
}

kustomizeFileName := *files[0]
yamlkustomizeobj, err := utils.ReadYamlFile(filepath.Join(t.absRootDir, kustomizeFileName))

if err != nil {
err = fmt.Errorf("unable to read the kustomization file in the directory %s, error: %v", t.absRootDir, err)
zap.S().Error("error while reading the file", kustomizeFileName, zap.Error(err))
return allResourcesConfig, multierror.Append(t.errIacLoadDirs, results.DirScanErr{IacType: "kustomize", Directory: t.absRootDir, ErrMessage: err.Error()})
}

// ResourceConfig representing the kustomization.y(a)ml file
config := output.ResourceConfig{
Name: filepath.Dir(t.absRootDir),
cesar-rodriguez marked this conversation as resolved.
Show resolved Hide resolved
Type: kustomizedirectory,
Line: 1,
ID: kustomizedirectory + "." + filepath.Dir(t.absRootDir),
Source: filepath.Join(t.absRootDir, kustomizeFileName),
Config: yamlkustomizeobj,
}

allResourcesConfig[kustomizedirectory] = append(allResourcesConfig[kustomizedirectory], config)

// obtaining list of IacDocuments from the target working directory
iacDocuments, err := LoadKustomize(t.absRootDir, kustomizeFileName, t.version, t.useKustomizeBinary)
if err != nil {
errMsg := fmt.Sprintf("error occurred while loading kustomize directory '%s'. err: %v", t.absRootDir, err)
zap.S().Error("error occurred while loading kustomize directory", zap.String("kustomize directory", t.absRootDir), zap.Error(err))
return nil, multierror.Append(t.errIacLoadDirs, results.DirScanErr{IacType: "kustomize", Directory: t.absRootDir, ErrMessage: errMsg})
}

for _, doc := range iacDocuments {
var k k8sv1.K8sV1
var config *output.ResourceConfig

config, err = k.Normalize(doc)
if err != nil {
zap.S().Warn("unable to normalize data", zap.Error(err), zap.String("file", doc.FilePath))
continue
}

// TODO finding a better solution to detect accurate line number for tracing back the files causing violations
config.Line = 1
config.Source = doc.FilePath
allResourcesConfig[config.Type] = append(allResourcesConfig[config.Type], *config)
}

return allResourcesConfig, t.errIacLoadDirs
}

// LoadKustomize loads up a 'kustomized' directory and returns a returns a list of IacDocuments
func LoadKustomize(basepath, filename, version string, useKustomizeBinary bool) ([]*utils.IacDocument, error) {

var yaml []byte
if useKustomizeBinary {
envVar := "KUSTOMIZE_" + version
kustomizeBinaryPath, exists := os.LookupEnv(envVar)
if !exists {
return nil, fmt.Errorf(kustomizeErrMessage, "Environment variable "+envVar+" not set")
}
exe := kustomizeBinaryPath
arg1 := "build"
arg2 := basepath

cmd := exec.Command(exe, arg1, arg2)

var stdOut, stdErr bytes.Buffer
cmd.Stdout = &stdOut
cmd.Stderr = &stdErr

err := cmd.Run()

if err != nil {
if stdErr.String() != "" {
return nil, fmt.Errorf(kustomizeErrMessage, stdErr.String())
}
return nil, fmt.Errorf(kustomizeErrMessage, err)
}

yaml = stdOut.Bytes()
} else {
fSys := filesys.MakeFsOnDisk()
k := krusty.MakeKustomizer(krusty.MakeDefaultOptions())

m, err := k.Run(fSys, basepath)
if err != nil {
return nil, fmt.Errorf(kustomizeErrMessage, err)
}

yaml, err = m.AsYaml()
if err != nil {
return nil, err
}
}

res, err := utils.LoadYAMLString(string(yaml), filename)
if err != nil {
return nil, err
}

return res, nil
}
Loading