37 Star 407 Fork 74

GVPrancher/rancher

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
binding.go 6.31 KB
一键复制 编辑 原始数据 按行查看 历史
package podsecuritypolicy
import (
"fmt"
"github.com/rancher/types/apis/core/v1"
"github.com/rancher/types/apis/extensions/v1beta1"
"github.com/rancher/types/apis/management.cattle.io/v3"
v12 "github.com/rancher/types/apis/rbac.authorization.k8s.io/v1"
"github.com/rancher/types/config"
"github.com/sirupsen/logrus"
v13 "k8s.io/api/core/v1"
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"
"k8s.io/client-go/tools/cache"
)
const namespaceByProjectNameIndex = "podsecuritypolicy.rbac.user.cattle.io/by-project-name"
// RegisterBindings updates the pod security policy for this binding if it has been changed. Also resync service
// accounts so they pick up the change. If no policy exists then exits without doing anything.
func RegisterBindings(context *config.UserContext) {
logrus.Infof("registering podsecuritypolicy project handler for cluster %v", context.ClusterName)
namespaceInformer := context.Core.Namespaces("").Controller().Informer()
namespaceIndexers := map[string]cache.IndexFunc{
namespaceByProjectNameIndex: namespaceByProjectName,
}
namespaceInformer.AddIndexers(namespaceIndexers)
lifecycle := &lifecycle{
policyLister: context.Extensions.PodSecurityPolicies("").Controller().Lister(),
policies: context.Extensions.PodSecurityPolicies(""),
psptLister: context.Management.Management.PodSecurityPolicyTemplates("").Controller().Lister(),
clusterRoleLister: context.RBAC.ClusterRoles("").Controller().Lister(),
clusterRoles: context.RBAC.ClusterRoles(""),
serviceAccountLister: context.Core.ServiceAccounts("").Controller().Lister(),
serviceAccounts: context.Core.ServiceAccounts("").Controller(),
namespaces: context.Core.Namespaces(""),
namespaceIndexer: namespaceInformer.GetIndexer(),
}
context.Management.Management.PodSecurityPolicyTemplateProjectBindings("").
AddLifecycle("PodSecurityPolicyTemplateProjectBindingsLifecycleHandler", lifecycle)
}
func namespaceByProjectName(obj interface{}) ([]string, error) {
namespace, ok := obj.(*v13.Namespace)
if !ok || namespace.Annotations[projectIDAnnotation] == "" {
return []string{}, nil
}
return []string{namespace.Annotations[projectIDAnnotation]}, nil
}
type lifecycle struct {
policyLister v1beta1.PodSecurityPolicyLister
policies v1beta1.PodSecurityPolicyInterface
psptLister v3.PodSecurityPolicyTemplateLister
clusterRoleLister v12.ClusterRoleLister
clusterRoles v12.ClusterRoleInterface
serviceAccountLister v1.ServiceAccountLister
serviceAccounts v1.ServiceAccountController
namespaces v1.NamespaceInterface
namespaceIndexer cache.Indexer
}
func (l *lifecycle) Create(obj *v3.PodSecurityPolicyTemplateProjectBinding) (*v3.PodSecurityPolicyTemplateProjectBinding, error) {
return l.sync(obj)
}
func (l *lifecycle) Updated(obj *v3.PodSecurityPolicyTemplateProjectBinding) (*v3.PodSecurityPolicyTemplateProjectBinding, error) {
return l.sync(obj)
}
func (l *lifecycle) Remove(obj *v3.PodSecurityPolicyTemplateProjectBinding) (*v3.PodSecurityPolicyTemplateProjectBinding, error) {
return obj, l.syncNamespacesInProject(obj.TargetProjectName)
}
func (l *lifecycle) sync(obj *v3.PodSecurityPolicyTemplateProjectBinding) (*v3.PodSecurityPolicyTemplateProjectBinding, error) {
if obj.PodSecurityPolicyTemplateName == "" {
return obj, nil
}
podSecurityPolicyName := fmt.Sprintf("%v-psp", obj.PodSecurityPolicyTemplateName)
_, err := l.policyLister.Get("", podSecurityPolicyName)
if err != nil {
if errors.IsNotFound(err) {
_, err = l.createPolicy(obj, podSecurityPolicyName)
if err != nil {
return nil, fmt.Errorf("error creating policy: %v", err)
}
} else {
return nil, fmt.Errorf("error getting policy: %v", err)
}
}
clusterRoleName := fmt.Sprintf("%v-clusterrole", obj.PodSecurityPolicyTemplateName)
_, err = l.clusterRoleLister.Get("", clusterRoleName)
if err != nil {
if errors.IsNotFound(err) {
_, err = l.createClusterRole(clusterRoleName, podSecurityPolicyName, obj)
if err != nil {
return nil, fmt.Errorf("error creating cluster role: %v", err)
}
} else {
return nil, fmt.Errorf("error getting cluster role: %v", err)
}
}
return obj, l.syncNamespacesInProject(obj.TargetProjectName)
}
func (l *lifecycle) createPolicy(obj *v3.PodSecurityPolicyTemplateProjectBinding,
podSecurityPolicyName string) (*v1beta13.PodSecurityPolicy, error) {
template, err := l.psptLister.Get("", obj.PodSecurityPolicyTemplateName)
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,
}
return l.policies.Create(psp)
}
func (l *lifecycle) createClusterRole(clusterRoleName string, podSecurityPolicyName string,
obj *v3.PodSecurityPolicyTemplateProjectBinding) (*rbac.ClusterRole, error) {
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.PodSecurityPolicyTemplateName
return l.clusterRoles.Create(newRole)
}
func (l *lifecycle) syncNamespacesInProject(projectName string) error {
namespaces, err := l.namespaceIndexer.ByIndex(namespaceByProjectNameIndex, projectName)
if err != nil {
return fmt.Errorf("error getting namespaces")
}
for _, rawNamespace := range namespaces {
namespace, ok := rawNamespace.(*v13.Namespace)
if !ok {
return fmt.Errorf("error converting to namespace: %v", rawNamespace)
}
l.namespaces.Controller().Enqueue("", namespace.Name)
}
return nil
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/rancher/rancher.git
git@gitee.com:rancher/rancher.git
rancher
rancher
rancher
v2.1.13-rc2

搜索帮助