Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

observe: traffic direction filter #976

Merged
merged 2 commits into from
Apr 14, 2023
Merged
Show file tree
Hide file tree
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
6 changes: 6 additions & 0 deletions cmd/observe/flows.go
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,9 @@ func newFlowsCmdHelper(usage cmdUsage, vp *viper.Viper, ofilter *flowFilter) *co
filterFlags.Var(filterVar(
"to-identity", ofilter,
"Show all flows terminating at an endpoint with the given security identity"))
filterFlags.Var(filterVar(
"traffic-direction", ofilter,
"Show all flows in the given traffic direction (either ingress or egress)"))
chancez marked this conversation as resolved.
Show resolved Hide resolved

rawFilterFlags := pflag.NewFlagSet("raw-filters", pflag.ContinueOnError)
rawFilterFlags.StringArray(allowlistFlag, []string{}, "Specify allowlist as JSON encoded FlowFilters")
Expand Down Expand Up @@ -504,6 +507,9 @@ func newFlowsCmdHelper(usage cmdUsage, vp *viper.Viper, ofilter *flowFilter) *co
flowsCmd.RegisterFlagCompletionFunc("from-identity", func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
return reservedIdentitiesNames(), cobra.ShellCompDirectiveDefault
})
flowsCmd.RegisterFlagCompletionFunc("traffic-direction", func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
return []string{"ingress", "egress"}, cobra.ShellCompDirectiveDefault
})
flowsCmd.RegisterFlagCompletionFunc("output", func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
return []string{
"compact",
Expand Down
16 changes: 16 additions & 0 deletions cmd/observe/flows_filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ func newFlowFilter() *flowFilter {
{"node-name"},
{"tcp-flags"},
{"uuid"},
{"traffic-direction"},
},
}
}
Expand Down Expand Up @@ -555,6 +556,21 @@ func (of *flowFilter) set(f *filterTracker, name, val string, track bool) error
f.apply(func(f *flowpb.FlowFilter) {
f.TcpFlags = append(f.TcpFlags, flags)
})

// traffic direction filter
case "traffic-direction":
switch td := strings.ToLower(val); td {
case "ingress":
f.apply(func(f *flowpb.FlowFilter) {
f.TrafficDirection = append(f.TrafficDirection, flowpb.TrafficDirection_INGRESS)
})
case "egress":
f.apply(func(f *flowpb.FlowFilter) {
f.TrafficDirection = append(f.TrafficDirection, flowpb.TrafficDirection_EGRESS)
})
default:
return fmt.Errorf("%s: invalid traffic direction, expected ingress or egress", td)
}
}

return nil
Expand Down
59 changes: 59 additions & 0 deletions cmd/observe/flows_filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -433,3 +433,62 @@ func TestUuid(t *testing.T) {
}
assert.Nil(t, f.blacklist)
}

func TestTrafficDirection(t *testing.T) {
tt := []struct {
name string
flags []string
filters []*flowpb.FlowFilter
err string
}{
{
name: "ingress",
flags: []string{"--traffic-direction", "ingress"},
filters: []*flowpb.FlowFilter{
{TrafficDirection: []flowpb.TrafficDirection{flowpb.TrafficDirection_INGRESS}},
},
},
{
name: "egress",
flags: []string{"--traffic-direction", "egress"},
filters: []*flowpb.FlowFilter{
{TrafficDirection: []flowpb.TrafficDirection{flowpb.TrafficDirection_EGRESS}},
},
},
{
name: "mixed case",
flags: []string{"--traffic-direction", "INGRESS", "--traffic-direction", "EgrEss"},
filters: []*flowpb.FlowFilter{
{
TrafficDirection: []flowpb.TrafficDirection{
flowpb.TrafficDirection_INGRESS,
flowpb.TrafficDirection_EGRESS,
},
},
},
},
{
name: "invalid",
flags: []string{"--traffic-direction", "to the moon"},
err: "to the moon: invalid traffic direction, expected ingress or egress",
},
}

for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
f := newFlowFilter()
cmd := newFlowsCmdWithFilter(viper.New(), f)
err := cmd.Flags().Parse(tc.flags)
diff := cmp.Diff(tc.filters, f.whitelist.flowFilters(), cmpopts.IgnoreUnexported(flowpb.FlowFilter{}))
if diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}
if tc.err != "" {
assert.Errorf(t, err, tc.err)
} else {
assert.NoError(t, err)
}
assert.Nil(t, f.blacklist)
})
}
}
119 changes: 60 additions & 59 deletions cmd/observe_help.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,65 +38,66 @@ Selectors Flags:


