Skip to content

Commit f2a8cf2

Browse files
authored
Uses the new parsing structure for RBAC parsing (#3206)
* begin interface change * move over processor config * use it * fix tests * Generics * rename * builder * Change to use the builder pattern instead of the option pattern * remove unused methods * fix unit tests * rename somethings * missed a spot * fix builder
1 parent 2ed5f03 commit f2a8cf2

20 files changed

+1367
-322
lines changed

apis/v1beta1/config.go

+41-1
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ import (
2727
"github.com/go-logr/logr"
2828
"gopkg.in/yaml.v3"
2929
corev1 "k8s.io/api/core/v1"
30+
rbacv1 "k8s.io/api/rbac/v1"
3031

3132
"github.com/open-telemetry/opentelemetry-operator/internal/components"
3233
"github.com/open-telemetry/opentelemetry-operator/internal/components/exporters"
34+
"github.com/open-telemetry/opentelemetry-operator/internal/components/processors"
3335
"github.com/open-telemetry/opentelemetry-operator/internal/components/receivers"
3436
)
3537

@@ -139,9 +141,43 @@ type Config struct {
139141
Service Service `json:"service" yaml:"service"`
140142
}
141143

144+
// getRbacRulesForComponentKinds gets the RBAC Rules for the given ComponentKind(s).
145+
func (c *Config) getRbacRulesForComponentKinds(logger logr.Logger, componentKinds ...ComponentKind) ([]rbacv1.PolicyRule, error) {
146+
var rules []rbacv1.PolicyRule
147+
enabledComponents := c.GetEnabledComponents()
148+
for _, componentKind := range componentKinds {
149+
var retriever components.ParserRetriever
150+
var cfg AnyConfig
151+
switch componentKind {
152+
case KindReceiver:
153+
retriever = receivers.ReceiverFor
154+
cfg = c.Receivers
155+
case KindExporter:
156+
retriever = exporters.ParserFor
157+
cfg = c.Exporters
158+
case KindProcessor:
159+
retriever = processors.ProcessorFor
160+
if c.Processors == nil {
161+
cfg = AnyConfig{}
162+
} else {
163+
cfg = *c.Processors
164+
}
165+
}
166+
for componentName := range enabledComponents[componentKind] {
167+
// TODO: Clean up the naming here and make it simpler to use a retriever.
168+
parser := retriever(componentName)
169+
if parsedRules, err := parser.GetRBACRules(logger, cfg.Object[componentName]); err != nil {
170+
return nil, err
171+
} else {
172+
rules = append(rules, parsedRules...)
173+
}
174+
}
175+
}
176+
return rules, nil
177+
}
178+
142179
// getPortsForComponentKinds gets the ports for the given ComponentKind(s).
143180
func (c *Config) getPortsForComponentKinds(logger logr.Logger, componentKinds ...ComponentKind) ([]corev1.ServicePort, error) {
144-
145181
var ports []corev1.ServicePort
146182
enabledComponents := c.GetEnabledComponents()
147183
for _, componentKind := range componentKinds {
@@ -187,6 +223,10 @@ func (c *Config) GetAllPorts(logger logr.Logger) ([]corev1.ServicePort, error) {
187223
return c.getPortsForComponentKinds(logger, KindReceiver, KindExporter)
188224
}
189225

226+
func (c *Config) GetAllRbacRules(logger logr.Logger) ([]rbacv1.PolicyRule, error) {
227+
return c.getRbacRulesForComponentKinds(logger, KindReceiver, KindExporter, KindProcessor)
228+
}
229+
190230
// Yaml encodes the current object and returns it as a string.
191231
func (c *Config) Yaml() (string, error) {
192232
var buf bytes.Buffer

internal/components/builder.go

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// Copyright The OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package components
16+
17+
import (
18+
"fmt"
19+
20+
corev1 "k8s.io/api/core/v1"
21+
"k8s.io/apimachinery/pkg/util/intstr"
22+
23+
"github.com/open-telemetry/opentelemetry-operator/internal/naming"
24+
)
25+
26+
type ParserOption[ComponentConfigType any] func(*Settings[ComponentConfigType])
27+
28+
type Settings[ComponentConfigType any] struct {
29+
protocol corev1.Protocol
30+
appProtocol *string
31+
targetPort intstr.IntOrString
32+
nodePort int32
33+
name string
34+
port int32
35+
portParser PortParser[ComponentConfigType]
36+
rbacGen RBACRuleGenerator[ComponentConfigType]
37+
}
38+
39+
func NewEmptySettings[ComponentConfigType any]() *Settings[ComponentConfigType] {
40+
return &Settings[ComponentConfigType]{}
41+
}
42+
43+
func (o *Settings[ComponentConfigType]) Apply(opts ...ParserOption[ComponentConfigType]) {
44+
for _, opt := range opts {
45+
opt(o)
46+
}
47+
}
48+
49+
func (o *Settings[ComponentConfigType]) GetServicePort() *corev1.ServicePort {
50+
return &corev1.ServicePort{
51+
Name: naming.PortName(o.name, o.port),
52+
Port: o.port,
53+
Protocol: o.protocol,
54+
AppProtocol: o.appProtocol,
55+
TargetPort: o.targetPort,
56+
NodePort: o.nodePort,
57+
}
58+
}
59+
60+
type Builder[ComponentConfigType any] []ParserOption[ComponentConfigType]
61+
62+
func NewBuilder[ComponentConfigType any]() Builder[ComponentConfigType] {
63+
return []ParserOption[ComponentConfigType]{}
64+
}
65+
66+
func (b Builder[ComponentConfigType]) WithProtocol(protocol corev1.Protocol) Builder[ComponentConfigType] {
67+
return append(b, func(o *Settings[ComponentConfigType]) {
68+
o.protocol = protocol
69+
})
70+
}
71+
func (b Builder[ComponentConfigType]) WithAppProtocol(appProtocol *string) Builder[ComponentConfigType] {
72+
return append(b, func(o *Settings[ComponentConfigType]) {
73+
o.appProtocol = appProtocol
74+
})
75+
}
76+
func (b Builder[ComponentConfigType]) WithTargetPort(targetPort int32) Builder[ComponentConfigType] {
77+
return append(b, func(o *Settings[ComponentConfigType]) {
78+
o.targetPort = intstr.FromInt32(targetPort)
79+
})
80+
}
81+
func (b Builder[ComponentConfigType]) WithNodePort(nodePort int32) Builder[ComponentConfigType] {
82+
return append(b, func(o *Settings[ComponentConfigType]) {
83+
o.nodePort = nodePort
84+
})
85+
}
86+
func (b Builder[ComponentConfigType]) WithName(name string) Builder[ComponentConfigType] {
87+
return append(b, func(o *Settings[ComponentConfigType]) {
88+
o.name = name
89+
})
90+
}
91+
func (b Builder[ComponentConfigType]) WithPort(port int32) Builder[ComponentConfigType] {
92+
return append(b, func(o *Settings[ComponentConfigType]) {
93+
o.port = port
94+
})
95+
}
96+
func (b Builder[ComponentConfigType]) WithPortParser(portParser PortParser[ComponentConfigType]) Builder[ComponentConfigType] {
97+
return append(b, func(o *Settings[ComponentConfigType]) {
98+
o.portParser = portParser
99+
})
100+
}
101+
func (b Builder[ComponentConfigType]) WithRbacGen(rbacGen RBACRuleGenerator[ComponentConfigType]) Builder[ComponentConfigType] {
102+
return append(b, func(o *Settings[ComponentConfigType]) {
103+
o.rbacGen = rbacGen
104+
})
105+
}
106+
107+
func (b Builder[ComponentConfigType]) Build() (*GenericParser[ComponentConfigType], error) {
108+
o := NewEmptySettings[ComponentConfigType]()
109+
o.Apply(b...)
110+
if len(o.name) == 0 {
111+
return nil, fmt.Errorf("invalid settings struct, no name specified")
112+
}
113+
return &GenericParser[ComponentConfigType]{name: o.name, portParser: o.portParser, rbacGen: o.rbacGen, settings: o}, nil
114+
}
115+
116+
func (b Builder[ComponentConfigType]) MustBuild() *GenericParser[ComponentConfigType] {
117+
if p, err := b.Build(); err != nil {
118+
panic(err)
119+
} else {
120+
return p
121+
}
122+
}

0 commit comments

Comments
 (0)