Skip to content

Commit 5204c95

Browse files
author
Israel Blancas
committed
Add automatic RBAC creation for k8sobjects receiver
Signed-off-by: Israel Blancas <[email protected]>
1 parent 2b22708 commit 5204c95

File tree

8 files changed

+279
-0
lines changed

8 files changed

+279
-0
lines changed

.chloggen/3429.yaml

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
2+
change_type: enhancement
3+
4+
# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action)
5+
component: collector
6+
7+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
8+
note: Create RBAC rules for the k8sobjects receiver automatically.
9+
10+
# One or more tracking issues related to the change
11+
issues: [3429]
12+
13+
# (Optional) One or more lines of additional information to render under the primary note.
14+
# These lines will be padded with 2 spaces and then inserted directly into the document.
15+
# Use pipe (|) for multiline entries.
16+
subtext:

internal/components/receivers/helpers.go

+3
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ var (
143143
components.NewBuilder[k8seventsConfig]().WithName("k8s_events").
144144
WithRbacGen(generatek8seventsRbacRules).
145145
MustBuild(),
146+
components.NewBuilder[k8sobjectsConfig]().WithName("k8sobjects").
147+
WithRbacGen(generatek8sobjectsRbacRules).
148+
MustBuild(),
146149
NewScraperParser("prometheus"),
147150
NewScraperParser("sshcheck"),
148151
NewScraperParser("cloudfoundry"),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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 receivers
16+
17+
import (
18+
"github.com/go-logr/logr"
19+
rbacv1 "k8s.io/api/rbac/v1"
20+
)
21+
22+
type k8sobjectsConfig struct {
23+
Objects []k8sObject `yaml:"objects"`
24+
}
25+
26+
type k8sObject struct {
27+
Name string `yaml:"name"`
28+
Mode string `yaml:"mode"`
29+
Group string `yaml:"group,omitempty"`
30+
}
31+
32+
func generatek8sobjectsRbacRules(_ logr.Logger, config k8sobjectsConfig) ([]rbacv1.PolicyRule, error) {
33+
// The k8s Objects Receiver needs get permissions on the following resources always.
34+
prs := []rbacv1.PolicyRule{}
35+
for _, obj := range config.Objects {
36+
permissions := []string{"list"}
37+
if obj.Mode == "pull" && (obj.Name != "events" && obj.Name != "events.k8s.io") {
38+
permissions = append(permissions, "get")
39+
} else if obj.Mode == "watch" {
40+
permissions = append(permissions, "watch")
41+
}
42+
prs = append(prs, rbacv1.PolicyRule{
43+
APIGroups: []string{obj.Group},
44+
Resources: []string{obj.Name},
45+
Verbs: permissions,
46+
})
47+
}
48+
return prs, nil
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
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 receivers
16+
17+
import (
18+
"testing"
19+
20+
"github.com/go-logr/logr"
21+
"github.com/stretchr/testify/assert"
22+
rbacv1 "k8s.io/api/rbac/v1"
23+
)
24+
25+
func Test_generatek8sobjectsRbacRules(t *testing.T) {
26+
tests := []struct {
27+
name string
28+
config k8sobjectsConfig
29+
want []rbacv1.PolicyRule
30+
}{
31+
{
32+
name: "basic watch mode",
33+
config: k8sobjectsConfig{
34+
Objects: []k8sObject{
35+
{
36+
Name: "pods",
37+
Mode: "watch",
38+
Group: "v1",
39+
},
40+
},
41+
},
42+
want: []rbacv1.PolicyRule{
43+
{
44+
APIGroups: []string{"v1"},
45+
Resources: []string{"pods"},
46+
Verbs: []string{"list", "watch"},
47+
},
48+
},
49+
},
50+
{
51+
name: "pull mode with events",
52+
config: k8sobjectsConfig{
53+
Objects: []k8sObject{
54+
{
55+
Name: "events",
56+
Mode: "pull",
57+
Group: "v1",
58+
},
59+
},
60+
},
61+
want: []rbacv1.PolicyRule{
62+
{
63+
APIGroups: []string{"v1"},
64+
Resources: []string{"events"},
65+
Verbs: []string{"list"},
66+
},
67+
},
68+
},
69+
{
70+
name: "pull mode with non-events",
71+
config: k8sobjectsConfig{
72+
Objects: []k8sObject{
73+
{
74+
Name: "pods",
75+
Mode: "pull",
76+
Group: "v1",
77+
},
78+
},
79+
},
80+
want: []rbacv1.PolicyRule{
81+
{
82+
APIGroups: []string{"v1"},
83+
Resources: []string{"pods"},
84+
Verbs: []string{"list", "get"},
85+
},
86+
},
87+
},
88+
{
89+
name: "multiple objects",
90+
config: k8sobjectsConfig{
91+
Objects: []k8sObject{
92+
{
93+
Name: "pods",
94+
Mode: "pull",
95+
Group: "v1",
96+
},
97+
{
98+
Name: "events",
99+
Mode: "pull",
100+
Group: "v1",
101+
},
102+
{
103+
Name: "deployments",
104+
Mode: "watch",
105+
Group: "apps/v1",
106+
},
107+
},
108+
},
109+
want: []rbacv1.PolicyRule{
110+
{
111+
APIGroups: []string{"v1"},
112+
Resources: []string{"pods"},
113+
Verbs: []string{"list", "get"},
114+
},
115+
{
116+
APIGroups: []string{"v1"},
117+
Resources: []string{"events"},
118+
Verbs: []string{"list"},
119+
},
120+
{
121+
APIGroups: []string{"apps/v1"},
122+
Resources: []string{"deployments"},
123+
Verbs: []string{"list", "watch"},
124+
},
125+
},
126+
},
127+
}
128+
129+
for _, tt := range tests {
130+
t.Run(tt.name, func(t *testing.T) {
131+
got, err := generatek8sobjectsRbacRules(logr.Logger{}, tt.config)
132+
assert.NoError(t, err)
133+
assert.Equal(t, tt.want, got)
134+
})
135+
}
136+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
apiVersion: v1
2+
kind: Namespace
3+
metadata:
4+
name: chainsaw-k8sobjects
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
apiVersion: rbac.authorization.k8s.io/v1
2+
kind: ClusterRole
3+
metadata:
4+
name: simplest-chainsaw-k8sobjects-cluster-role
5+
rules:
6+
- apiGroups:
7+
- ""
8+
resources:
9+
- pods
10+
verbs:
11+
- list
12+
- get
13+
---
14+
apiVersion: rbac.authorization.k8s.io/v1
15+
kind: ClusterRoleBinding
16+
metadata:
17+
labels:
18+
app.kubernetes.io/component: opentelemetry-collector
19+
app.kubernetes.io/instance: chainsaw-k8sobjects.simplest
20+
app.kubernetes.io/managed-by: opentelemetry-operator
21+
app.kubernetes.io/name: simplest-chainsaw-k8sobjects-collector
22+
app.kubernetes.io/part-of: opentelemetry
23+
name: simplest-chainsaw-k8sobjects-collector
24+
roleRef:
25+
apiGroup: rbac.authorization.k8s.io
26+
kind: ClusterRole
27+
name: simplest-chainsaw-k8sobjects-cluster-role
28+
subjects:
29+
- kind: ServiceAccount
30+
name: simplest-collector
31+
namespace: chainsaw-k8sobjects
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
apiVersion: opentelemetry.io/v1alpha1
2+
kind: OpenTelemetryCollector
3+
metadata:
4+
name: simplest
5+
namespace: chainsaw-k8sobjects
6+
spec:
7+
config: |
8+
receivers:
9+
k8sobjects:
10+
auth_type: serviceAccount
11+
objects:
12+
- name: pods
13+
mode: pull
14+
processors:
15+
exporters:
16+
debug:
17+
service:
18+
pipelines:
19+
traces:
20+
receivers: [k8sobjects]
21+
processors: []
22+
exporters: [debug]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json
2+
apiVersion: chainsaw.kyverno.io/v1alpha1
3+
kind: Test
4+
metadata:
5+
creationTimestamp: null
6+
name: receiver-k8sobjects
7+
spec:
8+
steps:
9+
- name: create-namespace
10+
try:
11+
- apply:
12+
file: 00-install.yaml
13+
- name: pod-pull-config
14+
try:
15+
- apply:
16+
file: 01-install.yaml
17+
- assert:
18+
file: 01-assert.yaml

0 commit comments

Comments
 (0)