github.com/cilium/cilium@v1.16.2/pkg/hubble/metrics/policy/handler.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package policy 5 6 import ( 7 "context" 8 "fmt" 9 "strings" 10 11 "github.com/prometheus/client_golang/prometheus" 12 13 flowpb "github.com/cilium/cilium/api/v1/flow" 14 "github.com/cilium/cilium/pkg/hubble/metrics/api" 15 "github.com/cilium/cilium/pkg/identity" 16 monitorAPI "github.com/cilium/cilium/pkg/monitor/api" 17 ) 18 19 type policyHandler struct { 20 verdicts *prometheus.CounterVec 21 context *api.ContextOptions 22 } 23 24 func (d *policyHandler) Init(registry *prometheus.Registry, options api.Options) error { 25 c, err := api.ParseContextOptions(options) 26 if err != nil { 27 return err 28 } 29 d.context = c 30 31 labels := []string{"direction", "match", "action"} 32 labels = append(labels, d.context.GetLabelNames()...) 33 34 d.verdicts = prometheus.NewCounterVec(prometheus.CounterOpts{ 35 Namespace: api.DefaultPrometheusNamespace, 36 Name: "policy_verdicts_total", 37 Help: "Total number of Cilium network policy verdicts", 38 }, labels) 39 40 registry.MustRegister(d.verdicts) 41 return nil 42 } 43 44 func (d *policyHandler) Status() string { 45 return d.context.Status() 46 } 47 48 func (d *policyHandler) Context() *api.ContextOptions { 49 return d.context 50 } 51 52 func (d *policyHandler) ListMetricVec() []*prometheus.MetricVec { 53 return []*prometheus.MetricVec{d.verdicts.MetricVec} 54 } 55 56 func (d *policyHandler) ProcessFlow(ctx context.Context, flow *flowpb.Flow) error { 57 if flow.GetEventType().GetType() == monitorAPI.MessageTypePolicyVerdict { 58 return d.ProcessFlowL3L4(ctx, flow) 59 } 60 61 if flow.GetEventType().GetType() == monitorAPI.MessageTypeAccessLog { 62 return d.ProcessFlowL7(ctx, flow) 63 } 64 65 return nil 66 } 67 68 func (d *policyHandler) ProcessFlowL3L4(ctx context.Context, flow *flowpb.Flow) error { 69 // ignore verdict if the source is host since host is allowed to connect to any local endpoints. 70 if flow.GetSource().GetIdentity() == uint32(identity.ReservedIdentityHost) { 71 return nil 72 } 73 labelValues, err := d.context.GetLabelValues(flow) 74 if err != nil { 75 return err 76 } 77 78 direction := strings.ToLower(flow.GetTrafficDirection().String()) 79 match := strings.ToLower(monitorAPI.PolicyMatchType(flow.GetPolicyMatchType()).String()) 80 action := strings.ToLower(flow.Verdict.String()) 81 labels := []string{direction, match, action} 82 labels = append(labels, labelValues...) 83 84 d.verdicts.WithLabelValues(labels...).Inc() 85 return nil 86 } 87 88 func (d *policyHandler) ProcessFlowL7(ctx context.Context, flow *flowpb.Flow) error { 89 labelValues, err := d.context.GetLabelValues(flow) 90 if err != nil { 91 return err 92 } 93 94 direction := strings.ToLower(flow.GetTrafficDirection().String()) 95 var subType string 96 if l7 := flow.GetL7(); l7 != nil { 97 switch { 98 case l7.GetDns() != nil: 99 subType = "dns" 100 case l7.GetHttp() != nil: 101 subType = "http" 102 case l7.GetKafka() != nil: 103 subType = "kafka" 104 } 105 } 106 match := fmt.Sprintf("l7/%s", subType) 107 action := strings.ToLower(flow.Verdict.String()) 108 labels := []string{direction, match, action} 109 labels = append(labels, labelValues...) 110 111 d.verdicts.WithLabelValues(labels...).Inc() 112 return nil 113 }