From 1bdda21be4ac965bb2ec3eb3e6228fec9a53b4b1 Mon Sep 17 00:00:00 2001 From: Frank Jogeleit Date: Fri, 20 Jan 2023 13:08:44 +0100 Subject: [PATCH 1/3] add apis to list policy-report information Signed-off-by: Frank Jogeleit --- pkg/api/server.go | 3 + pkg/api/v1/finder.go | 8 ++ pkg/api/v1/handler.go | 26 +++++- pkg/api/v1/handler_test.go | 40 +++++++++ pkg/api/v1/model.go | 17 ++++ pkg/sqlite3/store.go | 177 +++++++++++++++++++++++++++++++++++++ pkg/sqlite3/store_test.go | 46 ++++++++++ 7 files changed, 314 insertions(+), 3 deletions(-) diff --git a/pkg/api/server.go b/pkg/api/server.go index 4fe4cd01..1c867feb 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -46,6 +46,9 @@ func (s *httpServer) RegisterV1Handler(finder v1.PolicyReportFinder) { s.mux.HandleFunc("/v1/namespaces", Gzip(v1.NamespaceListHandler(finder))) s.mux.HandleFunc("/v1/rule-status-count", Gzip(v1.RuleStatusCountHandler(finder))) + s.mux.HandleFunc("/v1/policy-reports", Gzip(v1.PolicyReportListHandler(finder))) + s.mux.HandleFunc("/v1/cluster-policy-reports", Gzip(v1.ClusterPolicyReportListHandler(finder))) + s.mux.HandleFunc("/v1/namespaced-resources/policies", Gzip(v1.NamespacedResourcesPolicyListHandler(finder))) s.mux.HandleFunc("/v1/namespaced-resources/rules", Gzip(v1.NamespacedResourcesRuleListHandler(finder))) s.mux.HandleFunc("/v1/namespaced-resources/kinds", Gzip(v1.NamespacedResourcesKindListHandler(finder))) diff --git a/pkg/api/v1/finder.go b/pkg/api/v1/finder.go index 96af3d67..dc6799d8 100644 --- a/pkg/api/v1/finder.go +++ b/pkg/api/v1/finder.go @@ -22,6 +22,14 @@ type Pagination struct { } type PolicyReportFinder interface { + // FetchClusterPolicyReports by filter and pagination + FetchClusterPolicyReports(Filter, Pagination) ([]*PolicyReport, error) + // FetchPolicyReports by filter and pagination + FetchPolicyReports(Filter, Pagination) ([]*PolicyReport, error) + // CountClusterPolicyReports by filter + CountClusterPolicyReports(Filter) (int, error) + // CountPolicyReports by filter + CountPolicyReports(Filter) (int, error) // FetchClusterPolicies from current PolicyReportResults FetchClusterPolicies(Filter) ([]string, error) // FetchClusterRules from current PolicyReportResults diff --git a/pkg/api/v1/handler.go b/pkg/api/v1/handler.go index c930a89d..5ac2d1b8 100644 --- a/pkg/api/v1/handler.go +++ b/pkg/api/v1/handler.go @@ -23,6 +23,26 @@ func TargetsHandler(targets []target.Client) http.HandlerFunc { } } +// PolicyReportListHandler REST API +func PolicyReportListHandler(finder PolicyReportFinder) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + filter := buildFilter(req) + count, err := finder.CountPolicyReports(filter) + list, err := finder.FetchPolicyReports(filter, buildPaginatiomn(req, []string{"namespace", "name"})) + helper.SendJSONResponse(w, PolicyReportList{Items: list, Count: count}, err) + } +} + +// PolicyReportListHandler REST API +func ClusterPolicyReportListHandler(finder PolicyReportFinder) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + filter := buildFilter(req) + count, err := finder.CountClusterPolicyReports(filter) + list, err := finder.FetchClusterPolicyReports(filter, buildPaginatiomn(req, []string{"namespace", "name"})) + helper.SendJSONResponse(w, PolicyReportList{Items: list, Count: count}, err) + } +} + // ClusterResourcesPolicyListHandler REST API func ClusterResourcesPolicyListHandler(finder PolicyReportFinder) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { @@ -159,7 +179,7 @@ func NamespacedResourcesResultHandler(finder PolicyReportFinder) http.HandlerFun return func(w http.ResponseWriter, req *http.Request) { filter := buildFilter(req) count, err := finder.CountNamespacedResults(filter) - list, err := finder.FetchNamespacedResults(filter, buildPaginatiomn(req)) + list, err := finder.FetchNamespacedResults(filter, buildPaginatiomn(req, defaultOrder)) helper.SendJSONResponse(w, ResultList{Items: list, Count: count}, err) } } @@ -169,7 +189,7 @@ func ClusterResourcesResultHandler(finder PolicyReportFinder) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { filter := buildFilter(req) count, err := finder.CountClusterResults(filter) - list, err := finder.FetchClusterResults(filter, buildPaginatiomn(req)) + list, err := finder.FetchClusterResults(filter, buildPaginatiomn(req, defaultOrder)) helper.SendJSONResponse(w, ResultList{Items: list, Count: count}, err) } } @@ -187,7 +207,7 @@ func NamespaceListHandler(finder PolicyReportFinder) http.HandlerFunc { } } -func buildPaginatiomn(req *http.Request) Pagination { +func buildPaginatiomn(req *http.Request, defaultOrder []string) Pagination { page, err := strconv.Atoi(req.URL.Query().Get("page")) if err != nil || page < 1 { page = 0 diff --git a/pkg/api/v1/handler_test.go b/pkg/api/v1/handler_test.go index b58ba941..97448d16 100644 --- a/pkg/api/v1/handler_test.go +++ b/pkg/api/v1/handler_test.go @@ -520,6 +520,46 @@ func Test_V1_API(t *testing.T) { t.Errorf("handler returned unexpected body: got %v want %v", rr.Body.String(), expected) } }) + + t.Run("PolicyReportListHandler", func(t *testing.T) { + req, err := http.NewRequest("GET", "/v1/policy-reports?namespaces=test&labels=app:policy-reporter", nil) + if err != nil { + t.Fatal(err) + } + + rr := httptest.NewRecorder() + handler := v1.PolicyReportListHandler(store) + handler.ServeHTTP(rr, req) + + if status := rr.Code; status != http.StatusOK { + t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK) + } + + expected := `{"items":[{"id":"7605991845421273693","name":"polr-test","namespace":"test","labels":{"app":"policy-reporter","scope":"namespace"},"pass":0,"skip":0,"warn":0,"error":0,"fail":1}],"count":1}` + if !strings.Contains(rr.Body.String(), expected) { + t.Errorf("handler returned unexpected body: got %v want %v", rr.Body.String(), expected) + } + }) + + t.Run("ClusterPolicyReportListHandler", func(t *testing.T) { + req, err := http.NewRequest("GET", "/v1/policy-reports?labels=app:policy-reporter", nil) + if err != nil { + t.Fatal(err) + } + + rr := httptest.NewRecorder() + handler := v1.ClusterPolicyReportListHandler(store) + handler.ServeHTTP(rr, req) + + if status := rr.Code; status != http.StatusOK { + t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK) + } + + expected := `{"items":[{"id":"7174304213499286261","name":"cpolr","labels":{"app":"policy-reporter","scope":"cluster"},"pass":0,"skip":0,"warn":0,"error":0,"fail":0}],"count":1}` + if !strings.Contains(rr.Body.String(), expected) { + t.Errorf("handler returned unexpected body: got %v want %v", rr.Body.String(), expected) + } + }) } func Test_TargetsAPI(t *testing.T) { diff --git a/pkg/api/v1/model.go b/pkg/api/v1/model.go index 345f740c..1d05cfc2 100644 --- a/pkg/api/v1/model.go +++ b/pkg/api/v1/model.go @@ -5,6 +5,23 @@ import ( "github.com/kyverno/policy-reporter/pkg/target" ) +type PolicyReport struct { + ID string `json:"id"` + Name string `json:"name"` + Namespace string `json:"namespace,omitempty"` + Labels map[string]string `json:"labels"` + Pass int `json:"pass"` + Skip int `json:"skip"` + Warn int `json:"warn"` + Error int `json:"error"` + Fail int `json:"fail"` +} + +type PolicyReportList struct { + Items []*PolicyReport `json:"items"` + Count int `json:"count"` +} + type ResultList struct { Items []*ListResult `json:"items"` Count int `json:"count"` diff --git a/pkg/sqlite3/store.go b/pkg/sqlite3/store.go index 0b60382e..969a94d6 100644 --- a/pkg/sqlite3/store.go +++ b/pkg/sqlite3/store.go @@ -204,6 +204,183 @@ func (s *policyReportStore) CleanUp() error { return err } +// FetchPolicyReports by filter and pagination +func (s *policyReportStore) FetchPolicyReports(filter api.Filter, pagination api.Pagination) ([]*api.PolicyReport, error) { + whereParts := make([]string, 0) + args := make([]interface{}, 0) + + var argCounter int + var where string + + if len(filter.Namespaces) > 0 { + argCounter, whereParts, args = appendWhere(filter.Namespaces, "namespace", whereParts, args, argCounter) + } else { + whereParts = append(whereParts, `namespace != ""`) + } + + if len(filter.ReportLabel) > 0 { + for key, value := range filter.ReportLabel { + argCounter++ + + whereParts = append(whereParts, fmt.Sprintf("json_extract(labels, '$.\"%s\"') = $%d", key, argCounter)) + args = append(args, value) + } + } + + paginationString := generatePagination(pagination) + where = strings.Join(whereParts, " AND ") + + var list = make([]*api.PolicyReport, 0) + + query := `SELECT id, namespace, name, labels, pass, skip, warn, fail, error FROM policy_report WHERE ` + where + " " + paginationString + + fmt.Println(query) + + rows, err := s.db.Query(`SELECT id, namespace, name, labels, pass, skip, warn, fail, error FROM policy_report WHERE `+where+" "+paginationString, args...) + if err != nil { + return list, err + } + defer rows.Close() + + for rows.Next() { + var labels string + r := &api.PolicyReport{} + err := rows.Scan(&r.ID, &r.Namespace, &r.Name, &labels, &r.Pass, &r.Skip, &r.Warn, &r.Fail, &r.Error) + if err != nil { + log.Printf("[ERROR] failed to scan PolicyReport: %s", err) + return list, err + } + + r.Labels, err = convertJSONToMap(labels) + if err != nil { + log.Printf("[ERROR] failed to convert json to labels: %s\n", err) + return list, err + } + + list = append(list, r) + } + + return list, nil +} + +// CountPolicyReports by filter +func (s *policyReportStore) CountPolicyReports(filter api.Filter) (int, error) { + whereParts := make([]string, 0) + args := make([]interface{}, 0) + + var argCounter int + var where string + + if len(filter.Namespaces) > 0 { + argCounter, whereParts, args = appendWhere(filter.Namespaces, "namespace", whereParts, args, argCounter) + } else { + whereParts = append(whereParts, `namespace != ""`) + } + + if len(filter.ReportLabel) > 0 { + for key, value := range filter.ReportLabel { + argCounter++ + + whereParts = append(whereParts, fmt.Sprintf("json_extract(labels, '$.\"%s\"') = $%d", key, argCounter)) + args = append(args, value) + } + } + + where = strings.Join(whereParts, " AND ") + var count int + + row := s.db.QueryRow(`SELECT count(id) FROM policy_report WHERE `+where, args...) + err := row.Scan(&count) + if err != nil { + return count, err + } + + return count, nil +} + +// FetchClusterPolicyReports by filter and pagination +func (s *policyReportStore) FetchClusterPolicyReports(filter api.Filter, pagination api.Pagination) ([]*api.PolicyReport, error) { + whereParts := make([]string, 0) + args := make([]interface{}, 0) + + var argCounter int + var where string + + whereParts = append(whereParts, `namespace = ""`) + + if len(filter.ReportLabel) > 0 { + for key, value := range filter.ReportLabel { + argCounter++ + + whereParts = append(whereParts, fmt.Sprintf("json_extract(labels, '$.\"%s\"') = $%d", key, argCounter)) + args = append(args, value) + } + } + + paginationString := generatePagination(pagination) + where = strings.Join(whereParts, " AND ") + + var list = make([]*api.PolicyReport, 0) + + rows, err := s.db.Query(`SELECT id, name, labels, pass, skip, warn, fail, error FROM policy_report WHERE `+where+" "+paginationString, args...) + if err != nil { + return list, err + } + defer rows.Close() + + for rows.Next() { + var labels string + r := &api.PolicyReport{} + err := rows.Scan(&r.ID, &r.Name, &labels, &r.Pass, &r.Skip, &r.Warn, &r.Fail, &r.Error) + if err != nil { + log.Printf("[ERROR] failed to scan PolicyReport: %s", err) + return list, err + } + + r.Labels, err = convertJSONToMap(labels) + if err != nil { + log.Printf("[ERROR] failed to convert json to labels: %s\n", err) + return list, err + } + + list = append(list, r) + } + + return list, nil +} + +// CountClusterPolicyReports by filter and pagination +func (s *policyReportStore) CountClusterPolicyReports(filter api.Filter) (int, error) { + whereParts := make([]string, 0) + args := make([]interface{}, 0) + + var argCounter int + var where string + + whereParts = append(whereParts, `namespace = ""`) + + if len(filter.ReportLabel) > 0 { + for key, value := range filter.ReportLabel { + argCounter++ + + whereParts = append(whereParts, fmt.Sprintf("json_extract(labels, '$.\"%s\"') = $%d", key, argCounter)) + args = append(args, value) + } + } + + where = strings.Join(whereParts, " AND ") + + var count int + + row := s.db.QueryRow(`SELECT count(id) FROM policy_report WHERE `+where, args...) + err := row.Scan(&count) + if err != nil { + return count, err + } + + return count, nil +} + func (s *policyReportStore) FetchClusterPolicies(filter api.Filter) ([]string, error) { list := make([]string, 0) diff --git a/pkg/sqlite3/store_test.go b/pkg/sqlite3/store_test.go index 77311ff1..76f6d2ff 100644 --- a/pkg/sqlite3/store_test.go +++ b/pkg/sqlite3/store_test.go @@ -11,6 +11,8 @@ import ( var pagination = v1.Pagination{Page: 1, Offset: 20, Direction: "ASC", SortBy: []string{"resource_name"}} +var polrPagination = v1.Pagination{Page: 1, Offset: 20, Direction: "ASC", SortBy: []string{"namespace"}} + var result1 = report.Result{ ID: "123", Message: "validation error: requests and limits required. Rule autogen-check-for-requests-and-limits failed at path /spec/template/spec/containers/0/resources/requests/", @@ -665,6 +667,50 @@ func Test_PolicyReportStore(t *testing.T) { } }) + t.Run("CountPolicyReports", func(t *testing.T) { + items, err := store.CountPolicyReports(v1.Filter{Namespaces: []string{"test"}, ReportLabel: map[string]string{"scope": "namespaced"}}) + if err != nil { + t.Fatalf("Unexpected Error: %s", err) + } + + if items != 1 { + t.Fatalf("Should return one policy report, got %d", items) + } + }) + + t.Run("FetchPolicyReports", func(t *testing.T) { + items, err := store.FetchPolicyReports(v1.Filter{Namespaces: []string{"test"}, ReportLabel: map[string]string{"scope": "namespaced"}}, polrPagination) + if err != nil { + t.Fatalf("Unexpected Error: %s", err) + } + + if len(items) != 1 { + t.Fatalf("Should return one policy report, got %d", len(items)) + } + }) + + t.Run("CountClusterReports", func(t *testing.T) { + items, err := store.CountClusterPolicyReports(v1.Filter{ReportLabel: map[string]string{"scope": "cluster"}}) + if err != nil { + t.Fatalf("Unexpected Error: %s", err) + } + + if items != 1 { + t.Fatalf("Should return one policy report, got %d", items) + } + }) + + t.Run("FetchClusterReports", func(t *testing.T) { + items, err := store.FetchClusterPolicyReports(v1.Filter{ReportLabel: map[string]string{"scope": "cluster"}}, polrPagination) + if err != nil { + t.Fatalf("Unexpected Error: %s", err) + } + + if len(items) != 1 { + t.Fatalf("Should return one policy report, got %d", len(items)) + } + }) + t.Run("ClusterLabels", func(t *testing.T) { items, err := store.FetchClusterReportLabels(v1.Filter{Sources: []string{"Kyverno"}}) if err != nil { From cdd19d826038ac9b411d47e79c96ae8188caf0ee Mon Sep 17 00:00:00 2001 From: Frank Jogeleit Date: Fri, 20 Jan 2023 13:14:03 +0100 Subject: [PATCH 2/3] add apis to list policy-report information Signed-off-by: Frank Jogeleit --- pkg/api/gzip.go | 3 +-- pkg/api/v1/handler.go | 2 +- pkg/crd/client/informers/externalversions/generic.go | 2 +- pkg/kubernetes/policy_report_client.go | 2 +- pkg/kubernetes/secrets/client.go | 4 ++-- pkg/report/client.go | 2 +- pkg/report/publisher.go | 2 +- pkg/report/store.go | 2 +- pkg/sqlite3/store.go | 4 ---- 9 files changed, 9 insertions(+), 14 deletions(-) diff --git a/pkg/api/gzip.go b/pkg/api/gzip.go index f567fd18..348d9166 100644 --- a/pkg/api/gzip.go +++ b/pkg/api/gzip.go @@ -3,7 +3,6 @@ package api import ( "compress/gzip" "io" - "io/ioutil" "net/http" "strings" "sync" @@ -11,7 +10,7 @@ import ( var gzPool = sync.Pool{ New: func() interface{} { - w := gzip.NewWriter(ioutil.Discard) + w := gzip.NewWriter(io.Discard) return w }, } diff --git a/pkg/api/v1/handler.go b/pkg/api/v1/handler.go index 5ac2d1b8..bdbd3394 100644 --- a/pkg/api/v1/handler.go +++ b/pkg/api/v1/handler.go @@ -67,7 +67,7 @@ func NamespacedResourcesPolicyListHandler(finder PolicyReportFinder) http.Handle } } -// NamespacedResourcesPolicyListHandler REST API +// NamespacedResourcesRuleListHandler REST API func NamespacedResourcesRuleListHandler(finder PolicyReportFinder) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { list, err := finder.FetchNamespacedRules(buildFilter(req)) diff --git a/pkg/crd/client/informers/externalversions/generic.go b/pkg/crd/client/informers/externalversions/generic.go index caedaca8..fe28164f 100644 --- a/pkg/crd/client/informers/externalversions/generic.go +++ b/pkg/crd/client/informers/externalversions/generic.go @@ -52,7 +52,7 @@ func (f *genericInformer) Lister() cache.GenericLister { // TODO extend this to unknown resources with a client pool func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { switch resource { - // Group=wgpolicyk8s.io, Version=v1alpha2 + // Group=wgpolicyk8s.io, Version=v1alpha2 case policyreportv1alpha2.SchemeGroupVersion.WithResource("clusterpolicyreports"): return &genericInformer{resource: resource.GroupResource(), informer: f.Wgpolicyk8s().V1alpha2().ClusterPolicyReports().Informer()}, nil case policyreportv1alpha2.SchemeGroupVersion.WithResource("policyreports"): diff --git a/pkg/kubernetes/policy_report_client.go b/pkg/kubernetes/policy_report_client.go index 41b6785f..06d1af36 100644 --- a/pkg/kubernetes/policy_report_client.go +++ b/pkg/kubernetes/policy_report_client.go @@ -136,7 +136,7 @@ func (k *k8sPolicyReportClient) configureClusterPolicyReport() cache.SharedIndex return cpolrInformer } -// NewPolicyReportAdapter new Adapter for Policy Report Kubernetes API +// NewPolicyReportClient new Client for Policy Report Kubernetes API func NewPolicyReportClient(client versioned.Interface, mapper Mapper, reportFilter *report.Filter, publisher report.EventPublisher) report.PolicyReportClient { fatcory := externalversions.NewSharedInformerFactory(client, time.Hour) v1alpha2 := fatcory.Wgpolicyk8s().V1alpha2() diff --git a/pkg/kubernetes/secrets/client.go b/pkg/kubernetes/secrets/client.go index 1f05f7e2..2a0ed127 100644 --- a/pkg/kubernetes/secrets/client.go +++ b/pkg/kubernetes/secrets/client.go @@ -27,11 +27,11 @@ type k8sClient struct { func (c *k8sClient) Get(ctx context.Context, name string) (Values, error) { secret, err := c.client.Get(ctx, name, metav1.GetOptions{}) + values := Values{} if err != nil { - return Values{}, err + return values, err } - values := Values{} if host, ok := secret.Data["host"]; ok { values.Host = string(host) } diff --git a/pkg/report/client.go b/pkg/report/client.go index 9849a2c7..4e570762 100644 --- a/pkg/report/client.go +++ b/pkg/report/client.go @@ -8,7 +8,7 @@ type PolicyReportResultListener = func(PolicyReport, Result, bool) // PolicyReportClient watches for PolicyReport Events and executes registered callback type PolicyReportClient interface { - // WatchPolicyReports starts to watch for PolicyReport LifecycleEvent events + // Run WatchPolicyReports starts to watch for PolicyReport LifecycleEvent events Run(stopper chan struct{}) error // HasSynced the configured PolicyReport HasSynced() bool diff --git a/pkg/report/publisher.go b/pkg/report/publisher.go index c1f80d17..ef6fcfc6 100644 --- a/pkg/report/publisher.go +++ b/pkg/report/publisher.go @@ -11,7 +11,7 @@ type EventPublisher interface { UnregisterListener(string) // GetListener returns a list of all registered Listeners GetListener() map[string]PolicyReportListener - // Process LifecycleEvent with all registered listeners + // Publish Process LifecycleEvent with all registered listeners Publish(event LifecycleEvent) } diff --git a/pkg/report/store.go b/pkg/report/store.go index 7a651c60..3dbe8d45 100644 --- a/pkg/report/store.go +++ b/pkg/report/store.go @@ -9,7 +9,7 @@ type PolicyReportStore interface { Get(id string) (PolicyReport, bool) // Add a PolicyReport to the Store Add(r PolicyReport) error - // Add a PolicyReport to the Store + // Update a PolicyReport to the Store Update(r PolicyReport) error // Remove a PolicyReport with the given Type and ID from the Store Remove(id string) error diff --git a/pkg/sqlite3/store.go b/pkg/sqlite3/store.go index 969a94d6..a5e17bb1 100644 --- a/pkg/sqlite3/store.go +++ b/pkg/sqlite3/store.go @@ -232,10 +232,6 @@ func (s *policyReportStore) FetchPolicyReports(filter api.Filter, pagination api var list = make([]*api.PolicyReport, 0) - query := `SELECT id, namespace, name, labels, pass, skip, warn, fail, error FROM policy_report WHERE ` + where + " " + paginationString - - fmt.Println(query) - rows, err := s.db.Query(`SELECT id, namespace, name, labels, pass, skip, warn, fail, error FROM policy_report WHERE `+where+" "+paginationString, args...) if err != nil { return list, err From a65570dd6bff4ead6777e50ca410b9476986452d Mon Sep 17 00:00:00 2001 From: Frank Jogeleit Date: Fri, 20 Jan 2023 13:24:17 +0100 Subject: [PATCH 3/3] add apis to list policy-report information Signed-off-by: Frank Jogeleit --- pkg/api/v1/handler.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/api/v1/handler.go b/pkg/api/v1/handler.go index bdbd3394..9c1ff0b5 100644 --- a/pkg/api/v1/handler.go +++ b/pkg/api/v1/handler.go @@ -27,7 +27,7 @@ func TargetsHandler(targets []target.Client) http.HandlerFunc { func PolicyReportListHandler(finder PolicyReportFinder) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { filter := buildFilter(req) - count, err := finder.CountPolicyReports(filter) + count, _ := finder.CountPolicyReports(filter) list, err := finder.FetchPolicyReports(filter, buildPaginatiomn(req, []string{"namespace", "name"})) helper.SendJSONResponse(w, PolicyReportList{Items: list, Count: count}, err) } @@ -37,7 +37,7 @@ func PolicyReportListHandler(finder PolicyReportFinder) http.HandlerFunc { func ClusterPolicyReportListHandler(finder PolicyReportFinder) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { filter := buildFilter(req) - count, err := finder.CountClusterPolicyReports(filter) + count, _ := finder.CountClusterPolicyReports(filter) list, err := finder.FetchClusterPolicyReports(filter, buildPaginatiomn(req, []string{"namespace", "name"})) helper.SendJSONResponse(w, PolicyReportList{Items: list, Count: count}, err) } @@ -178,7 +178,7 @@ func RuleStatusCountHandler(finder PolicyReportFinder) http.HandlerFunc { func NamespacedResourcesResultHandler(finder PolicyReportFinder) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { filter := buildFilter(req) - count, err := finder.CountNamespacedResults(filter) + count, _ := finder.CountNamespacedResults(filter) list, err := finder.FetchNamespacedResults(filter, buildPaginatiomn(req, defaultOrder)) helper.SendJSONResponse(w, ResultList{Items: list, Count: count}, err) } @@ -188,7 +188,7 @@ func NamespacedResourcesResultHandler(finder PolicyReportFinder) http.HandlerFun func ClusterResourcesResultHandler(finder PolicyReportFinder) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { filter := buildFilter(req) - count, err := finder.CountClusterResults(filter) + count, _ := finder.CountClusterResults(filter) list, err := finder.FetchClusterResults(filter, buildPaginatiomn(req, defaultOrder)) helper.SendJSONResponse(w, ResultList{Items: list, Count: count}, err) }