Filters Flags:
--fqdn filter Show all flows related to the given fully qualified domain name (e.g. "*.cilium.io").
--from-fqdn filter Show all flows originating at the given fully qualified domain name (e.g. "*.cilium.io").
--from-identity filter Show all flows originating at an endpoint with the given security identity
--from-ip filter Show all flows originating at the given IP address. Each of the source IPs can be specified as an exact match (e.g. '1.1.1.1') or as a CIDR range (e.g.'1.1.1.0/24').
--from-label filter Show only flows originating in an endpoint with the given labels (e.g. "key1=value1", "reserved:world")
--from-namespace filter Show all flows originating in the given Kubernetes namespace.
--from-pod filter Show all flows originating in the given pod name prefix([namespace/]<pod-name>). If namespace is not provided, 'default' is used
--from-port filter Show only flows with the given source port (e.g. 8080)
--from-service filter Shows flows where the source IP address matches the ClusterIP address of the given service name prefix([namespace/]<svc-name>). If namespace is not provided, 'default' is used
--from-workload filter Show all flows originating at an endpoint with the given workload
--http-method filter Show only flows which match this HTTP method (e.g. "get", "post")
--http-path filter Show only flows which match this HTTP path regular expressions (e.g. "/page/\\d+")
--http-status filter Show only flows which match this HTTP status code prefix (e.g. "404", "5+")
--identity filter Show all flows related to an endpoint with the given security identity
--ip filter Show all flows related to the given IP address. Each of the IPs can be specified as an exact match (e.g. '1.1.1.1') or as a CIDR range (e.g.'1.1.1.0/24').
--ip-version filter Show only IPv4, IPv6 flows or non IP flows (e.g. ARP packets) (ie: "none", "v4", "v6")
-4, --ipv4 filter[=v4] Show only IPv4 flows
-6, --ipv6 filter[=v6] Show only IPv6 flows
-l, --label filter Show only flows related to an endpoint with the given labels (e.g. "key1=value1", "reserved:world")
-n, --namespace filter Show all flows related to the given Kubernetes namespace.
--node-name filter Show all flows which match the given node names (e.g. "k8s*", "test-cluster/*.company.com")
--not filter[=true] Reverses the next filter to be blacklist i.e. --not --from-ip 2.2.2.2
--pod filter Show all flows related to the given pod name prefix ([namespace/]<pod-name>). If namespace is not provided, 'default' is used.
--port filter Show only flows with given port in either source or destination (e.g. 8080)
--protocol filter Show only flows which match the given L4/L7 flow protocol (e.g. "udp", "http")
--service filter Shows flows where either the source or destination IP address matches the ClusterIP address of the given service name prefix ([namespace/]<svc-name>). If namespace is not provided, 'default' is used.
--tcp-flags filter Show only flows which match the given TCP flags (e.g. "syn", "ack", "fin")
--to-fqdn filter Show all flows terminating at the given fully qualified domain name (e.g. "*.cilium.io").
--to-identity filter Show all flows terminating at an endpoint with the given security identity
--to-ip filter Show all flows terminating at the given IP address. Each of the destination IPs can be specified as an exact match (e.g. '1.1.1.1') or as a CIDR range (e.g.'1.1.1.0/24').
--to-label filter Show only flows terminating in an endpoint with given labels (e.g. "key1=value1", "reserved:world")
--to-namespace filter Show all flows terminating in the given Kubernetes namespace.
--to-pod filter Show all flows terminating in the given pod name prefix([namespace/]<pod-name>). If namespace is not provided, 'default' is used
--to-port filter Show only flows with the given destination port (e.g. 8080)
--to-service filter Shows flows where the destination IP address matches the ClusterIP address of the given service name prefix ([namespace/]<svc-name>). If namespace is not provided, 'default' is used
--to-workload filter Show all flows terminating at an endpoint with the given workload
--trace-id filter Show only flows which match this trace ID
-t, --type filter Filter by event types TYPE[:SUBTYPE]. Available types and subtypes:
TYPE SUBTYPE
capture n/a
drop n/a
l7 n/a
policy-verdict n/a
trace from-endpoint
from-host
from-network
from-overlay
from-proxy
from-stack
to-endpoint
to-host
to-network
to-overlay
to-proxy
to-stack
trace-sock n/a
--uuid filter Show the only flow matching this unique flow identifier, if any
--verdict filter Show only flows with this verdict [FORWARDED, DROPPED, AUDIT, REDIRECTED, ERROR, TRACED, TRANSLATED]
--workload filter Show all flows related to an endpoint with the given workload
--fqdn filter Show all flows related to the given fully qualified domain name (e.g. "*.cilium.io").
--from-fqdn filter Show all flows originating at the given fully qualified domain name (e.g. "*.cilium.io").
--from-identity filter Show all flows originating at an endpoint with the given security identity
--from-ip filter Show all flows originating at the given IP address. Each of the source IPs can be specified as an exact match (e.g. '1.1.1.1') or as a CIDR range (e.g.'1.1.1.0/24').
--from-label filter Show only flows originating in an endpoint with the given labels (e.g. "key1=value1", "reserved:world")
--from-namespace filter Show all flows originating in the given Kubernetes namespace.
--from-pod filter Show all flows originating in the given pod name prefix([namespace/]<pod-name>). If namespace is not provided, 'default' is used
--from-port filter Show only flows with the given source port (e.g. 8080)
--from-service filter Shows flows where the source IP address matches the ClusterIP address of the given service name prefix([namespace/]<svc-name>). If namespace is not provided, 'default' is used
--from-workload filter Show all flows originating at an endpoint with the given workload
--http-method filter Show only flows which match this HTTP method (e.g. "get", "post")
--http-path filter Show only flows which match this HTTP path regular expressions (e.g. "/page/\\d+")
--http-status filter Show only flows which match this HTTP status code prefix (e.g. "404", "5+")
--identity filter Show all flows related to an endpoint with the given security identity
--ip filter Show all flows related to the given IP address. Each of the IPs can be specified as an exact match (e.g. '1.1.1.1') or as a CIDR range (e.g.'1.1.1.0/24').
--ip-version filter Show only IPv4, IPv6 flows or non IP flows (e.g. ARP packets) (ie: "none", "v4", "v6")
-4, --ipv4 filter[=v4] Show only IPv4 flows
-6, --ipv6 filter[=v6] Show only IPv6 flows
-l, --label filter Show only flows related to an endpoint with the given labels (e.g. "key1=value1", "reserved:world")
-n, --namespace filter Show all flows related to the given Kubernetes namespace.
--node-name filter Show all flows which match the given node names (e.g. "k8s*", "test-cluster/*.company.com")
--not filter[=true] Reverses the next filter to be blacklist i.e. --not --from-ip 2.2.2.2
--pod filter Show all flows related to the given pod name prefix ([namespace/]<pod-name>). If namespace is not provided, 'default' is used.
--port filter Show only flows with given port in either source or destination (e.g. 8080)
--protocol filter Show only flows which match the given L4/L7 flow protocol (e.g. "udp", "http")
--service filter Shows flows where either the source or destination IP address matches the ClusterIP address of the given service name prefix ([namespace/]<svc-name>). If namespace is not provided, 'default' is used.
--tcp-flags filter Show only flows which match the given TCP flags (e.g. "syn", "ack", "fin")
--to-fqdn filter Show all flows terminating at the given fully qualified domain name (e.g. "*.cilium.io").
--to-identity filter Show all flows terminating at an endpoint with the given security identity
--to-ip filter Show all flows terminating at the given IP address. Each of the destination IPs can be specified as an exact match (e.g. '1.1.1.1') or as a CIDR range (e.g.'1.1.1.0/24').
--to-label filter Show only flows terminating in an endpoint with given labels (e.g. "key1=value1", "reserved:world")
--to-namespace filter Show all flows terminating in the given Kubernetes namespace.
--to-pod filter Show all flows terminating in the given pod name prefix([namespace/]<pod-name>). If namespace is not provided, 'default' is used
--to-port filter Show only flows with the given destination port (e.g. 8080)
--to-service filter Shows flows where the destination IP address matches the ClusterIP address of the given service name prefix ([namespace/]<svc-name>). If namespace is not provided, 'default' is used
--to-workload filter Show all flows terminating at an endpoint with the given workload
--trace-id filter Show only flows which match this trace ID
--traffic-direction filter Show all flows in the given traffic direction (either ingress or egress)
-t, --type filter Filter by event types TYPE[:SUBTYPE]. Available types and subtypes:
TYPE SUBTYPE
capture n/a
drop n/a
l7 n/a
policy-verdict n/a
trace from-endpoint
from-host
from-network
from-overlay
from-proxy
from-stack
to-endpoint
to-host
to-network
to-overlay
to-proxy
to-stack
trace-sock n/a
--uuid filter Show the only flow matching this unique flow identifier, if any
--verdict filter Show only flows with this verdict [FORWARDED, DROPPED, AUDIT, REDIRECTED, ERROR, TRACED, TRANSLATED]
--workload filter Show all flows related to an endpoint with the given workload

