Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/component/otelcol/auth/auth.go
4096 views
1
// Package auth provides utilities to create a Flow component from
2
// OpenTelemetry Collector authentication extensions.
3
//
4
// Other OpenTelemetry Collector extensions are better served as generic Flow
5
// components rather than being placed in the otelcol namespace.
6
package auth
7
8
import (
9
"context"
10
"os"
11
12
"github.com/grafana/agent/component"
13
"github.com/grafana/agent/component/otelcol/internal/lazycollector"
14
"github.com/grafana/agent/component/otelcol/internal/scheduler"
15
"github.com/grafana/agent/pkg/build"
16
"github.com/grafana/agent/pkg/river"
17
"github.com/grafana/agent/pkg/util/zapadapter"
18
"github.com/prometheus/client_golang/prometheus"
19
otelcomponent "go.opentelemetry.io/collector/component"
20
otelconfig "go.opentelemetry.io/collector/config"
21
sdkprometheus "go.opentelemetry.io/otel/exporters/prometheus"
22
"go.opentelemetry.io/otel/sdk/metric"
23
24
_ "github.com/grafana/agent/component/otelcol/internal/featuregate" // Enable needed feature gates
25
)
26
27
// Arguments is an extension of component.Arguments which contains necessary
28
// settings for OpenTelemetry Collector authentication extensions.
29
type Arguments interface {
30
component.Arguments
31
32
// Convert converts the Arguments into an OpenTelemetry Collector
33
// authentication extension configuration.
34
Convert() (otelconfig.Extension, error)
35
36
// Extensions returns the set of extensions that the configured component is
37
// allowed to use.
38
Extensions() map[otelconfig.ComponentID]otelcomponent.Extension
39
40
// Exporters returns the set of exporters that are exposed to the configured
41
// component.
42
Exporters() map[otelconfig.DataType]map[otelconfig.ComponentID]otelcomponent.Exporter
43
}
44
45
// Exports is a common Exports type for Flow components which expose
46
// OpenTelemetry Collector authentication extensions.
47
type Exports struct {
48
// Handler is the managed component. Handler is updated any time the
49
// extension is updated.
50
Handler Handler `river:"handler,attr"`
51
}
52
53
// Handler combines an extension with its ID.
54
type Handler struct {
55
ID otelconfig.ComponentID
56
Extension otelcomponent.Extension
57
}
58
59
var _ river.Capsule = Handler{}
60
61
// RiverCapsule marks Handler as a capsule type.
62
func (Handler) RiverCapsule() {}
63
64
// Auth is a Flow component shim which manages an OpenTelemetry Collector
65
// authentication extension.
66
type Auth struct {
67
ctx context.Context
68
cancel context.CancelFunc
69
70
opts component.Options
71
factory otelcomponent.ExtensionFactory
72
73
sched *scheduler.Scheduler
74
collector *lazycollector.Collector
75
}
76
77
var (
78
_ component.Component = (*Auth)(nil)
79
_ component.HealthComponent = (*Auth)(nil)
80
)
81
82
// New creates a new Flow component which encapsulates an OpenTelemetry
83
// Collector authentication extension. args must hold a value of the argument
84
// type registered with the Flow component.
85
//
86
// The registered component must be registered to export the Exports type from
87
// this package, otherwise New will panic.
88
func New(opts component.Options, f otelcomponent.ExtensionFactory, args Arguments) (*Auth, error) {
89
ctx, cancel := context.WithCancel(context.Background())
90
91
// Create a lazy collector where metrics from the upstream component will be
92
// forwarded.
93
collector := lazycollector.New()
94
opts.Registerer.MustRegister(collector)
95
96
r := &Auth{
97
ctx: ctx,
98
cancel: cancel,
99
100
opts: opts,
101
factory: f,
102
103
sched: scheduler.New(opts.Logger),
104
collector: collector,
105
}
106
if err := r.Update(args); err != nil {
107
return nil, err
108
}
109
return r, nil
110
}
111
112
// Run starts the Auth component.
113
func (a *Auth) Run(ctx context.Context) error {
114
defer a.cancel()
115
return a.sched.Run(ctx)
116
}
117
118
// Update implements component.Component. It will convert the Arguments into
119
// configuration for OpenTelemetry Collector authentication extension
120
// configuration and manage the underlying OpenTelemetry Collector extension.
121
func (a *Auth) Update(args component.Arguments) error {
122
rargs := args.(Arguments)
123
124
host := scheduler.NewHost(
125
a.opts.Logger,
126
scheduler.WithHostExtensions(rargs.Extensions()),
127
scheduler.WithHostExporters(rargs.Exporters()),
128
)
129
130
reg := prometheus.NewRegistry()
131
a.collector.Set(reg)
132
133
promExporter, err := sdkprometheus.New(sdkprometheus.WithRegisterer(reg), sdkprometheus.WithoutTargetInfo())
134
if err != nil {
135
return err
136
}
137
138
settings := otelcomponent.ExtensionCreateSettings{
139
TelemetrySettings: otelcomponent.TelemetrySettings{
140
Logger: zapadapter.New(a.opts.Logger),
141
142
TracerProvider: a.opts.Tracer,
143
MeterProvider: metric.NewMeterProvider(metric.WithReader(promExporter)),
144
},
145
146
BuildInfo: otelcomponent.BuildInfo{
147
Command: os.Args[0],
148
Description: "Grafana Agent",
149
Version: build.Version,
150
},
151
}
152
153
extensionConfig, err := rargs.Convert()
154
if err != nil {
155
return err
156
}
157
158
// Create instances of the extension from our factory.
159
var components []otelcomponent.Component
160
161
ext, err := a.factory.CreateExtension(a.ctx, settings, extensionConfig)
162
if err != nil {
163
return err
164
} else if ext != nil {
165
components = append(components, ext)
166
}
167
168
// Inform listeners that our handler changed.
169
a.opts.OnStateChange(Exports{
170
Handler: Handler{
171
ID: otelconfig.NewComponentID(otelconfig.Type(a.opts.ID)),
172
Extension: ext,
173
},
174
})
175
176
// Schedule the components to run once our component is running.
177
a.sched.Schedule(host, components...)
178
return nil
179
}
180
181
// CurrentHealth implements component.HealthComponent.
182
func (a *Auth) CurrentHealth() component.Health {
183
return a.sched.CurrentHealth()
184
}
185
186