Skip to content

Commit

Permalink
Merge pull request open-policy-agent#583 from drybrough/feat/support-…
Browse files Browse the repository at this point in the history
…properties

Add support for properties files.
  • Loading branch information
jalseth authored Jun 25, 2021
2 parents c0885da + 08d15c1 commit 10f5a38
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 14 deletions.
5 changes: 5 additions & 0 deletions acceptance.bats
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,11 @@
[[ "$output" =~ "ALB \`my-alb-listener\` is using HTTP rather than HTTP" ]]
}

@test "Can parse properties files" {
run ./conftest test -p examples/properties/policy/ examples/properties/sample.properties
[ "$status" -eq 0 ]
}

@test "Can parse stdin with parser flag" {
run bash -c "cat examples/ini/grafana.ini | ./conftest test -p examples/ini/policy --parser ini -"
[ "$status" -eq 1 ]
Expand Down
19 changes: 19 additions & 0 deletions examples/properties/policy/test.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package main

deny_valid_uri[msg] {
value := input[name]
contains(lower(name), "url")
not contains(lower(value), "http")
msg := sprintf("Must have a valid uri defined '%s'", [value])
}

secret_exceptions = {
"secret.value.exception"
}

deny_no_secrets[msg] {
value := input[name]
not secret_exceptions[name]
contains(lower(name), "secret")
msg := sprintf("'%s' may contain a secret value", [name])
}
3 changes: 3 additions & 0 deletions examples/properties/sample.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SAMPLE_VALUE=something-here
other.value.url=https://example.com/
secret.value.exception=f9761ebe-d4dc-11eb-8046-1e00e20cdb95
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (
github.com/hashicorp/hcl v1.0.0
github.com/jstemmer/go-junit-report v0.9.1
github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/magiconair/properties v1.8.1 // indirect
github.com/moby/buildkit v0.8.2
github.com/olekukonko/tablewriter v0.0.5
github.com/open-policy-agent/opa v0.29.4
Expand Down
33 changes: 19 additions & 14 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/open-policy-agent/conftest/parser/ini"
"github.com/open-policy-agent/conftest/parser/json"
"github.com/open-policy-agent/conftest/parser/jsonnet"
"github.com/open-policy-agent/conftest/parser/properties"
"github.com/open-policy-agent/conftest/parser/toml"
"github.com/open-policy-agent/conftest/parser/vcl"
"github.com/open-policy-agent/conftest/parser/xml"
Expand All @@ -28,20 +29,21 @@ import (
// The defined parsers are the parsers that are valid for
// parsing files.
const (
TOML = "toml"
CUE = "cue"
Dockerfile = "dockerfile"
EDN = "edn"
HCL1 = "hcl1"
HCL2 = "hcl2"
CUE = "cue"
INI = "ini"
HOCON = "hocon"
Dockerfile = "dockerfile"
YAML = "yaml"
IGNORE = "ignore"
INI = "ini"
JSON = "json"
JSONNET = "jsonnet"
EDN = "edn"
PROPERTIES = "properties"
TOML = "toml"
VCL = "vcl"
XML = "xml"
IGNORE = "ignore"
YAML = "yaml"
)

// Parser defines all of the methods that every parser
Expand Down Expand Up @@ -81,6 +83,8 @@ func New(parser string) (Parser, error) {
return &xml.Parser{}, nil
case IGNORE:
return &ignore.Parser{}, nil
case PROPERTIES:
return &properties.Parser{}, nil
default:
return nil, fmt.Errorf("unknown parser: %v", parser)
}
Expand Down Expand Up @@ -134,20 +138,21 @@ func NewFromPath(path string) (Parser, error) {
// Parsers returns a list of the supported Parsers.
func Parsers() []string {
parsers := []string{
TOML,
CUE,
Dockerfile,
EDN,
HCL1,
HCL2,
CUE,
INI,
HOCON,
Dockerfile,
YAML,
IGNORE,
INI,
JSON,
JSONNET,
EDN,
PROPERTIES,
TOML,
VCL,
XML,
IGNORE,
YAML,
}

return parsers
Expand Down
31 changes: 31 additions & 0 deletions parser/properties/properties.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package properties

import (
"encoding/json"
"fmt"

prop "github.com/magiconair/properties"
)

// Parser is a properties parser.
type Parser struct{}

func (pp *Parser) Unmarshal(p []byte, v interface{}) error {
rawProps, err := prop.LoadString(string(p))
if err != nil {
return fmt.Errorf("Could not parse properties file: %w", err)
}

result := rawProps.Map()

j, err := json.Marshal(result)
if err != nil {
return fmt.Errorf("marshal properties to json: %w", err)
}

if err := json.Unmarshal(j, v); err != nil {
return fmt.Errorf("unmarshal properties json: %w", err)
}

return nil
}
38 changes: 38 additions & 0 deletions parser/properties/properties_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package properties

import (
"testing"
)

func TestPropertiesParser(t *testing.T) {
parser := &Parser{}
sample := `# This is a simle properties file
SAMPLE_KEY=https://example.com/
! some comment=not-a-prop
my-property=some-value`

var input interface{}
if err := parser.Unmarshal([]byte(sample), &input); err != nil {
t.Errorf("parser should not have thrown an error: %v", err)
}

if input == nil {
t.Errorf("there should be information parsed but its nil")
}

inputMap := input.(map[string]interface{})
myProp := inputMap["my-property"].(string)
if myProp != "some-value" {
t.Errorf("Failed to parse property: %s", myProp)
}

spaceProp := inputMap["SAMPLE_KEY"].(string)
if spaceProp != "https://example.com/" {
t.Errorf("Failed to strip whitespace from key: %s", myProp)
}

inputLen := len(inputMap)
if inputLen != 2 {
t.Errorf("Failed to parse all properties: expected 2 got %d", inputLen)
}
}

0 comments on commit 10f5a38

Please sign in to comment.