Skip to content

Commit

Permalink
yaml support
Browse files Browse the repository at this point in the history
Signed-off-by: Charles-Edouard Brétéché <[email protected]>
  • Loading branch information
eddycharly committed Sep 29, 2023
1 parent c314889 commit f8ff94a
Show file tree
Hide file tree
Showing 18 changed files with 430 additions and 45 deletions.
4 changes: 0 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
.tools
.gopath
json-kyverno
.terraform/
.terraform.lock.hcl
tf.plan
tf.plan.json
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,9 @@ make build
## invoke json-kyverno

```console
./json-kyverno --payload ./tf.plan.json --pre-process "planned_values.root_module.resources" --policy ./policy.yaml
# with json payload
./json-kyverno --payload ./testdata/tf-plan/tf.plan.json --pre-process "planned_values.root_module.resources" --policy ./testdata/tf-plan/policy.yaml

# with yaml payload
./json-kyverno --payload ./testdata/payload-yaml/payload.yaml --pre-process "planned_values.root_module.resources" --policy ./testdata/payload-yaml/policy.yaml
```
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/kyverno/kyverno v1.5.0-rc1.0.20230927190803-27858f634e28
github.com/spf13/cobra v1.7.0
github.com/stretchr/testify v1.8.4
gopkg.in/yaml.v3 v3.0.1
k8s.io/apimachinery v0.28.2
sigs.k8s.io/kubectl-validate v0.0.0-20230927155409-3b3ca3ad91d0
)
Expand Down Expand Up @@ -282,7 +283,6 @@ require (
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a // indirect
k8s.io/api v0.28.2 // indirect
k8s.io/apiextensions-apiserver v0.28.1 // indirect
Expand Down
6 changes: 3 additions & 3 deletions pkg/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import (
"errors"
"fmt"

"github.com/eddycharly/json-kyverno/pkg/engine/template"
jsonengine "github.com/eddycharly/json-kyverno/pkg/json-engine"
"github.com/eddycharly/json-kyverno/pkg/payload"
"github.com/eddycharly/json-kyverno/pkg/policy"
"github.com/eddycharly/json-kyverno/pkg/template"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/output/pluralize"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
Expand All @@ -26,7 +26,7 @@ func (c *command) Run(cmd *cobra.Command, _ []string) error {
if err != nil {
return err
}
fmt.Fprintln(out, "Loading plan ...")
fmt.Fprintln(out, "Loading payload ...")
payload, err := payload.Load(c.payload)
if err != nil {
return err
Expand Down Expand Up @@ -79,7 +79,7 @@ func NewRootCommand() *cobra.Command {
RunE: command.Run,
SilenceUsage: true,
}
cmd.Flags().StringVar(&command.payload, "payload", "", "Path to json payload")
cmd.Flags().StringVar(&command.payload, "payload", "", "Path to payload (json or yaml file)")
cmd.Flags().StringSliceVar(&command.preprocessors, "pre-process", nil, "JmesPath expression used to pre process payload")
cmd.Flags().StringSliceVar(&command.policies, "policy", nil, "Path to json-kyverno policies")
return cmd
Expand Down
21 changes: 18 additions & 3 deletions pkg/commands/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,31 @@ import (
"github.com/stretchr/testify/assert"
)

func TestCommand(t *testing.T) {
func Test_TfPlan(t *testing.T) {
cmd := NewRootCommand()
assert.NotNil(t, cmd)
cmd.SetArgs([]string{
"--payload",
"../../tf.plan.json",
"../../testdata/tf-plan/tf.plan.json",
"--pre-process",
"planned_values.root_module.resources",
"--policy",
"../../policy.yaml",
"../../testdata/tf-plan/policy.yaml",
})
err := cmd.Execute()
assert.NoError(t, err)
}

func Test_PayloadYaml(t *testing.T) {
cmd := NewRootCommand()
assert.NotNil(t, cmd)
cmd.SetArgs([]string{
"--payload",
"../../testdata/payload-yaml/payload.yaml",
"--pre-process",
"planned_values.root_module.resources",
"--policy",
"../../testdata/payload-yaml/policy.yaml",
})
err := cmd.Execute()
assert.NoError(t, err)
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion pkg/match/options.go → pkg/engine/match/options.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package match

import (
"github.com/eddycharly/json-kyverno/pkg/template"
"github.com/eddycharly/json-kyverno/pkg/engine/template"
)

type matchOptions struct {
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions pkg/json-engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"github.com/eddycharly/json-kyverno/pkg/engine"
"github.com/eddycharly/json-kyverno/pkg/engine/blocks/loop"
"github.com/eddycharly/json-kyverno/pkg/engine/builder"
"github.com/eddycharly/json-kyverno/pkg/match"
"github.com/eddycharly/json-kyverno/pkg/template"
"github.com/eddycharly/json-kyverno/pkg/engine/match"
"github.com/eddycharly/json-kyverno/pkg/engine/template"
)

type JsonEngineRequest struct {
Expand Down
32 changes: 30 additions & 2 deletions pkg/payload/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ package payload

import (
"encoding/json"
"fmt"
"os"
"path/filepath"

"github.com/eddycharly/json-kyverno/pkg/utils/file"
yamlutils "github.com/kyverno/kyverno/pkg/utils/yaml"
"gopkg.in/yaml.v3"
)

func Load(path string) (interface{}, error) {
Expand All @@ -12,8 +17,31 @@ func Load(path string) (interface{}, error) {
return nil, err
}
var payload interface{}
if err := json.Unmarshal(content, &payload); err != nil {
return nil, err
switch {
case file.IsJson(path):
if err := json.Unmarshal(content, &payload); err != nil {
return nil, err
}
case file.IsYaml(path):
documents, err := yamlutils.SplitDocuments(content)
if err != nil {
return nil, err
}
var objects []interface{}
for _, document := range documents {
var object map[string]interface{}
if err := yaml.Unmarshal(document, &object); err != nil {
return nil, err
}
objects = append(objects, object)
}
if len(objects) == 1 {
payload = objects[0]
} else {
payload = objects
}
default:
return nil, fmt.Errorf("unrecognized payload format, must be yaml or json (%s)", path)
}
return payload, nil
}
11 changes: 2 additions & 9 deletions pkg/policy/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/eddycharly/json-kyverno/pkg/apis/v1alpha1"
"github.com/eddycharly/json-kyverno/pkg/data"
fileinfo "github.com/eddycharly/json-kyverno/pkg/utils/file-info"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/resource/convert"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/resource/loader"
yamlutils "github.com/kyverno/kyverno/pkg/utils/yaml"
Expand All @@ -20,14 +21,6 @@ var (
policy_v1alpha1 = gv_v1alpha1.WithKind("Policy")
)

func IsYaml(file fs.FileInfo) bool {
if file.IsDir() {
return false
}
ext := filepath.Ext(file.Name())
return ext == ".yml" || ext == ".yaml"
}

func Load(path ...string) ([]*v1alpha1.Policy, error) {
var policies []*v1alpha1.Policy
for _, path := range path {
Expand All @@ -46,7 +39,7 @@ func load(path string) ([]*v1alpha1.Policy, error) {
if err != nil {
return err
}
if IsYaml(info) {
if fileinfo.IsYaml(info) {
files = append(files, file)
}
return nil
Expand Down
28 changes: 28 additions & 0 deletions pkg/utils/file-info/ext.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package fileinfo

import (
"io/fs"

"github.com/eddycharly/json-kyverno/pkg/utils/file"
)

func IsYaml(info fs.FileInfo) bool {
if info.IsDir() {
return false
}
return file.IsYaml(info.Name())
}

func IsJson(info fs.FileInfo) bool {
if info.IsDir() {
return false
}
return file.IsJson(info.Name())
}

func IsYamlOrJson(info fs.FileInfo) bool {
if info.IsDir() {
return false
}
return file.IsYamlOrJson(info.Name())
}
19 changes: 19 additions & 0 deletions pkg/utils/file/ext.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package file

import (
"path/filepath"
)

func IsYaml(path string) bool {
ext := filepath.Ext(path)
return ext == ".yml" || ext == ".yaml"
}

func IsJson(path string) bool {
ext := filepath.Ext(path)
return ext == ".json"
}

func IsYamlOrJson(path string) bool {
return IsYaml(path) || IsJson(path)
}
18 changes: 0 additions & 18 deletions s3.tf

This file was deleted.

130 changes: 130 additions & 0 deletions testdata/payload-yaml/payload.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
format_version: '1.1'
terraform_version: 1.4.6
planned_values:
root_module:
resources:
- address: aws_s3_bucket.example
mode: managed
type: aws_s3_bucket
name: example
provider_name: registry.terraform.io/hashicorp/aws
schema_version: 0
values:
bucket: my-tf-test-bucket
force_destroy: false
tags:
Environment: Dev
Name: My bucket
Team: Kyverno
tags_all:
Environment: Dev
Name: My bucket
Team: Kyverno
timeouts:
sensitive_values:
cors_rule: []
grant: []
lifecycle_rule: []
logging: []
object_lock_configuration: []
replication_configuration: []
server_side_encryption_configuration: []
tags: {}
tags_all: {}
versioning: []
website: []
resource_changes:
- address: aws_s3_bucket.example
mode: managed
type: aws_s3_bucket
name: example
provider_name: registry.terraform.io/hashicorp/aws
change:
actions:
- create
before:
after:
bucket: my-tf-test-bucket
force_destroy: false
tags:
Environment: Dev
Name: My bucket
Team: Kyverno
tags_all:
Environment: Dev
Name: My bucket
Team: Kyverno
timeouts:
after_unknown:
acceleration_status: true
acl: true
arn: true
bucket_domain_name: true
bucket_prefix: true
bucket_regional_domain_name: true
cors_rule: true
grant: true
hosted_zone_id: true
id: true
lifecycle_rule: true
logging: true
object_lock_configuration: true
object_lock_enabled: true
policy: true
region: true
replication_configuration: true
request_payer: true
server_side_encryption_configuration: true
tags: {}
tags_all: {}
versioning: true
website: true
website_domain: true
website_endpoint: true
before_sensitive: false
after_sensitive:
cors_rule: []
grant: []
lifecycle_rule: []
logging: []
object_lock_configuration: []
replication_configuration: []
server_side_encryption_configuration: []
tags: {}
tags_all: {}
versioning: []
website: []
configuration:
provider_config:
aws:
name: aws
full_name: registry.terraform.io/hashicorp/aws
expressions:
access_key:
constant_value: mock_access_key
region:
constant_value: eu-west-1
secret_key:
constant_value: mock_secret_key
skip_credentials_validation:
constant_value: true
skip_metadata_api_check:
constant_value: true
skip_requesting_account_id:
constant_value: true
root_module:
resources:
- address: aws_s3_bucket.example
mode: managed
type: aws_s3_bucket
name: example
provider_config_key: aws
expressions:
bucket:
constant_value: my-tf-test-bucket
tags:
constant_value:
Environment: Dev
Name: My bucket
Team: Kyverno
schema_version: 0
Loading

0 comments on commit f8ff94a

Please sign in to comment.