Skip to content

Commit

Permalink
Support Selector for target namespace filter
Browse files Browse the repository at this point in the history
Signed-off-by: Frank Jogeleit <frank.jogeleit@lovoo.com>
  • Loading branch information
Frank Jogeleit committed Mar 7, 2024
1 parent 3e3dc4b commit 62979d4
Show file tree
Hide file tree
Showing 11 changed files with 223 additions and 122 deletions.
2 changes: 1 addition & 1 deletion cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func newRunCMD(version string) *cobra.Command {
return err
}

nsClient, err := resolver.NamespceClient()
nsClient, err := resolver.NamespaceClient()
if err != nil {
return err
}
Expand Down
7 changes: 4 additions & 3 deletions pkg/api/v2/views.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,12 +344,13 @@ func MapResourceCategoryToSourceDetails(categories []db.ResourceCategory) []*Sou
}

type ValueFilter struct {
Include []string `json:"include,omitempty"`
Exclude []string `json:"exclude,omitempty"`
Include []string `json:"include,omitempty"`
Exclude []string `json:"exclude,omitempty"`
Selector map[string]string `json:"selector,omitempty"`
}

func (v ValueFilter) Empty() bool {
return len(v.Exclude)+len(v.Include) == 0
return len(v.Exclude)+len(v.Include)+len(v.Selector) == 0
}

