From cad1384dbab62456a04b7d169bc4e4f6355f739a Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Wed, 1 Nov 2023 00:24:13 -0700 Subject: [PATCH 1/3] add Golang API docs Signed-off-by: Jim Bugwadia --- README.md | 15 ++---- test/api/go/main/main.go | 72 +++++++++++++++++++++++++ website/docs/go-library/index.md | 90 +++++++++++++++++++++++++++++++- 3 files changed, 166 insertions(+), 11 deletions(-) create mode 100644 test/api/go/main/main.go diff --git a/README.md b/README.md index d150363e..eab94dd8 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,6 @@ ![logo](website/docs/static/kyverno-json-horizontal.png) - Use Kyverno's powerful, declarative, low-code policies to validate any runtime or configuration data that can be converted to JSON including: * Terraform files * Dockerfiles @@ -15,6 +14,8 @@ Use Kyverno's powerful, declarative, low-code policies to validate any runtime o Run `kyverno-json` as a CLI, or a web application with a REST API. Or, integrate as a Golang library. +**WARNING: ⚠️ Kyverno JSON is in early development and changes may not be backwards compatible.** + ## 📙 Documentation Documentation is available at: https://kyverno.github.io/kyverno-json @@ -33,23 +34,17 @@ We are here to help! 👉 For discussions or questions, join the [Kyverno Slack channel](https://slack.k8s.io/#kyverno). -👉 For community meeting access, join the [mailing list](https://groups.google.com/g/kyverno). - -👉 To get notified ⭐️ [star this repository](https://github.com/kyverno/kyverno-json/stargazers). +👉 To get notified on updates ⭐️ [star this repository](https://github.com/kyverno/kyverno-json/stargazers). ## ➕ Contributing Thanks for your interest in contributing to Kyverno! Here are some steps to help get you started: -✔ Read and agree to the [Contribution Guidelines](/CONTRIBUTING.md). - -✔ Check out the [good first issues](https://github.com/kyverno/kyverno-json/labels/good%20first%20issue) list. Add a comment with `/assign` to request assignment of the issue. +✔ Look through the [good first issues](https://github.com/kyverno/kyverno-json/labels/good%20first%20issue) list. Add a comment with `/assign` to request assignment of the issue. ✔ Check out the Kyverno [Community page](https://kyverno.io/community/) for other ways to get involved. -## Developer Documentation - -Developer documentation can be found in the [.docs](./.docs/) folder. +✔ Read the developer documentation in the [.docs](./.docs/) folder. ## License diff --git a/test/api/go/main/main.go b/test/api/go/main/main.go new file mode 100644 index 00000000..a53153d5 --- /dev/null +++ b/test/api/go/main/main.go @@ -0,0 +1,72 @@ +package main + +import ( + "context" + "encoding/json" + "log" + + "github.com/kyverno/kyverno-json/pkg/apis/v1alpha1" + jsonengine "github.com/kyverno/kyverno-json/pkg/json-engine" + "gopkg.in/yaml.v2" +) + +func main() { + + // load policies + policyYAML := ` + apiVersion: json.kyverno.io/v1alpha1 + kind: ValidatingPolicy + metadata: + name: authz + spec: + rules: + - name: delete-checks + match: + all: + (input.method): "DELETE" + assert: + all: + - check: + role: "admin" + ` + + var policy v1alpha1.ValidatingPolicy + yaml.Unmarshal([]byte(policyYAML), &policy) + + // load payloads + requestJSON := `{ + "name": "Annie", + "role": "admin", + "input": { + "method": "DELETE", + "path": "/red-files" + } + }` + + var payload interface{} + json.Unmarshal([]byte(requestJSON), &payload) + + // create a JsonEngineRequest + request := jsonengine.JsonEngineRequest{ + Resources: []interface{}{payload}, + Policies: []*v1alpha1.ValidatingPolicy{&policy}, + } + + // create a J + engine := jsonengine.New() + + responses := engine.Run(context.Background(), request) + + logger := log.Default() + for _, resp := range responses { + if resp.Error != nil { + // ...handle execution error + logger.Printf("policy error: %v", resp.Error) + } + + if resp.Failure != nil { + // ...handle policy failure + logger.Printf("policy failure: %v", resp.Failure) + } + } +} diff --git a/website/docs/go-library/index.md b/website/docs/go-library/index.md index b878927e..9a8cdaa0 100644 --- a/website/docs/go-library/index.md +++ b/website/docs/go-library/index.md @@ -1,4 +1,92 @@ # Usage +The Go API provides a way to embed the Kyverno JSON engine in Go programs that validate JSON payloads using Kyverno policies. + +The Go API can be added to a program's dependencies as follows: + +```sh +go get github.com/kyverno/kyverno-json/pkg/jsonengine +``` + +Here is a sample program that shows the overall flow for programatically using the Kyverno JSON Engine: + +```go +package main + +import ( + "context" + "encoding/json" + "log" + + "github.com/kyverno/kyverno-json/pkg/apis/v1alpha1" + jsonengine "github.com/kyverno/kyverno-json/pkg/json-engine" + "gopkg.in/yaml.v2" +) + +func main() { + + // load policies + policyYAML := ` + apiVersion: json.kyverno.io/v1alpha1 + kind: ValidatingPolicy + metadata: + name: authz + spec: + rules: + - name: delete-checks + match: + all: + (input.method): "DELETE" + assert: + all: + - check: + role: "admin" + ` + + var policy v1alpha1.ValidatingPolicy + yaml.Unmarshal([]byte(policyYAML), &policy) + + // load payloads + requestJSON := `{ + "name": "Annie", + "role": "admin", + "input": { + "method": "DELETE", + "path": "/red-files" + } + }` + + var payload interface{} + json.Unmarshal([]byte(requestJSON), &payload) + + // create a JsonEngineRequest + request := jsonengine.JsonEngineRequest{ + Resources: []interface{}{payload}, + Policies: []*v1alpha1.ValidatingPolicy{&policy}, + } + + // create a JSON Engine + engine := jsonengine.New() + + // execute the request + responses := engine.Run(context.Background(), request) + + // process the response + logger := log.Default() + for _, resp := range responses { + if resp.Error != nil { + // ...handle execution error + logger.Printf("policy error: %v", resp.Error) + } + + if resp.Failure != nil { + // ...handle policy failure + logger.Printf("policy failure: %v", resp.Failure) + } + } +} +``` + + + -tbd... \ No newline at end of file From f91f568b8181cf4009e05e9d4bbacbe44c99b25e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Wed, 1 Nov 2023 21:57:40 +0100 Subject: [PATCH 2/3] fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 5cd3974a..971faacf 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( go.uber.org/multierr v1.11.0 golang.org/x/crypto v0.14.0 gopkg.in/inf.v0 v0.9.1 + gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 gotest.tools v2.2.0+incompatible k8s.io/apimachinery v0.28.3 @@ -125,7 +126,6 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c // indirect google.golang.org/grpc v1.59.0 // indirect google.golang.org/protobuf v1.31.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/api v0.28.3 // indirect k8s.io/apiextensions-apiserver v0.28.1 // indirect k8s.io/apiserver v0.28.3 // indirect From 6c0ebaa1294b00e558cf2d52db9bddd0df22286c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Wed, 1 Nov 2023 22:10:30 +0100 Subject: [PATCH 3/3] fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché --- test/api/go/main/main.go | 51 +++++++++++++------------- website/docs/go-library/index.md | 61 +++++++++++++++----------------- 2 files changed, 55 insertions(+), 57 deletions(-) diff --git a/test/api/go/main/main.go b/test/api/go/main/main.go index a53153d5..77880054 100644 --- a/test/api/go/main/main.go +++ b/test/api/go/main/main.go @@ -5,33 +5,32 @@ import ( "encoding/json" "log" - "github.com/kyverno/kyverno-json/pkg/apis/v1alpha1" jsonengine "github.com/kyverno/kyverno-json/pkg/json-engine" - "gopkg.in/yaml.v2" + "github.com/kyverno/kyverno-json/pkg/policy" ) -func main() { - - // load policies - policyYAML := ` - apiVersion: json.kyverno.io/v1alpha1 - kind: ValidatingPolicy - metadata: - name: authz - spec: - rules: - - name: delete-checks - match: - all: - (input.method): "DELETE" - assert: - all: - - check: - role: "admin" - ` +const policyYAML = ` +apiVersion: json.kyverno.io/v1alpha1 +kind: ValidatingPolicy +metadata: + name: authz +spec: + rules: + - name: delete-checks + match: + all: + (input.method): "DELETE" + assert: + all: + - check: + role: "admin" +` - var policy v1alpha1.ValidatingPolicy - yaml.Unmarshal([]byte(policyYAML), &policy) +func main() { + policies, err := policy.Parse([]byte(policyYAML)) + if err != nil { + panic(err) + } // load payloads requestJSON := `{ @@ -44,12 +43,14 @@ func main() { }` var payload interface{} - json.Unmarshal([]byte(requestJSON), &payload) + if err := json.Unmarshal([]byte(requestJSON), &payload); err != nil { + panic(err) + } // create a JsonEngineRequest request := jsonengine.JsonEngineRequest{ Resources: []interface{}{payload}, - Policies: []*v1alpha1.ValidatingPolicy{&policy}, + Policies: policies, } // create a J diff --git a/website/docs/go-library/index.md b/website/docs/go-library/index.md index 9a8cdaa0..8d28142d 100644 --- a/website/docs/go-library/index.md +++ b/website/docs/go-library/index.md @@ -6,6 +6,8 @@ The Go API can be added to a program's dependencies as follows: ```sh go get github.com/kyverno/kyverno-json/pkg/jsonengine +go get github.com/kyverno/kyverno-json/pkg/policy + ``` Here is a sample program that shows the overall flow for programatically using the Kyverno JSON Engine: @@ -18,33 +20,32 @@ import ( "encoding/json" "log" - "github.com/kyverno/kyverno-json/pkg/apis/v1alpha1" jsonengine "github.com/kyverno/kyverno-json/pkg/json-engine" - "gopkg.in/yaml.v2" + "github.com/kyverno/kyverno-json/pkg/policy" ) -func main() { +const policyYAML = ` +apiVersion: json.kyverno.io/v1alpha1 +kind: ValidatingPolicy +metadata: + name: authz +spec: + rules: + - name: delete-checks + match: + all: + (input.method): "DELETE" + assert: + all: + - check: + role: "admin" +` - // load policies - policyYAML := ` - apiVersion: json.kyverno.io/v1alpha1 - kind: ValidatingPolicy - metadata: - name: authz - spec: - rules: - - name: delete-checks - match: - all: - (input.method): "DELETE" - assert: - all: - - check: - role: "admin" - ` - - var policy v1alpha1.ValidatingPolicy - yaml.Unmarshal([]byte(policyYAML), &policy) +func main() { + policies, err := policy.Parse([]byte(policyYAML)) + if err != nil { + panic(err) + } // load payloads requestJSON := `{ @@ -57,21 +58,21 @@ func main() { }` var payload interface{} - json.Unmarshal([]byte(requestJSON), &payload) + if err := json.Unmarshal([]byte(requestJSON), &payload); err != nil { + panic(err) + } // create a JsonEngineRequest request := jsonengine.JsonEngineRequest{ Resources: []interface{}{payload}, - Policies: []*v1alpha1.ValidatingPolicy{&policy}, + Policies: policies, } - // create a JSON Engine + // create a J engine := jsonengine.New() - // execute the request responses := engine.Run(context.Background(), request) - // process the response logger := log.Default() for _, resp := range responses { if resp.Error != nil { @@ -86,7 +87,3 @@ func main() { } } ``` - - - -