@@ -32,6 +32,7 @@ const (
32
32
equal = iota
33
33
regex
34
34
exist
35
+ shouldnotexist
35
36
testKubeConfig = "/tmp/kube-config-otelcol-e2e-testing"
36
37
uidRe = "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}"
37
38
startTimeRe = "^\\ \\ d{4}-\\ \\ d{2}-\\ \\ d{2}T\\ \\ d{2}%3A\\ \\ d{2}%3A\\ \\ d{2}(?:%2E\\ \\ d+)?[A-Z]?(?:[+.-](?:08%3A\\ \\ d{2}|\\ \\ d{2}[A-Z]))?$"
@@ -722,6 +723,146 @@ func TestE2E_MixRBAC(t *testing.T) {
722
723
}
723
724
}
724
725
726
+ // Test with `filter::namespace` set and only role binding to collector's SA. We can't get node and namespace labels/annotations.
727
+ // While `k8s.pod.ip` is not set in `k8sattributes:extract:metadata` and the `pod_association` is not `connection`
728
+ // we expect that the `k8s.pod.ip` metadata is not added.
729
+ func TestE2E_NamespacedRBACNoPodIP (t * testing.T ) {
730
+ testDir := filepath .Join ("testdata" , "e2e" , "namespacedrbacnopodip" )
731
+
732
+ k8sClient , err := k8stest .NewK8sClient (testKubeConfig )
733
+ require .NoError (t , err )
734
+
735
+ nsFile := filepath .Join (testDir , "namespace.yaml" )
736
+ buf , err := os .ReadFile (nsFile )
737
+ require .NoErrorf (t , err , "failed to read namespace object file %s" , nsFile )
738
+ nsObj , err := k8stest .CreateObject (k8sClient , buf )
739
+ require .NoErrorf (t , err , "failed to create k8s namespace from file %s" , nsFile )
740
+ nsName := nsObj .GetName ()
741
+ defer func () {
742
+ require .NoErrorf (t , k8stest .DeleteObject (k8sClient , nsObj ), "failed to delete namespace %s" , nsName )
743
+ }()
744
+
745
+ metricsConsumer := new (consumertest.MetricsSink )
746
+ tracesConsumer := new (consumertest.TracesSink )
747
+ logsConsumer := new (consumertest.LogsSink )
748
+ shutdownSinks := startUpSinks (t , metricsConsumer , tracesConsumer , logsConsumer )
749
+ defer shutdownSinks ()
750
+
751
+ testID := uuid .NewString ()[:8 ]
752
+ collectorObjs := k8stest .CreateCollectorObjects (t , k8sClient , testID , filepath .Join (testDir , "collector" ))
753
+ createTeleOpts := & k8stest.TelemetrygenCreateOpts {
754
+ ManifestsDir : filepath .Join (testDir , "telemetrygen" ),
755
+ TestID : testID ,
756
+ OtlpEndpoint : fmt .Sprintf ("otelcol-%s.%s:4317" , testID , nsName ),
757
+ DataTypes : []string {"metrics" , "logs" , "traces" },
758
+ }
759
+ telemetryGenObjs , telemetryGenObjInfos := k8stest .CreateTelemetryGenObjects (t , k8sClient , createTeleOpts )
760
+ defer func () {
761
+ for _ , obj := range append (collectorObjs , telemetryGenObjs ... ) {
762
+ require .NoErrorf (t , k8stest .DeleteObject (k8sClient , obj ), "failed to delete object %s" , obj .GetName ())
763
+ }
764
+ }()
765
+
766
+ for _ , info := range telemetryGenObjInfos {
767
+ k8stest .WaitForTelemetryGenToStart (t , k8sClient , info .Namespace , info .PodLabelSelectors , info .Workload , info .DataType )
768
+ }
769
+
770
+ wantEntries := 20 // Minimal number of metrics/traces/logs to wait for.
771
+ waitForData (t , wantEntries , metricsConsumer , tracesConsumer , logsConsumer )
772
+
773
+ tcs := []struct {
774
+ name string
775
+ dataType component.DataType
776
+ service string
777
+ attrs map [string ]* expectedValue
778
+ }{
779
+ {
780
+ name : "traces-deployment" ,
781
+ dataType : component .DataTypeTraces ,
782
+ service : "test-traces-deployment" ,
783
+ attrs : map [string ]* expectedValue {
784
+ "k8s.pod.name" : newExpectedValue (regex , "telemetrygen-" + testID + "-traces-deployment-[a-z0-9]*-[a-z0-9]*" ),
785
+ "k8s.pod.ip" : newExpectedValue (shouldnotexist , "" ),
786
+ "k8s.pod.uid" : newExpectedValue (regex , uidRe ),
787
+ "k8s.pod.start_time" : newExpectedValue (exist , startTimeRe ),
788
+ "k8s.node.name" : newExpectedValue (exist , "" ),
789
+ "k8s.namespace.name" : newExpectedValue (equal , nsName ),
790
+ "k8s.deployment.name" : newExpectedValue (equal , "telemetrygen-" + testID + "-traces-deployment" ),
791
+ "k8s.deployment.uid" : newExpectedValue (regex , uidRe ),
792
+ "k8s.replicaset.name" : newExpectedValue (regex , "telemetrygen-" + testID + "-traces-deployment-[a-z0-9]*" ),
793
+ "k8s.replicaset.uid" : newExpectedValue (regex , uidRe ),
794
+ "k8s.annotations.workload" : newExpectedValue (equal , "deployment" ),
795
+ "k8s.labels.app" : newExpectedValue (equal , "telemetrygen-" + testID + "-traces-deployment" ),
796
+ "k8s.container.name" : newExpectedValue (equal , "telemetrygen" ),
797
+ "container.image.name" : newExpectedValue (equal , "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen" ),
798
+ "container.image.tag" : newExpectedValue (equal , "latest" ),
799
+ "container.id" : newExpectedValue (exist , "" ),
800
+ },
801
+ },
802
+ {
803
+ name : "metrics-deployment" ,
804
+ dataType : component .DataTypeMetrics ,
805
+ service : "test-metrics-deployment" ,
806
+ attrs : map [string ]* expectedValue {
807
+ "k8s.pod.name" : newExpectedValue (regex , "telemetrygen-" + testID + "-metrics-deployment-[a-z0-9]*-[a-z0-9]*" ),
808
+ "k8s.pod.ip" : newExpectedValue (shouldnotexist , "" ),
809
+ "k8s.pod.uid" : newExpectedValue (regex , uidRe ),
810
+ "k8s.pod.start_time" : newExpectedValue (exist , startTimeRe ),
811
+ "k8s.node.name" : newExpectedValue (exist , "" ),
812
+ "k8s.namespace.name" : newExpectedValue (equal , nsName ),
813
+ "k8s.deployment.name" : newExpectedValue (equal , "telemetrygen-" + testID + "-metrics-deployment" ),
814
+ "k8s.deployment.uid" : newExpectedValue (regex , uidRe ),
815
+ "k8s.replicaset.name" : newExpectedValue (regex , "telemetrygen-" + testID + "-metrics-deployment-[a-z0-9]*" ),
816
+ "k8s.replicaset.uid" : newExpectedValue (regex , uidRe ),
817
+ "k8s.annotations.workload" : newExpectedValue (equal , "deployment" ),
818
+ "k8s.labels.app" : newExpectedValue (equal , "telemetrygen-" + testID + "-metrics-deployment" ),
819
+ "k8s.container.name" : newExpectedValue (equal , "telemetrygen" ),
820
+ "container.image.name" : newExpectedValue (equal , "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen" ),
821
+ "container.image.tag" : newExpectedValue (equal , "latest" ),
822
+ "container.id" : newExpectedValue (exist , "" ),
823
+ },
824
+ },
825
+ {
826
+ name : "logs-deployment" ,
827
+ dataType : component .DataTypeLogs ,
828
+ service : "test-logs-deployment" ,
829
+ attrs : map [string ]* expectedValue {
830
+ "k8s.pod.name" : newExpectedValue (regex , "telemetrygen-" + testID + "-logs-deployment-[a-z0-9]*-[a-z0-9]*" ),
831
+ "k8s.pod.ip" : newExpectedValue (shouldnotexist , "" ),
832
+ "k8s.pod.uid" : newExpectedValue (regex , uidRe ),
833
+ "k8s.pod.start_time" : newExpectedValue (exist , startTimeRe ),
834
+ "k8s.node.name" : newExpectedValue (exist , "" ),
835
+ "k8s.namespace.name" : newExpectedValue (equal , nsName ),
836
+ "k8s.deployment.name" : newExpectedValue (equal , "telemetrygen-" + testID + "-logs-deployment" ),
837
+ "k8s.deployment.uid" : newExpectedValue (regex , uidRe ),
838
+ "k8s.replicaset.name" : newExpectedValue (regex , "telemetrygen-" + testID + "-logs-deployment-[a-z0-9]*" ),
839
+ "k8s.replicaset.uid" : newExpectedValue (regex , uidRe ),
840
+ "k8s.annotations.workload" : newExpectedValue (equal , "deployment" ),
841
+ "k8s.labels.app" : newExpectedValue (equal , "telemetrygen-" + testID + "-logs-deployment" ),
842
+ "k8s.container.name" : newExpectedValue (equal , "telemetrygen" ),
843
+ "container.image.name" : newExpectedValue (equal , "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen" ),
844
+ "container.image.tag" : newExpectedValue (equal , "latest" ),
845
+ "container.id" : newExpectedValue (exist , "" ),
846
+ },
847
+ },
848
+ }
849
+
850
+ for _ , tc := range tcs {
851
+ t .Run (tc .name , func (t * testing.T ) {
852
+ switch tc .dataType {
853
+ case component .DataTypeTraces :
854
+ scanTracesForAttributes (t , tracesConsumer , tc .service , tc .attrs )
855
+ case component .DataTypeMetrics :
856
+ scanMetricsForAttributes (t , metricsConsumer , tc .service , tc .attrs )
857
+ case component .DataTypeLogs :
858
+ scanLogsForAttributes (t , logsConsumer , tc .service , tc .attrs )
859
+ default :
860
+ t .Fatalf ("unknown data type %s" , tc .dataType )
861
+ }
862
+ })
863
+ }
864
+ }
865
+
725
866
func scanTracesForAttributes (t * testing.T , ts * consumertest.TracesSink , expectedService string ,
726
867
kvs map [string ]* expectedValue ) {
727
868
// Iterate over the received set of traces starting from the most recent entries due to a bug in the processor:
@@ -787,8 +928,12 @@ func scanLogsForAttributes(t *testing.T, ls *consumertest.LogsSink, expectedServ
787
928
788
929
func resourceHasAttributes (resource pcommon.Resource , kvs map [string ]* expectedValue ) error {
789
930
foundAttrs := make (map [string ]bool )
790
- for k := range kvs {
791
- foundAttrs [k ] = false
931
+ shouldNotFoundAttrs := make (map [string ]bool )
932
+ for k , v := range kvs {
933
+ if v .mode != shouldnotexist {
934
+ foundAttrs [k ] = false
935
+ }
936
+ shouldNotFoundAttrs [k ] = false
792
937
}
793
938
794
939
resource .Attributes ().Range (
@@ -806,6 +951,8 @@ func resourceHasAttributes(resource pcommon.Resource, kvs map[string]*expectedVa
806
951
}
807
952
case exist :
808
953
foundAttrs [k ] = true
954
+ case shouldnotexist :
955
+ shouldNotFoundAttrs [k ] = true
809
956
}
810
957
811
958
}
@@ -814,6 +961,11 @@ func resourceHasAttributes(resource pcommon.Resource, kvs map[string]*expectedVa
814
961
)
815
962
816
963
var err error
964
+ for k , v := range shouldNotFoundAttrs {
965
+ if v {
966
+ err = multierr .Append (err , fmt .Errorf ("%v attribute should not be added" , k ))
967
+ }
968
+ }
817
969
for k , v := range foundAttrs {
818
970
if ! v {
819
971
err = multierr .Append (err , fmt .Errorf ("%v attribute not found" , k ))
0 commit comments