Raw-Filters Flags:
--allowlist stringArray Specify allowlist as JSON encoded FlowFilters
Expand Down
20 changes: 10 additions & 10 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/cilium/hubble
go 1.20

require (
github.com/cilium/cilium v1.14.0-snapshot.0
github.com/cilium/cilium v1.14.0-snapshot.1
github.com/fatih/color v1.15.0
github.com/google/go-cmp v0.5.9
github.com/sirupsen/logrus v1.9.0
Expand Down Expand Up @@ -35,11 +35,11 @@ require (
github.com/go-openapi/loads v0.21.2 // indirect
github.com/go-openapi/runtime v0.25.0 // indirect
github.com/go-openapi/spec v0.20.8 // indirect
github.com/go-openapi/strfmt v0.21.3 // indirect
github.com/go-openapi/strfmt v0.21.5 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/go-openapi/validate v0.22.0 // indirect
github.com/go-openapi/validate v0.22.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
Expand All @@ -65,24 +65,24 @@ require (
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/sasha-s/go-deadlock v0.3.1 // indirect
github.com/shirou/gopsutil/v3 v3.23.1 // indirect
github.com/shirou/gopsutil/v3 v3.23.2 // indirect
github.com/spf13/afero v1.9.3 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
github.com/tklauser/go-sysconf v0.3.11 // indirect
github.com/tklauser/numcpus v0.6.0 // indirect
github.com/vishvananda/netlink v1.2.1-beta.2.0.20220608195807-1a118fe229fc // indirect
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
github.com/vishvananda/netns v0.0.4 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
go.mongodb.org/mongo-driver v1.10.0 // indirect
go.opentelemetry.io/otel v1.12.0 // indirect
go.opentelemetry.io/otel/trace v1.12.0 // indirect
golang.org/x/exp v0.0.0-20221106115401-f9659909a136 // indirect
go.opentelemetry.io/otel v1.14.0 // indirect
go.opentelemetry.io/otel/trace v1.14.0 // indirect
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/time v0.3.0 // indirect
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect
google.golang.org/genproto v0.0.0-20230330200707-38013875ee22 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
Loading