Skip to content

Commit

Permalink
add custom board docs
Browse files Browse the repository at this point in the history
Signed-off-by: Frank Jogeleit <[email protected]>
  • Loading branch information
Frank Jogeleit committed Feb 28, 2024
1 parent 92191d8 commit 824115b
Show file tree
Hide file tree
Showing 12 changed files with 273 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Documentation for upcoming features and changes for the new Policy Reporter UI v

* [Basic Installation](https://github.com/kyverno/policy-reporter/blob/3.x/docs/TUTORIALS.md)
* [OAUth2 / OpenIDConnect](https://github.com/kyverno/policy-reporter/blob/3.x/docs/UI_AUTH.md)
* [UI CustomBoards](https://github.com/kyverno/policy-reporter/blob/3.x/docs/CUSTOM_BOARDS.md)

## Documentation

Expand Down
70 changes: 70 additions & 0 deletions docs/CUSTOM_BOARDS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Policy Reporter UI - Custom Boards

CustomBoards allows you to configure additional dashboards with a custom subset of sources and namespaces, selected via a list and/or label selector

## Example CustomBoard Config

![Custom Boards](https://github.com/kyverno/policy-reporter/blob/3.x/docs/images/custom-boards/list.png)

```yaml
ui:
enabled: true

customBoards:
- name: System
namespaces:
list:
- kube-system
- kyverno
- policy-reporter
```
### CustomBoard with NamespaceSelector
![Custom Boards](https://github.com/kyverno/policy-reporter/blob/3.x/docs/images/custom-boards/selector.png)
```yaml
ui:
enabled: true

customBoards:
- name: System
namespaces:
selector:
group: system
```
### CustomBoard with ClusterResources
![Custom Boards](https://github.com/kyverno/policy-reporter/blob/3.x/docs/images/custom-boards/cluster.png)
```yaml
ui:
enabled: true

customBoards:
- name: System
clusterScope:
enabled: true
namespaces:
selector:
group: system
```
### CustomBoard with Source List
![Custom Boards](https://github.com/kyverno/policy-reporter/blob/3.x/docs/images/custom-boards/source.png)
```yaml
ui:
enabled: true

customBoards:
- name: System
clusterScope:
enabled: true
namespaces:
selector:
group: system
sources:
list: [kyverno]
```
Binary file added docs/images/custom-boards/cluster.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/custom-boards/list.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/custom-boards/selector.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/custom-boards/source.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ require (
github.com/segmentio/fasthash v1.0.3
github.com/spf13/cobra v1.8.0
github.com/spf13/viper v1.18.2
github.com/stretchr/testify v1.8.4
github.com/uptrace/bun v1.1.17
github.com/uptrace/bun/dialect/mysqldialect v1.1.17
github.com/uptrace/bun/dialect/pgdialect v1.1.17
Expand Down Expand Up @@ -107,6 +108,7 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
Expand Down
70 changes: 70 additions & 0 deletions pkg/api/healthz_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package api_test

import (
"errors"
"net/http"
"net/http/httptest"
"testing"

"github.com/gin-gonic/gin"
"github.com/kyverno/policy-reporter/pkg/api"
"github.com/stretchr/testify/assert"
)

func TestHealthCheckSuccess(t *testing.T) {
check := func() error {
return nil
}

gin.SetMode(gin.ReleaseMode)

server := api.NewServer(gin.New(), api.WithHealthChecks([]api.HealthCheck{check}))

req, _ := http.NewRequest("GET", "/healthz", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

assert := assert.New(t)
assert.Equal(http.StatusOK, w.Code)
}

func TestHealthCheckError(t *testing.T) {
check := func() error {
return nil
}

err := func() error {
return errors.New("unhealthy")
}

gin.SetMode(gin.ReleaseMode)

server := api.NewServer(gin.New(), api.WithHealthChecks([]api.HealthCheck{check, err}))

req, _ := http.NewRequest("GET", "/healthz", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

assert := assert.New(t)
assert.Equal(http.StatusServiceUnavailable, w.Code)
}

func TestReadyCheckSuccess(t *testing.T) {
check := func() error {
return nil
}

gin.SetMode(gin.ReleaseMode)

server := api.NewServer(gin.New(), api.WithHealthChecks([]api.HealthCheck{check}))

req, _ := http.NewRequest("GET", "/ready", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

assert := assert.New(t)
assert.Equal(http.StatusOK, w.Code)
}
60 changes: 60 additions & 0 deletions pkg/api/metrics_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package api_test

import (
"net/http"
"net/http/httptest"
"testing"

"github.com/gin-gonic/gin"
"github.com/kyverno/policy-reporter/pkg/api"
"github.com/stretchr/testify/assert"
)

func TestMetrics(t *testing.T) {
gin.SetMode(gin.ReleaseMode)

server := api.NewServer(gin.New(), api.WithMetrics())

req, _ := http.NewRequest("GET", "/metrics", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

assert := assert.New(t)
assert.Equal(http.StatusOK, w.Code)
}

func TestMetricsWithBasicAuthError(t *testing.T) {
gin.SetMode(gin.ReleaseMode)

server := api.NewServer(gin.New(), api.WithBasicAuth(api.BasicAuth{
Username: "user",
Password: "password",
}), api.WithMetrics())

req, _ := http.NewRequest("GET", "/metrics", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

assert := assert.New(t)
assert.Equal(http.StatusUnauthorized, w.Code)
}

func TestMetricsWithBasicAuthSuccess(t *testing.T) {
gin.SetMode(gin.ReleaseMode)

server := api.NewServer(gin.New(), api.WithBasicAuth(api.BasicAuth{
Username: "user",
Password: "password",
}), api.WithMetrics())

req, _ := http.NewRequest("GET", "/metrics", nil)
req.SetBasicAuth("user", "password")
w := httptest.NewRecorder()

server.Serve(w, req)

assert := assert.New(t)
assert.Equal(http.StatusOK, w.Code)
}
7 changes: 6 additions & 1 deletion pkg/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package api

import (
"fmt"
"net/http"
"time"

"github.com/gin-contrib/gzip"
Expand Down Expand Up @@ -32,11 +33,15 @@ func (s *Server) Start() error {
return s.engine.Run(fmt.Sprintf(":%d", s.port))
}

func (s *Server) Serve(w http.ResponseWriter, req *http.Request) {
s.engine.ServeHTTP(w, req)
}

func (s *Server) Register(path string, handler Handler) error {
return handler.Register(s.engine.Group(path, s.middleware...))
}

func NewServer(engine *gin.Engine, options []ServerOption) *Server {
func NewServer(engine *gin.Engine, options ...ServerOption) *Server {
server := &Server{
engine: engine,
port: 8080,
Expand Down
63 changes: 63 additions & 0 deletions pkg/api/server_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package api_test

import (
"net/http"
"net/http/httptest"
"testing"

"github.com/gin-gonic/gin"
"github.com/kyverno/policy-reporter/pkg/api"
"github.com/stretchr/testify/assert"
)

var check = func() error {
return nil
}

func TestWithoutGZIP(t *testing.T) {
gin.SetMode(gin.ReleaseMode)

engine := gin.New()

server := api.NewServer(engine, api.WithHealthChecks([]api.HealthCheck{check}))

req, _ := http.NewRequest("GET", "/healthz", nil)
req.Header.Add("Accept-Encoding", "gzip")
w := httptest.NewRecorder()

server.Serve(w, req)

assert := assert.New(t)
assert.Equal(http.StatusOK, w.Code)
assert.Equal("", w.Header().Get("Content-Encoding"))
}

func TestWithGZIP(t *testing.T) {
gin.SetMode(gin.ReleaseMode)

server := api.NewServer(gin.New(), api.WithGZIP(), api.WithHealthChecks([]api.HealthCheck{check}))

req, _ := http.NewRequest("GET", "/healthz", nil)
req.Header.Add("Accept-Encoding", "gzip")
w := httptest.NewRecorder()

server.Serve(w, req)

assert := assert.New(t)
assert.Equal(http.StatusOK, w.Code)
assert.Equal("gzip", w.Header().Get("Content-Encoding"))
}

func TestWithProfiling(t *testing.T) {
gin.SetMode(gin.ReleaseMode)

server := api.NewServer(gin.New(), api.WithProfiling())

req, _ := http.NewRequest("GET", "/debug/pprof/", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

assert := assert.New(t)
assert.Equal(http.StatusOK, w.Code)
}
2 changes: 1 addition & 1 deletion pkg/config/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func (r *Resolver) Server(ctx context.Context, options []api.ServerOption) (*api
gin.SetMode(gin.ReleaseMode)
}

return api.NewServer(gin.New(), append(defaults, options...)), nil
return api.NewServer(gin.New(), append(defaults, options...)...), nil
}

// Database resolver method
Expand Down

0 comments on commit 824115b

Please sign in to comment.