Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 48 additions & 1 deletion internal/model/filters.go
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should name this flag --object-pattern and --exclude-object-pattern. There is an existing flag --objects and that is too close to --object.

Can you also update site/content/userguide/usage/commands.md and internal/commands/show.go?

Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package model

import (
"fmt"
"regexp"

"github.com/pkg/errors"
"github.com/spf13/pflag"
Expand All @@ -31,6 +32,8 @@ type Namespaced interface {
type Filters struct {
includes []string
excludes []string
regexpObjectIncludes []*regexp.Regexp
regexpObjectExcludes []*regexp.Regexp
excludeClusterObjects bool
kindFilter Filter
componentFilter Filter
Expand All @@ -39,11 +42,13 @@ type Filters struct {

// NewFilters sets up options in the supplied flags and returns a function to return filters.
func NewFilters(flags *pflag.FlagSet, includeAllFilters bool) func() (Filters, error) {
var includes, excludes, kindIncludes, kindExcludes, nsIncludes, nsExcludes []string
var includes, excludes, kindIncludes, kindExcludes, nsIncludes, nsExcludes, regexpObjectIncludes, regexpObjectExcludes []string
var includeClusterScopedObjects bool

flags.StringArrayVarP(&includes, "component", "c", nil, "include just this component")
flags.StringArrayVarP(&excludes, "exclude-component", "C", nil, "exclude this component")
flags.StringArrayVarP(&regexpObjectIncludes, "object", "t", nil, "include k8s components matching this regexp")
flags.StringArrayVarP(&regexpObjectExcludes, "exclude-object", "T", nil, "exclude k8s components matching this regexp")
if includeAllFilters {
flags.StringArrayVarP(&kindIncludes, "kind", "k", nil, "include objects with this kind")
flags.StringArrayVarP(&kindExcludes, "exclude-kind", "K", nil, "exclude objects with this kind")
Expand All @@ -69,9 +74,30 @@ func NewFilters(flags *pflag.FlagSet, includeAllFilters bool) func() (Filters, e
includeClusterScopedObjects = false
}
}

regexpIncludes := make([]*regexp.Regexp, 0, len(regexpObjectIncludes))
regexpExcludes := make([]*regexp.Regexp, 0, len(regexpObjectExcludes))
for _, re := range regexpObjectIncludes {
compiled, err := regexp.Compile(fmt.Sprintf(`(?i)^%s$`, re))
if err != nil {
return Filters{}, errors.Wrapf(err, "invalid --object regexp %q", re)
}
regexpIncludes = append(regexpIncludes, compiled)
}

for _, re := range regexpObjectExcludes {
compiled, err := regexp.Compile(fmt.Sprintf(`(?i)^%s$`, re))
if err != nil {
return Filters{}, errors.Wrapf(err, "invalid --exclude-object regexp %q", re)
}
regexpExcludes = append(regexpExcludes, compiled)
}

return Filters{
includes: includes,
excludes: excludes,
regexpObjectIncludes: regexpIncludes,
regexpObjectExcludes: regexpExcludes,
kindFilter: of,
componentFilter: cf,
namespaceFilter: nf,
Expand All @@ -95,6 +121,24 @@ func (f Filters) GVKFilter(gvk schema.GroupVersionKind) bool {
return f.kindFilter != nil && f.kindFilter.ShouldInclude(gvk.Kind)
}

// ObjectFilter returns true if the name matches all include regexes and does not match all exclude regexes
// This code was inspired and adapted from grafana tanka
// https://github.com/grafana/tanka/blob/a6a63ac17f713d5fd64bb6d7972bc84c6b5902a6/pkg/process/filter.go#L74
func (f Filters) ObjectFilter(object K8sQbecMeta) bool {
kindName := object.GetKind() + "/" + object.GetName()
for _, re := range f.regexpObjectIncludes {
if !re.MatchString(kindName) {
return false
}
}
for _, re := range f.regexpObjectExcludes {
if re.MatchString(kindName) {
return false
}
}
return true
}

// HasNamespaceFilters returns true if filters based on namespace scope are in effect.
func (f Filters) HasNamespaceFilters() bool {
return (f.namespaceFilter != nil && f.namespaceFilter.HasFilters()) || f.excludeClusterObjects
Expand All @@ -103,6 +147,9 @@ func (f Filters) HasNamespaceFilters() bool {
// Match returns true if the current filters match the supplied object. The client can be nil
// if namespace scope filters are not in effect.
func (f Filters) Match(o K8sQbecMeta, client Namespaced, defaultNS string) (bool, error) {
if !f.ObjectFilter(o) {
return false, nil
}
if f.HasNamespaceFilters() && client == nil {
return false, fmt.Errorf("no namespace metadata when namespace filters present")
}
Expand Down
Loading