forked from rancher/rancher
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cluster.go
139 lines (120 loc) · 4.89 KB
/
cluster.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package podsecuritypolicy
import (
"context"
"fmt"
"k8s.io/apimachinery/pkg/runtime"
v12 "github.com/rancher/types/apis/core/v1"
"github.com/rancher/types/apis/extensions/v1beta1"
v3 "github.com/rancher/types/apis/management.cattle.io/v3"
v1 "github.com/rancher/types/apis/rbac.authorization.k8s.io/v1"
"github.com/rancher/types/config"
"github.com/sirupsen/logrus"
v1beta13 "k8s.io/api/extensions/v1beta1"
rbac "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type clusterManager struct {
clusterName string
templateLister v3.PodSecurityPolicyTemplateLister
policyLister v1beta1.PodSecurityPolicyLister
policies v1beta1.PodSecurityPolicyInterface
serviceAccountLister v12.ServiceAccountLister
serviceAccountsController v12.ServiceAccountController
clusterRoleLister v1.ClusterRoleLister
clusterRoles v1.ClusterRoleInterface
clusters v3.ClusterInterface
}
// RegisterCluster updates the pod security policy if the pod security policy template default for this cluster has been
// updated, then resyncs all service accounts in this namespace.
func RegisterCluster(ctx context.Context, context *config.UserContext) {
logrus.Infof("registering podsecuritypolicy cluster handler for cluster %v", context.ClusterName)
m := &clusterManager{
clusterName: context.ClusterName,
policies: context.Extensions.PodSecurityPolicies(""),
clusters: context.Management.Management.Clusters(""),
templateLister: context.Management.Management.PodSecurityPolicyTemplates("").Controller().Lister(),
policyLister: context.Extensions.PodSecurityPolicies("").Controller().Lister(),
clusterRoleLister: context.RBAC.ClusterRoles("").Controller().Lister(),
clusterRoles: context.RBAC.ClusterRoles(""),
serviceAccountLister: context.Core.ServiceAccounts("").Controller().Lister(),
serviceAccountsController: context.Core.ServiceAccounts("").Controller(),
}
context.Management.Management.Clusters("").AddHandler(ctx, "ClusterSyncHandler", m.sync)
}
func (m *clusterManager) sync(key string, obj *v3.Cluster) (runtime.Object, error) {
if obj == nil ||
m.clusterName != obj.Name ||
obj.Spec.DefaultPodSecurityPolicyTemplateName == obj.Status.AppliedPodSecurityPolicyTemplateName {
// Nothing to do
return nil, nil
}
if obj.Spec.DefaultPodSecurityPolicyTemplateName != "" {
podSecurityPolicyName := fmt.Sprintf("%v-psp", obj.Spec.DefaultPodSecurityPolicyTemplateName)
_, err := m.policyLister.Get("", podSecurityPolicyName)
if err != nil {
if errors.IsNotFound(err) {
template, err := m.templateLister.Get("", obj.Spec.DefaultPodSecurityPolicyTemplateName)
if err != nil {
return nil, fmt.Errorf("error getting pspt: %v", err)
}
objectMeta := metav1.ObjectMeta{}
objectMeta.Name = podSecurityPolicyName
objectMeta.Annotations = make(map[string]string)
objectMeta.Annotations[podSecurityPolicyTemplateParentAnnotation] = template.Name
objectMeta.Annotations[podSecurityPolicyTemplateVersionAnnotation] = template.ResourceVersion
psp := &v1beta13.PodSecurityPolicy{
TypeMeta: metav1.TypeMeta{
Kind: podSecurityPolicy,
APIVersion: apiVersion,
},
ObjectMeta: objectMeta,
Spec: template.Spec,
}
_, err = m.policies.Create(psp)
if err != nil {
return nil, fmt.Errorf("error creating psp: %v", err)
}
} else {
return nil, fmt.Errorf("error getting policy: %v", err)
}
}
clusterRoleName := fmt.Sprintf("%v-clusterrole", obj.Spec.DefaultPodSecurityPolicyTemplateName)
_, err = m.clusterRoleLister.Get("", clusterRoleName)
if err != nil {
if errors.IsNotFound(err) {
newRole := &rbac.ClusterRole{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{},
Name: clusterRoleName,
},
TypeMeta: metav1.TypeMeta{
Kind: "ClusterRole",
},
Rules: []rbac.PolicyRule{
{
APIGroups: []string{"extensions"},
Resources: []string{"podsecuritypolicies"},
Verbs: []string{"use"},
ResourceNames: []string{podSecurityPolicyName},
},
},
}
newRole.Annotations[podSecurityPolicyTemplateParentAnnotation] = obj.Spec.DefaultPodSecurityPolicyTemplateName
_, err := m.clusterRoles.Create(newRole)
if err != nil {
return nil, fmt.Errorf("error creating cluster role: %v", err)
}
} else {
return nil, fmt.Errorf("error getting cluster role: %v", err)
}
}
obj.Status.AppliedPodSecurityPolicyTemplateName = obj.Spec.DefaultPodSecurityPolicyTemplateName
_, err = m.clusters.Update(obj)
if err != nil {
return nil, fmt.Errorf("error updating cluster: %v", err)
}
return nil, resyncServiceAccounts(m.serviceAccountLister, m.serviceAccountsController, "")
}
return nil, nil
}