diff --git a/config/configauth/pdatacontext.go b/config/configauth/pdatacontext.go new file mode 100644 index 00000000000..6898e4764eb --- /dev/null +++ b/config/configauth/pdatacontext.go @@ -0,0 +1,49 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package configauth + +import ( + "context" + + "go.opentelemetry.io/collector/model/pdata" +) + +type ctxKey struct{} + +type AuthContext interface { + Equal(other interface{}) bool + GetAttribute(attrName string) interface{} + GetAttributeNames() []string +} + +func InjectAuthContext(ctx context.Context, ac AuthContext) context.Context { + return context.WithValue(ctx, ctxKey{}, ac) +} + +func ExtractAuthContext(ctx context.Context) (AuthContext, bool) { + ac, ok := ctx.Value(ctxKey{}).(AuthContext) + if !ok { + return nil, false + } + return ac, true +} + +func InjectPDataContext(pda pdata.PDataContext, ac AuthContext) { + pda.Set(ctxKey{}, ac) +} + +func ExtractPDataContext(pda pdata.PDataContext) AuthContext { + return pda.Get(ctxKey{}).(AuthContext) +} diff --git a/config/configauth/pdatacontext_test.go b/config/configauth/pdatacontext_test.go new file mode 100644 index 00000000000..1084c8a8b90 --- /dev/null +++ b/config/configauth/pdatacontext_test.go @@ -0,0 +1,15 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package configauth diff --git a/internal/otlptext/databuffer.go b/internal/otlptext/databuffer.go index 2bbcbb87e08..c622e5b14b0 100644 --- a/internal/otlptext/databuffer.go +++ b/internal/otlptext/databuffer.go @@ -36,6 +36,13 @@ func (b *dataBuffer) logAttr(label string, value string) { b.logEntry(" %-15s: %s", label, value) } +func (b *dataBuffer) logPDataContext(label string, am pdata.PDataContext) { + b.logEntry("%s:", label) + am.Range(func(_ interface{}, value interface{}) { + b.logEntry(" -> %v", value) // the context key is likely an empty struct + }) +} + func (b *dataBuffer) logAttributeMap(label string, am pdata.AttributeMap) { if am.Len() == 0 { return diff --git a/internal/otlptext/traces.go b/internal/otlptext/traces.go index 3a11e1e4534..c554448e5f2 100644 --- a/internal/otlptext/traces.go +++ b/internal/otlptext/traces.go @@ -32,6 +32,7 @@ func (textTracesMarshaler) MarshalTraces(td pdata.Traces) ([]byte, error) { for i := 0; i < rss.Len(); i++ { buf.logEntry("ResourceSpans #%d", i) rs := rss.At(i) + buf.logPDataContext("Pipeline Data Context", rs.PDataContext()) buf.logAttributeMap("Resource labels", rs.Resource().Attributes()) ilss := rs.InstrumentationLibrarySpans() for j := 0; j < ilss.Len(); j++ { diff --git a/model/internal/data/pdatacontext.go b/model/internal/data/pdatacontext.go new file mode 100644 index 00000000000..d65be8b5588 --- /dev/null +++ b/model/internal/data/pdatacontext.go @@ -0,0 +1,24 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package data + +type PDataContext struct { + List []PDataContextKeyValue +} + +type PDataContextKeyValue struct { + Key interface{} + Value interface{} +} diff --git a/model/internal/data/protogen/trace/v1/trace.pb.go b/model/internal/data/protogen/trace/v1/trace.pb.go index 092cb7903b4..1fb2a86643d 100644 --- a/model/internal/data/protogen/trace/v1/trace.pb.go +++ b/model/internal/data/protogen/trace/v1/trace.pb.go @@ -256,6 +256,9 @@ type ResourceSpans struct { // to the data in the "instrumentation_library_spans" field which have their own // schema_url field. SchemaUrl string `protobuf:"bytes,3,opt,name=schema_url,json=schemaUrl,proto3" json:"schema_url,omitempty"` + + // This is expected to be ignored by marshaling/unmarshaling. Double-check that this is true. + Context go_opentelemetry_io_collector_model_internal_data.PDataContext } func (m *ResourceSpans) Reset() { *m = ResourceSpans{} } diff --git a/model/pdata/pdatacontext.go b/model/pdata/pdatacontext.go new file mode 100644 index 00000000000..52841f870f9 --- /dev/null +++ b/model/pdata/pdatacontext.go @@ -0,0 +1,46 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package pdata + +import ( + "go.opentelemetry.io/collector/model/internal/data" +) + +type PDataContext struct { + orig *data.PDataContext +} + +func newPDataContext(orig *data.PDataContext) PDataContext { + return PDataContext{orig} +} + +func (pdc PDataContext) Set(key, val interface{}) { + pdc.orig.List = append(pdc.orig.List, data.PDataContextKeyValue{Key: key, Value: val}) +} + +func (pdc PDataContext) Get(key interface{}) interface{} { + for _, kv := range pdc.orig.List { + if kv.Key == key { + return kv.Value + } + } + return nil +} + +func (pdc PDataContext) Range(f func(k interface{}, v interface{})) { + for _, kv := range pdc.orig.List { + f(kv.Key, kv.Value) + } +} diff --git a/model/pdata/traces.go b/model/pdata/traces.go index 4fdf85a9871..85e3a72876a 100644 --- a/model/pdata/traces.go +++ b/model/pdata/traces.go @@ -152,3 +152,7 @@ func (ms SpanStatus) SetCode(v StatusCode) { ms.orig.DeprecatedCode = otlptrace.Status_DEPRECATED_STATUS_CODE_UNKNOWN_ERROR } } + +func (ms ResourceSpans) PDataContext() PDataContext { + return newPDataContext(&(*ms.orig).Context) +} diff --git a/service/internal/authcontext/authcontext.go b/service/internal/authcontext/authcontext.go new file mode 100644 index 00000000000..c859848112a --- /dev/null +++ b/service/internal/authcontext/authcontext.go @@ -0,0 +1,47 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package authcontext + +import ( + "context" + + "go.opentelemetry.io/collector/config/configauth" + "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/model/pdata" +) + +func NewTracesInjector(next consumer.Traces) consumer.Traces { + return injectorForTraces{next} +} + +type injectorForTraces struct { + next consumer.Traces +} + +func (tc injectorForTraces) Capabilities() consumer.Capabilities { + return consumer.Capabilities{MutatesData: false} +} + +func (tc injectorForTraces) ConsumeTraces(ctx context.Context, td pdata.Traces) error { + authContext, ok := configauth.ExtractAuthContext(ctx) + if ok && authContext != nil { + for i := 0; i < td.ResourceSpans().Len(); i++ { + rss := td.ResourceSpans().At(i) + configauth.InjectPDataContext(rss.PDataContext(), authContext) + } + } + + return tc.next.ConsumeTraces(ctx, td) +} diff --git a/service/internal/builder/receivers_builder.go b/service/internal/builder/receivers_builder.go index 4c15e92ba8a..2cb969c221b 100644 --- a/service/internal/builder/receivers_builder.go +++ b/service/internal/builder/receivers_builder.go @@ -26,6 +26,7 @@ import ( "go.opentelemetry.io/collector/component/componenterror" "go.opentelemetry.io/collector/config" "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/service/internal/authcontext" "go.opentelemetry.io/collector/service/internal/components" "go.opentelemetry.io/collector/service/internal/fanoutconsumer" ) @@ -182,6 +183,7 @@ func attachReceiverToPipelines( switch dataType { case config.TracesDataType: junction := buildFanoutTraceConsumer(builtPipelines) + junction = authcontext.NewTracesInjector(junction) createdReceiver, err = factory.CreateTracesReceiver(ctx, set, cfg, junction) case config.MetricsDataType: