forked from rancher/rancher
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cluster.go
136 lines (118 loc) · 4.75 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
package podsecuritypolicy
import (
"fmt"
v12 "github.com/rancher/types/apis/core/v1"
"github.com/rancher/types/apis/extensions/v1beta1"
"github.com/rancher/types/apis/management.cattle.io/v3"
"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(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("ClusterSyncHandler", m.sync)
}
func (m *clusterManager) sync(key string, obj *v3.Cluster) error {
if obj == nil ||
m.clusterName != obj.Name ||
obj.Spec.DefaultPodSecurityPolicyTemplateName == obj.Status.AppliedPodSecurityPolicyTemplateName {
// Nothing to do
return 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 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 fmt.Errorf("error creating psp: %v", err)
}
} else {
return 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 fmt.Errorf("error creating cluster role: %v", err)
}
} else {
return fmt.Errorf("error getting cluster role: %v", err)
}
}
obj.Status.AppliedPodSecurityPolicyTemplateName = obj.Spec.DefaultPodSecurityPolicyTemplateName
_, err = m.clusters.Update(obj)
if err != nil {
return fmt.Errorf("error updating cluster: %v", err)
}
return resyncServiceAccounts(m.serviceAccountLister, m.serviceAccountsController, "")
}
return nil
}