未验证 提交 57acaeba 编写于 作者: H hongming

use ownerReference control the lifecycle of user's kubeconfig and kubectl pod

Signed-off-by: Nhongming <talonwan@yunify.com>
上级 8f93266e
...@@ -124,7 +124,7 @@ func AddControllers( ...@@ -124,7 +124,7 @@ func AddControllers(
csrController := certificatesigningrequest.NewController(client.Kubernetes(), kubernetesInformer, client.Config()) csrController := certificatesigningrequest.NewController(client.Kubernetes(), kubernetesInformer, client.Config())
clusterRoleBindingController := clusterrolebinding.NewController(client.Kubernetes(), kubernetesInformer) clusterRoleBindingController := clusterrolebinding.NewController(client.Kubernetes(), kubernetesInformer, kubesphereInformer)
clusterController := cluster.NewClusterController( clusterController := cluster.NewClusterController(
client.Kubernetes(), client.Kubernetes(),
......
...@@ -38,7 +38,7 @@ const ( ...@@ -38,7 +38,7 @@ const (
DisplayNameAnnotationKey = "kubesphere.io/alias-name" DisplayNameAnnotationKey = "kubesphere.io/alias-name"
DescriptionAnnotationKey = "kubesphere.io/description" DescriptionAnnotationKey = "kubesphere.io/description"
CreatorAnnotationKey = "kubesphere.io/creator" CreatorAnnotationKey = "kubesphere.io/creator"
UsernameAnnotationKey = "kubesphere.io/username" UsernameLabelKey = "kubesphere.io/username"
System = "system" System = "system"
OpenPitrixRuntimeAnnotationKey = "openpitrix_runtime" OpenPitrixRuntimeAnnotationKey = "openpitrix_runtime"
WorkspaceAdmin = "workspace-admin" WorkspaceAdmin = "workspace-admin"
......
...@@ -221,7 +221,7 @@ func (c *Controller) reconcile(key string) error { ...@@ -221,7 +221,7 @@ func (c *Controller) reconcile(key string) error {
} }
// csr create by kubesphere auto approve // csr create by kubesphere auto approve
if username := csr.Annotations[constants.UsernameAnnotationKey]; username != "" { if username := csr.Labels[constants.UsernameLabelKey]; username != "" {
err = c.Approve(csr) err = c.Approve(csr)
if err != nil { if err != nil {
klog.Error(err) klog.Error(err)
...@@ -280,7 +280,7 @@ func (c *Controller) Approve(csr *certificatesv1beta1.CertificateSigningRequest) ...@@ -280,7 +280,7 @@ func (c *Controller) Approve(csr *certificatesv1beta1.CertificateSigningRequest)
} }
func (c *Controller) UpdateKubeconfig(csr *certificatesv1beta1.CertificateSigningRequest) error { func (c *Controller) UpdateKubeconfig(csr *certificatesv1beta1.CertificateSigningRequest) error {
username := csr.Annotations[constants.UsernameAnnotationKey] username := csr.Labels[constants.UsernameLabelKey]
err := c.kubeconfigOperator.UpdateKubeconfig(username, csr.Status.Certificate) err := c.kubeconfigOperator.UpdateKubeconfig(username, csr.Status.Certificate)
......
...@@ -23,7 +23,7 @@ import ( ...@@ -23,7 +23,7 @@ import (
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
utilruntime "k8s.io/apimachinery/pkg/util/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/informers" k8sinformers "k8s.io/client-go/informers"
rbacv1informers "k8s.io/client-go/informers/rbac/v1" rbacv1informers "k8s.io/client-go/informers/rbac/v1"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/kubernetes/scheme"
...@@ -34,6 +34,7 @@ import ( ...@@ -34,6 +34,7 @@ import (
"k8s.io/client-go/util/workqueue" "k8s.io/client-go/util/workqueue"
"k8s.io/klog" "k8s.io/klog"
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2" iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
"kubesphere.io/kubesphere/pkg/models/kubectl" "kubesphere.io/kubesphere/pkg/models/kubectl"
"time" "time"
) )
...@@ -63,7 +64,7 @@ type Controller struct { ...@@ -63,7 +64,7 @@ type Controller struct {
kubectlOperator kubectl.Interface kubectlOperator kubectl.Interface
} }
func NewController(k8sClient kubernetes.Interface, informerFactory informers.SharedInformerFactory) *Controller { func NewController(k8sClient kubernetes.Interface, k8sInformer k8sinformers.SharedInformerFactory, ksInformer ksinformers.SharedInformerFactory) *Controller {
// Create event broadcaster // Create event broadcaster
// Add sample-controller types to the default Kubernetes Scheme so Events can be // Add sample-controller types to the default Kubernetes Scheme so Events can be
// logged for sample-controller types. // logged for sample-controller types.
...@@ -73,13 +74,13 @@ func NewController(k8sClient kubernetes.Interface, informerFactory informers.Sha ...@@ -73,13 +74,13 @@ func NewController(k8sClient kubernetes.Interface, informerFactory informers.Sha
eventBroadcaster.StartLogging(klog.Infof) eventBroadcaster.StartLogging(klog.Infof)
eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: k8sClient.CoreV1().Events("")}) eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: k8sClient.CoreV1().Events("")})
recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: controllerName}) recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: controllerName})
informer := informerFactory.Rbac().V1().ClusterRoleBindings() informer := k8sInformer.Rbac().V1().ClusterRoleBindings()
ctl := &Controller{ ctl := &Controller{
k8sClient: k8sClient, k8sClient: k8sClient,
informer: informer, informer: informer,
lister: informer.Lister(), lister: informer.Lister(),
synced: informer.Informer().HasSynced, synced: informer.Informer().HasSynced,
kubectlOperator: kubectl.NewOperator(k8sClient, informerFactory), kubectlOperator: kubectl.NewOperator(k8sClient, k8sInformer, ksInformer),
workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "ClusterRoleBinding"), workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "ClusterRoleBinding"),
recorder: recorder, recorder: recorder,
} }
......
...@@ -49,7 +49,8 @@ func newResourceHandler(k8sClient kubernetes.Interface, factory informers.Inform ...@@ -49,7 +49,8 @@ func newResourceHandler(k8sClient kubernetes.Interface, factory informers.Inform
gitVerifier: git.NewGitVerifier(factory.KubernetesSharedInformerFactory()), gitVerifier: git.NewGitVerifier(factory.KubernetesSharedInformerFactory()),
registryGetter: registries.NewRegistryGetter(factory.KubernetesSharedInformerFactory()), registryGetter: registries.NewRegistryGetter(factory.KubernetesSharedInformerFactory()),
kubeconfigOperator: kubeconfig.NewOperator(k8sClient, nil, masterURL), kubeconfigOperator: kubeconfig.NewOperator(k8sClient, nil, masterURL),
kubectlOperator: kubectl.NewOperator(k8sClient, factory.KubernetesSharedInformerFactory()), kubectlOperator: kubectl.NewOperator(k8sClient, factory.KubernetesSharedInformerFactory(),
factory.KubeSphereSharedInformerFactory()),
} }
} }
......
...@@ -58,7 +58,6 @@ const ( ...@@ -58,7 +58,6 @@ const (
type Interface interface { type Interface interface {
GetKubeConfig(username string) (string, error) GetKubeConfig(username string) (string, error)
CreateKubeConfig(user *iamv1alpha2.User) error CreateKubeConfig(user *iamv1alpha2.User) error
DelKubeConfig(username string) error
UpdateKubeconfig(username string, certificate []byte) error UpdateKubeconfig(username string, certificate []byte) error
} }
...@@ -135,7 +134,7 @@ func (o *operator) CreateKubeConfig(user *iamv1alpha2.User) error { ...@@ -135,7 +134,7 @@ func (o *operator) CreateKubeConfig(user *iamv1alpha2.User) error {
} }
cm := &corev1.ConfigMap{TypeMeta: metav1.TypeMeta{Kind: configMapKind, APIVersion: configMapAPIVersion}, cm := &corev1.ConfigMap{TypeMeta: metav1.TypeMeta{Kind: configMapKind, APIVersion: configMapAPIVersion},
ObjectMeta: metav1.ObjectMeta{Name: configName, Annotations: map[string]string{constants.UsernameAnnotationKey: user.Name}}, ObjectMeta: metav1.ObjectMeta{Name: configName, Labels: map[string]string{constants.UsernameLabelKey: user.Name}},
Data: map[string]string{kubeconfigFileName: string(kubeconfig)}} Data: map[string]string{kubeconfigFileName: string(kubeconfig)}}
err = controllerutil.SetControllerReference(user, cm, scheme.Scheme) err = controllerutil.SetControllerReference(user, cm, scheme.Scheme)
...@@ -188,18 +187,6 @@ func (o *operator) GetKubeConfig(username string) (string, error) { ...@@ -188,18 +187,6 @@ func (o *operator) GetKubeConfig(username string) (string, error) {
return string(data), nil return string(data), nil
} }
func (o *operator) DelKubeConfig(username string) error {
configName := fmt.Sprintf(kubeconfigNameFormat, username)
deletePolicy := metav1.DeletePropagationBackground
err := o.k8sclient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Delete(configName, &metav1.DeleteOptions{PropagationPolicy: &deletePolicy})
if err != nil {
klog.Errorln(err)
return err
}
return nil
}
func (o *operator) createCSR(username string) ([]byte, error) { func (o *operator) createCSR(username string) ([]byte, error) {
csrConfig := &certutil.Config{ csrConfig := &certutil.Config{
CommonName: username, CommonName: username,
...@@ -248,7 +235,7 @@ func (o *operator) createCSR(username string) ([]byte, error) { ...@@ -248,7 +235,7 @@ func (o *operator) createCSR(username string) ([]byte, error) {
}, },
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: csrName, Name: csrName,
Annotations: map[string]string{constants.UsernameAnnotationKey: username}, Labels: map[string]string{constants.UsernameLabelKey: username},
}, },
Spec: certificatesv1beta1.CertificateSigningRequestSpec{ Spec: certificatesv1beta1.CertificateSigningRequestSpec{
Request: csr, Request: csr,
......
...@@ -20,18 +20,20 @@ package kubectl ...@@ -20,18 +20,20 @@ package kubectl
import ( import (
"fmt" "fmt"
appsv1 "k8s.io/api/apps/v1"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/client-go/informers" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
k8sinformers "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
"k8s.io/klog" "k8s.io/klog"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
"kubesphere.io/kubesphere/pkg/models" "kubesphere.io/kubesphere/pkg/models"
"math/rand" "math/rand"
"os" "os"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
appsv1 "k8s.io/api/apps/v1"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"kubesphere.io/kubesphere/pkg/constants" "kubesphere.io/kubesphere/pkg/constants"
) )
...@@ -44,16 +46,16 @@ const ( ...@@ -44,16 +46,16 @@ const (
type Interface interface { type Interface interface {
GetKubectlPod(username string) (models.PodInfo, error) GetKubectlPod(username string) (models.PodInfo, error)
CreateKubectlDeploy(username string) error CreateKubectlDeploy(username string) error
DeleteKubectlDeploy(username string) error
} }
type operator struct { type operator struct {
k8sClient kubernetes.Interface k8sClient kubernetes.Interface
informers informers.SharedInformerFactory k8sInformer k8sinformers.SharedInformerFactory
ksInformer ksinformers.SharedInformerFactory
} }
func NewOperator(k8sClient kubernetes.Interface, informers informers.SharedInformerFactory) Interface { func NewOperator(k8sClient kubernetes.Interface, k8sInformer k8sinformers.SharedInformerFactory, ksInformer ksinformers.SharedInformerFactory) Interface {
return &operator{k8sClient: k8sClient, informers: informers} return &operator{k8sClient: k8sClient, k8sInformer: k8sInformer, ksInformer: ksInformer}
} }
var DefaultImage = "kubesphere/kubectl:advanced-1.0.0" var DefaultImage = "kubesphere/kubectl:advanced-1.0.0"
...@@ -66,7 +68,7 @@ func init() { ...@@ -66,7 +68,7 @@ func init() {
func (o *operator) GetKubectlPod(username string) (models.PodInfo, error) { func (o *operator) GetKubectlPod(username string) (models.PodInfo, error) {
deployName := fmt.Sprintf(deployNameFormat, username) deployName := fmt.Sprintf(deployNameFormat, username)
deploy, err := o.informers.Apps().V1().Deployments().Lister().Deployments(namespace).Get(deployName) deploy, err := o.k8sInformer.Apps().V1().Deployments().Lister().Deployments(namespace).Get(deployName)
if err != nil { if err != nil {
klog.Errorln(err) klog.Errorln(err)
return models.PodInfo{}, err return models.PodInfo{}, err
...@@ -74,7 +76,7 @@ func (o *operator) GetKubectlPod(username string) (models.PodInfo, error) { ...@@ -74,7 +76,7 @@ func (o *operator) GetKubectlPod(username string) (models.PodInfo, error) {
selectors := deploy.Spec.Selector.MatchLabels selectors := deploy.Spec.Selector.MatchLabels
labelSelector := labels.Set(selectors).AsSelector() labelSelector := labels.Set(selectors).AsSelector()
pods, err := o.informers.Core().V1().Pods().Lister().Pods(namespace).List(labelSelector) pods, err := o.k8sInformer.Core().V1().Pods().Lister().Pods(namespace).List(labelSelector)
if err != nil { if err != nil {
klog.Errorln(err) klog.Errorln(err)
return models.PodInfo{}, err return models.PodInfo{}, err
...@@ -115,9 +117,20 @@ func selectCorrectPod(namespace string, pods []*v1.Pod) (kubectlPod *v1.Pod, err ...@@ -115,9 +117,20 @@ func selectCorrectPod(namespace string, pods []*v1.Pod) (kubectlPod *v1.Pod, err
func (o *operator) CreateKubectlDeploy(username string) error { func (o *operator) CreateKubectlDeploy(username string) error {
deployName := fmt.Sprintf(deployNameFormat, username) deployName := fmt.Sprintf(deployNameFormat, username)
user, err := o.ksInformer.Iam().V1alpha2().Users().Lister().Get(username)
if err != nil {
klog.Error(err)
// ignore if user not exist
if errors.IsNotFound(err) {
return nil
}
return err
}
replica := int32(1) replica := int32(1)
selector := metav1.LabelSelector{MatchLabels: map[string]string{"username": username}} selector := metav1.LabelSelector{MatchLabels: map[string]string{constants.UsernameLabelKey: username}}
deployment := appsv1.Deployment{ deployment := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: deployName, Name: deployName,
}, },
...@@ -127,7 +140,7 @@ func (o *operator) CreateKubectlDeploy(username string) error { ...@@ -127,7 +140,7 @@ func (o *operator) CreateKubectlDeploy(username string) error {
Template: v1.PodTemplateSpec{ Template: v1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{ Labels: map[string]string{
"username": username, constants.UsernameLabelKey: username,
}, },
}, },
Spec: v1.PodSpec{ Spec: v1.PodSpec{
...@@ -142,25 +155,17 @@ func (o *operator) CreateKubectlDeploy(username string) error { ...@@ -142,25 +155,17 @@ func (o *operator) CreateKubectlDeploy(username string) error {
}, },
} }
_, err := o.k8sClient.AppsV1().Deployments(namespace).Create(&deployment) err = controllerutil.SetControllerReference(user, deployment, scheme.Scheme)
if err != nil { if err != nil {
if errors.IsAlreadyExists(err) { klog.Errorln(err)
return nil
}
klog.Error(err)
return err return err
} }
return nil _, err = o.k8sClient.AppsV1().Deployments(namespace).Create(deployment)
}
func (o *operator) DeleteKubectlDeploy(username string) error {
deployName := fmt.Sprintf(deployNameFormat, username)
err := o.k8sClient.AppsV1().Deployments(namespace).Delete(deployName, metav1.NewDeleteOptions(0))
if err != nil { if err != nil {
if errors.IsNotFound(err) { if errors.IsAlreadyExists(err) {
return nil return nil
} }
klog.Error(err) klog.Error(err)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册