-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathrbac.go
109 lines (99 loc) · 3.33 KB
/
rbac.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package actions
import (
"context"
"fmt"
rhtasv1alpha1 "github.com/securesign/operator/api/v1alpha1"
"github.com/securesign/operator/internal/controller/common/action"
"github.com/securesign/operator/internal/controller/common/utils/kubernetes"
"github.com/securesign/operator/internal/controller/common/utils/kubernetes/ensure"
"github.com/securesign/operator/internal/controller/constants"
"github.com/securesign/operator/internal/controller/labels"
"golang.org/x/exp/maps"
v1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)
func NewRBACAction() action.Action[*rhtasv1alpha1.Trillian] {
return &rbacAction{}
}
type rbacAction struct {
action.BaseAction
}
func (i rbacAction) Name() string {
return "ensure RBAC"
}
func (i rbacAction) CanHandle(_ context.Context, instance *rhtasv1alpha1.Trillian) bool {
c := meta.FindStatusCondition(instance.Status.Conditions, constants.Ready)
return c.Reason == constants.Creating || c.Reason == constants.Ready
}
func (i rbacAction) Handle(ctx context.Context, instance *rhtasv1alpha1.Trillian) *action.Result {
var (
err error
)
labels := labels.For(LogServerComponentName, RBACName, instance.Name)
// ServiceAccount
if _, err = kubernetes.CreateOrUpdate(ctx, i.Client, &v1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: RBACName,
Namespace: instance.Namespace,
},
},
ensure.ControllerReference[*v1.ServiceAccount](instance, i.Client),
ensure.Labels[*v1.ServiceAccount](maps.Keys(labels), labels),
); err != nil {
return i.Error(ctx, reconcile.TerminalError(fmt.Errorf("could not create SA: %w", err)), instance)
}
// Role
if _, err = kubernetes.CreateOrUpdate(ctx, i.Client, &rbacv1.Role{
ObjectMeta: metav1.ObjectMeta{
Name: RBACName,
Namespace: instance.Namespace,
},
},
ensure.ControllerReference[*rbacv1.Role](instance, i.Client),
ensure.Labels[*rbacv1.Role](maps.Keys(labels), labels),
kubernetes.EnsureRoleRules(
rbacv1.PolicyRule{
APIGroups: []string{""},
Resources: []string{"configmaps"},
Verbs: []string{"create", "get", "update"},
},
rbacv1.PolicyRule{
APIGroups: []string{""},
Resources: []string{"secrets"},
Verbs: []string{"create", "get", "update"},
},
rbacv1.PolicyRule{
APIGroups: []string{"coordination.k8s.io"},
Resources: []string{"leases"},
Verbs: []string{"create", "get", "update", "watch", "patch"},
},
),
); err != nil {
return i.Error(ctx, reconcile.TerminalError(fmt.Errorf("could not create Role: %w", err)), instance)
}
// RoleBinding
if _, err = kubernetes.CreateOrUpdate(ctx, i.Client, &rbacv1.RoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: RBACName,
Namespace: instance.Namespace,
},
},
ensure.ControllerReference[*rbacv1.RoleBinding](instance, i.Client),
ensure.Labels[*rbacv1.RoleBinding](maps.Keys(labels), labels),
kubernetes.EnsureRoleBinding(
rbacv1.RoleRef{
APIGroup: v1.SchemeGroupVersion.Group,
Kind: "Role",
Name: RBACName,
},
rbacv1.Subject{
Kind: "ServiceAccount", Name: RBACName, Namespace: instance.Namespace,
}),
); err != nil {
return i.Error(ctx, reconcile.TerminalError(fmt.Errorf("could not create RoleBinding: %w", err)), instance)
}
return i.Continue()
}