Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/pkg/flow/internal/controller/config.go
4095 views
1
package controller
2
3
import (
4
"fmt"
5
6
"github.com/grafana/agent/pkg/river/ast"
7
"github.com/grafana/agent/pkg/river/diag"
8
)
9
10
const (
11
argumentBlockID = "argument"
12
exportBlockID = "export"
13
loggingBlockID = "logging"
14
tracingBlockID = "tracing"
15
)
16
17
// NewConfigNode creates a new ConfigNode from an initial ast.BlockStmt.
18
// The underlying config isn't applied until Evaluate is called.
19
func NewConfigNode(block *ast.BlockStmt, globals ComponentGlobals) (BlockNode, diag.Diagnostics) {
20
switch block.GetBlockName() {
21
case argumentBlockID:
22
return NewArgumentConfigNode(block, globals), nil
23
case exportBlockID:
24
return NewExportConfigNode(block, globals), nil
25
case loggingBlockID:
26
return NewLoggingConfigNode(block, globals), nil
27
case tracingBlockID:
28
return NewTracingConfigNode(block, globals), nil
29
default:
30
var diags diag.Diagnostics
31
diags.Add(diag.Diagnostic{
32
Severity: diag.SeverityLevelError,
33
Message: fmt.Sprintf("invalid config block type %s while creating new config node", block.GetBlockName()),
34
StartPos: ast.StartPos(block).Position(),
35
EndPos: ast.EndPos(block).Position(),
36
})
37
return nil, diags
38
}
39
}
40
41
// ConfigNodeMap represents the config BlockNodes in their explicit types.
42
// This is helpful when validating node conditions specific to config node
43
// types.
44
type ConfigNodeMap struct {
45
logging *LoggingConfigNode
46
tracing *TracingConfigNode
47
argumentMap map[string]*ArgumentConfigNode
48
exportMap map[string]*ExportConfigNode
49
}
50
51
// NewConfigNodeMap will create an initial ConfigNodeMap. Append must be called
52
// to populate NewConfigNodeMap.
53
func NewConfigNodeMap() *ConfigNodeMap {
54
return &ConfigNodeMap{
55
logging: nil,
56
tracing: nil,
57
argumentMap: map[string]*ArgumentConfigNode{},
58
exportMap: map[string]*ExportConfigNode{},
59
}
60
}
61
62
// Append will add a config node to the ConfigNodeMap. This will overwrite
63
// values on the ConfigNodeMap that are matched and previously set.
64
func (nodeMap *ConfigNodeMap) Append(configNode BlockNode) diag.Diagnostics {
65
var diags diag.Diagnostics
66
67
switch n := configNode.(type) {
68
case *ArgumentConfigNode:
69
nodeMap.argumentMap[n.Label()] = n
70
case *ExportConfigNode:
71
nodeMap.exportMap[n.Label()] = n
72
case *LoggingConfigNode:
73
nodeMap.logging = n
74
case *TracingConfigNode:
75
nodeMap.tracing = n
76
default:
77
diags.Add(diag.Diagnostic{
78
Severity: diag.SeverityLevelError,
79
Message: fmt.Sprintf("unsupported config node type found %q", n.Block().Name),
80
StartPos: ast.StartPos(n.Block()).Position(),
81
EndPos: ast.EndPos(n.Block()).Position(),
82
})
83
}
84
85
return diags
86
}
87
88
// Validate wraps all validators for ConfigNodeMap.
89
func (nodeMap *ConfigNodeMap) Validate(isInModule bool, args map[string]any) diag.Diagnostics {
90
var diags diag.Diagnostics
91
92
newDiags := nodeMap.ValidateModuleConstraints(isInModule)
93
diags = append(diags, newDiags...)
94
95
newDiags = nodeMap.ValidateUnsupportedArguments(args)
96
diags = append(diags, newDiags...)
97
98
return diags
99
}
100
101
// ValidateModuleConstraints will make sure config blocks with module
102
// constraints get followed.
103
func (nodeMap *ConfigNodeMap) ValidateModuleConstraints(isInModule bool) diag.Diagnostics {
104
var diags diag.Diagnostics
105
106
if isInModule {
107
if nodeMap.logging != nil {
108
diags.Add(diag.Diagnostic{
109
Severity: diag.SeverityLevelError,
110
Message: "logging block not allowed inside a module",
111
StartPos: ast.StartPos(nodeMap.logging.Block()).Position(),
112
EndPos: ast.EndPos(nodeMap.logging.Block()).Position(),
113
})
114
}
115
116
if nodeMap.tracing != nil {
117
diags.Add(diag.Diagnostic{
118
Severity: diag.SeverityLevelError,
119
Message: "tracing block not allowed inside a module",
120
StartPos: ast.StartPos(nodeMap.tracing.Block()).Position(),
121
EndPos: ast.EndPos(nodeMap.tracing.Block()).Position(),
122
})
123
}
124
return diags
125
}
126
127
for key := range nodeMap.argumentMap {
128
diags.Add(diag.Diagnostic{
129
Severity: diag.SeverityLevelError,
130
Message: "argument blocks only allowed inside a module",
131
StartPos: ast.StartPos(nodeMap.argumentMap[key].Block()).Position(),
132
EndPos: ast.EndPos(nodeMap.argumentMap[key].Block()).Position(),
133
})
134
}
135
136
for key := range nodeMap.exportMap {
137
diags.Add(diag.Diagnostic{
138
Severity: diag.SeverityLevelError,
139
Message: "export blocks only allowed inside a module",
140
StartPos: ast.StartPos(nodeMap.exportMap[key].Block()).Position(),
141
EndPos: ast.EndPos(nodeMap.exportMap[key].Block()).Position(),
142
})
143
}
144
145
return diags
146
}
147
148
// ValidateUnsupportedArguments will validate each provided argument is
149
// supported in the config.
150
func (nodeMap *ConfigNodeMap) ValidateUnsupportedArguments(args map[string]any) diag.Diagnostics {
151
var diags diag.Diagnostics
152
153
for argName := range args {
154
if _, found := nodeMap.argumentMap[argName]; found {
155
continue
156
}
157
diags.Add(diag.Diagnostic{
158
Severity: diag.SeverityLevelError,
159
Message: fmt.Sprintf("Provided argument %q is not defined in the module", argName),
160
})
161
}
162
163
return diags
164
}
165
166