type TargetFilter struct {
Expand Down
5 changes: 3 additions & 2 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package config

type ValueFilter struct {
Include []string `mapstructure:"include"`
Exclude []string `mapstructure:"exclude"`
Include []string `mapstructure:"include"`
Exclude []string `mapstructure:"exclude"`
Selector map[string]any `mapstructure:"selector"`
}

type EmailReportFilter struct {
Expand Down
9 changes: 6 additions & 3 deletions pkg/config/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ func (r *Resolver) SecretClient() secrets.Client {
}

// NamespaceClient resolver method
func (r *Resolver) NamespceClient() (namespaces.Client, error) {
func (r *Resolver) NamespaceClient() (namespaces.Client, error) {
clientset, err := r.Clientset()
if err != nil {
return nil, err
Expand All @@ -315,9 +315,12 @@ func (r *Resolver) NamespceClient() (namespaces.Client, error) {
}

func (r *Resolver) TargetFactory() *TargetFactory {
return &TargetFactory{
secretClient: r.SecretClient(),
ns, err := r.NamespaceClient()
if err != nil {
zap.L().Error("failed to create namespace client", zap.Error(err))
}

return NewTargetFactory(r.SecretClient(), target.NewResultFilterFactory(ns))
}

func (r *Resolver) DatabaseFactory() *DatabaseFactory {
Expand Down
214 changes: 140 additions & 74 deletions pkg/config/target_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ import (
"github.com/kyverno/policy-reporter/pkg/target/teams"
"github.com/kyverno/policy-reporter/pkg/target/telegram"
"github.com/kyverno/policy-reporter/pkg/target/webhook"
"github.com/kyverno/policy-reporter/pkg/validate"
)

// TargetFactory manages target creation
type TargetFactory struct {
secretClient secrets.Client
secretClient secrets.Client
filterFactory *target.ResultFilterFactory
}

// LokiClients resolver method
Expand Down Expand Up @@ -115,11 +117,16 @@ func (f *TargetFactory) createSlackClient(config, parent *Target[SlackOptions])
zap.S().Infof("%s configured", config.Name)

return slack.NewClient(slack.Options{
ClientOptions: config.ClientOptions(),
Webhook: config.Config.Webhook,
Channel: config.Config.Channel,
CustomFields: config.CustomFields,
HTTPClient: http.NewClient("", false),
ClientOptions: target.ClientOptions{
Name: config.Name,
SkipExistingOnStartup: config.SkipExisting,
ResultFilter: f.createResultFilter(config.Filter, config.MinimumPriority, config.Sources),
ReportFilter: createReportFilter(config.Filter),
},
Webhook: config.Config.Webhook,
Channel: config.Config.Channel,
CustomFields: config.CustomFields,
HTTPClient: http.NewClient("", false),
})
}

Expand Down Expand Up @@ -149,12 +156,17 @@ func (f *TargetFactory) createLokiClient(config, parent *Target[LokiOptions]) ta
zap.S().Infof("%s configured", config.Name)

return loki.NewClient(loki.Options{
ClientOptions: config.ClientOptions(),
Host: config.Config.Host + config.Config.Path,
CustomLabels: config.CustomFields,
Username: config.Config.Username,
Password: config.Config.Password,
HTTPClient: http.NewClient(config.Config.Certificate, config.Config.SkipTLS),
ClientOptions: target.ClientOptions{
Name: config.Name,
SkipExistingOnStartup: config.SkipExisting,
ResultFilter: f.createResultFilter(config.Filter, config.MinimumPriority, config.Sources),
ReportFilter: createReportFilter(config.Filter),
},
Host: config.Config.Host + config.Config.Path,
CustomLabels: config.CustomFields,
Username: config.Config.Username,
Password: config.Config.Password,
HTTPClient: http.NewClient(config.Config.Certificate, config.Config.SkipTLS),
})
}

Expand Down Expand Up @@ -186,16 +198,21 @@ func (f *TargetFactory) createElasticsearchClient(config, parent *Target[Elastic
zap.S().Infof("%s configured", config.Name)

return elasticsearch.NewClient(elasticsearch.Options{
ClientOptions: config.ClientOptions(),
Host: config.Config.Host,
Username: config.Config.Username,
Password: config.Config.Password,
ApiKey: config.Config.APIKey,
Rotation: config.Config.Rotation,
Index: config.Config.Index,
TypelessApi: config.Config.TypelessApi,
CustomFields: config.CustomFields,
HTTPClient: http.NewClient(config.Config.Certificate, config.Config.SkipTLS),
ClientOptions: target.ClientOptions{
Name: config.Name,
SkipExistingOnStartup: config.SkipExisting,
ResultFilter: f.createResultFilter(config.Filter, config.MinimumPriority, config.Sources),
ReportFilter: createReportFilter(config.Filter),
},
Host: config.Config.Host,
Username: config.Config.Username,
Password: config.Config.Password,
ApiKey: config.Config.APIKey,
Rotation: config.Config.Rotation,
Index: config.Config.Index,
TypelessApi: config.Config.TypelessApi,
CustomFields: config.CustomFields,
HTTPClient: http.NewClient(config.Config.Certificate, config.Config.SkipTLS),
})
}

Expand All @@ -217,10 +234,15 @@ func (f *TargetFactory) createDiscordClient(config, parent *Target[WebhookOption
zap.S().Infof("%s configured", config.Name)

return discord.NewClient(discord.Options{
ClientOptions: config.ClientOptions(),
Webhook: config.Config.Webhook,
CustomFields: config.CustomFields,
HTTPClient: http.NewClient(config.Config.Certificate, config.Config.SkipTLS),
ClientOptions: target.ClientOptions{
Name: config.Name,
SkipExistingOnStartup: config.SkipExisting,
ResultFilter: f.createResultFilter(config.Filter, config.MinimumPriority, config.Sources),
ReportFilter: createReportFilter(config.Filter),
},
Webhook: config.Config.Webhook,
CustomFields: config.CustomFields,
HTTPClient: http.NewClient(config.Config.Certificate, config.Config.SkipTLS),
})
}

Expand All @@ -242,10 +264,15 @@ func (f *TargetFactory) createTeamsClient(config, parent *Target[WebhookOptions]
zap.S().Infof("%s configured", config.Name)

return teams.NewClient(teams.Options{
ClientOptions: config.ClientOptions(),
Webhook: config.Config.Webhook,
CustomFields: config.CustomFields,
HTTPClient: http.NewClient(config.Config.Certificate, config.Config.SkipTLS),
ClientOptions: target.ClientOptions{
Name: config.Name,
SkipExistingOnStartup: config.SkipExisting,
ResultFilter: f.createResultFilter(config.Filter, config.MinimumPriority, config.Sources),
ReportFilter: createReportFilter(config.Filter),
},
Webhook: config.Config.Webhook,
CustomFields: config.CustomFields,
HTTPClient: http.NewClient(config.Config.Certificate, config.Config.SkipTLS),
})
}

Expand All @@ -267,11 +294,16 @@ func (f *TargetFactory) createWebhookClient(config, parent *Target[WebhookOption
zap.S().Infof("%s configured", config.Name)

return webhook.NewClient(webhook.Options{
ClientOptions: config.ClientOptions(),
Host: config.Config.Webhook,
Headers: config.Config.Headers,
CustomFields: config.CustomFields,
HTTPClient: http.NewClient(config.Config.Certificate, config.Config.SkipTLS),
ClientOptions: target.ClientOptions{
Name: config.Name,
SkipExistingOnStartup: config.SkipExisting,
ResultFilter: f.createResultFilter(config.Filter, config.MinimumPriority, config.Sources),
ReportFilter: createReportFilter(config.Filter),
},
Host: config.Config.Webhook,
Headers: config.Config.Headers,
CustomFields: config.CustomFields,
HTTPClient: http.NewClient(config.Config.Certificate, config.Config.SkipTLS),
})
}

Expand Down Expand Up @@ -316,12 +348,17 @@ func (f *TargetFactory) createTelegramClient(config, parent *Target[TelegramOpti
zap.S().Infof("%s configured", config.Name)

return telegram.NewClient(telegram.Options{
ClientOptions: config.ClientOptions(),
Host: fmt.Sprintf("%s/bot%s/sendMessage", host, config.Config.Token),
ChatID: config.Config.ChatID,
Headers: config.Config.Headers,
CustomFields: config.CustomFields,
HTTPClient: http.NewClient(config.Config.Certificate, config.Config.SkipTLS),
ClientOptions: target.ClientOptions{
Name: config.Name,
SkipExistingOnStartup: config.SkipExisting,
ResultFilter: f.createResultFilter(config.Filter, config.MinimumPriority, config.Sources),
ReportFilter: createReportFilter(config.Filter),
},
Host: fmt.Sprintf("%s/bot%s/sendMessage", host, config.Config.Token),
ChatID: config.Config.ChatID,
Headers: config.Config.Headers,
CustomFields: config.CustomFields,
HTTPClient: http.NewClient(config.Config.Certificate, config.Config.SkipTLS),
})
}

Expand All @@ -343,11 +380,16 @@ func (f *TargetFactory) createGoogleChatClient(config, parent *Target[WebhookOpt
zap.S().Infof("%s configured", config.Name)

return googlechat.NewClient(googlechat.Options{
ClientOptions: config.ClientOptions(),
Webhook: config.Config.Webhook,
Headers: config.Config.Headers,
CustomFields: config.CustomFields,
HTTPClient: http.NewClient(config.Config.Certificate, config.Config.SkipTLS),
ClientOptions: target.ClientOptions{
Name: config.Name,
SkipExistingOnStartup: config.SkipExisting,
ResultFilter: f.createResultFilter(config.Filter, config.MinimumPriority, config.Sources),
ReportFilter: createReportFilter(config.Filter),
},
Webhook: config.Config.Webhook,
Headers: config.Config.Headers,
CustomFields: config.CustomFields,
HTTPClient: http.NewClient(config.Config.Certificate, config.Config.SkipTLS),
})
}

Expand Down Expand Up @@ -400,10 +442,15 @@ func (f *TargetFactory) createS3Client(config, parent *Target[S3Options]) target
sugar.Infof("%s configured", config.Name)

return s3.NewClient(s3.Options{
ClientOptions: config.ClientOptions(),
S3: s3Client,
CustomFields: config.CustomFields,
Prefix: config.Config.Prefix,
ClientOptions: target.ClientOptions{
Name: config.Name,
SkipExistingOnStartup: config.SkipExisting,
ResultFilter: f.createResultFilter(config.Filter, config.MinimumPriority, config.Sources),
ReportFilter: createReportFilter(config.Filter),
},
S3: s3Client,
CustomFields: config.CustomFields,
Prefix: config.Config.Prefix,
})
}

Expand Down Expand Up @@ -447,9 +494,14 @@ func (f *TargetFactory) createKinesisClient(config, parent *Target[KinesisOption
sugar.Infof("%s configured", config.Name)

return kinesis.NewClient(kinesis.Options{
ClientOptions: config.ClientOptions(),
CustomFields: config.CustomFields,
Kinesis: kinesisClient,
ClientOptions: target.ClientOptions{
Name: config.Name,
SkipExistingOnStartup: config.SkipExisting,
ResultFilter: f.createResultFilter(config.Filter, config.MinimumPriority, config.Sources),
ReportFilter: createReportFilter(config.Filter),
},
CustomFields: config.CustomFields,
Kinesis: kinesisClient,
})
}

Expand Down Expand Up @@ -487,11 +539,16 @@ func (f *TargetFactory) createSecurityHub(config, parent *Target[SecurityHubOpti
sugar.Infof("%s configured", config.Name)

return securityhub.NewClient(securityhub.Options{
ClientOptions: config.ClientOptions(),
CustomFields: config.CustomFields,
Client: client,
AccountID: config.Config.AccountID,
Region: config.Config.Region,
ClientOptions: target.ClientOptions{
Name: config.Name,
SkipExistingOnStartup: config.SkipExisting,
ResultFilter: f.createResultFilter(config.Filter, config.MinimumPriority, config.Sources),
ReportFilter: createReportFilter(config.Filter),
},
CustomFields: config.CustomFields,
Client: client,
AccountID: config.Config.AccountID,
Region: config.Config.Region,
})
}

Expand Down Expand Up @@ -533,13 +590,32 @@ func (f *TargetFactory) createGCSClient(config, parent *Target[GCSOptions]) targ
sugar.Infof("%s configured", config.Name)

return gcs.NewClient(gcs.Options{
ClientOptions: config.ClientOptions(),
Client: gcsClient,
CustomFields: config.CustomFields,
Prefix: config.Config.Prefix,
ClientOptions: target.ClientOptions{
Name: config.Name,
SkipExistingOnStartup: config.SkipExisting,
ResultFilter: f.createResultFilter(config.Filter, config.MinimumPriority, config.Sources),
ReportFilter: createReportFilter(config.Filter),
},
Client: gcsClient,
CustomFields: config.CustomFields,
Prefix: config.Config.Prefix,
})
}

func (f *TargetFactory) createResultFilter(filter TargetFilter, minimumPriority string, sources []string) *report.ResultFilter {
return f.filterFactory.CreateFilter(
validate.RuleSets{
Include: filter.Namespaces.Include,
Exclude: filter.Namespaces.Exclude,
Selector: helper.ConvertMap(filter.Namespaces.Selector),
},
ToRuleSet(filter.Priorities),
ToRuleSet(filter.Policies),
minimumPriority,
sources,
)
}

func (f *TargetFactory) mapSecretValues(config any, ref, mountedSecret string) {
values := secrets.Values{}

Expand Down Expand Up @@ -648,8 +724,8 @@ func (f *TargetFactory) mapSecretValues(config any, ref, mountedSecret string) {
}
}

func NewTargetFactory(secretClient secrets.Client) *TargetFactory {
return &TargetFactory{secretClient: secretClient}
func NewTargetFactory(secretClient secrets.Client, filterFactory *target.ResultFilterFactory) *TargetFactory {
return &TargetFactory{secretClient: secretClient, filterFactory: filterFactory}
}

func mapWebhookTarget(config, parent *Target[WebhookOptions]) {
Expand Down Expand Up @@ -714,16 +790,6 @@ func setBool(config *bool, parent bool) {
}
}

func createResultFilter(filter TargetFilter, minimumPriority string, sources []string) *report.ResultFilter {
return target.NewResultFilter(
ToRuleSet(filter.Namespaces),
ToRuleSet(filter.Priorities),
ToRuleSet(filter.Policies),
minimumPriority,
sources,
)
}

func createReportFilter(filter TargetFilter) *report.ReportFilter {
return target.NewReportFilter(
ToRuleSet(filter.ReportLabels),
Expand Down
Loading

0 comments on commit 62979d4

Please sign in to comment.