未验证 提交 50a50e52 编写于 作者: K KubeSphere CI Bot 提交者: GitHub

Merge pull request #2782 from zryfish/fix_miss_caching_federatedworkspace

fix mistakenly caching federatedworkspace in non multicluster env
...@@ -60,25 +60,20 @@ const ( ...@@ -60,25 +60,20 @@ const (
controllerName = "workspacetemplate-controller" controllerName = "workspacetemplate-controller"
) )
type Controller struct { type controller struct {
k8sClient kubernetes.Interface k8sClient kubernetes.Interface
ksClient kubesphere.Interface ksClient kubesphere.Interface
workspaceTemplateInformer tenantv1alpha2informers.WorkspaceTemplateInformer workspaceTemplateLister tenantv1alpha2listers.WorkspaceTemplateLister
workspaceTemplateLister tenantv1alpha2listers.WorkspaceTemplateLister workspaceTemplateSynced cache.InformerSynced
workspaceTemplateSynced cache.InformerSynced workspaceRoleLister iamv1alpha2listers.WorkspaceRoleLister
workspaceRoleInformer iamv1alpha2informers.WorkspaceRoleInformer workspaceRoleSynced cache.InformerSynced
workspaceRoleLister iamv1alpha2listers.WorkspaceRoleLister roleBaseLister iamv1alpha2listers.RoleBaseLister
workspaceRoleSynced cache.InformerSynced roleBaseSynced cache.InformerSynced
roleBaseInformer iamv1alpha2informers.RoleBaseInformer workspaceLister tenantv1alpha1listers.WorkspaceLister
roleBaseLister iamv1alpha2listers.RoleBaseLister workspaceSynced cache.InformerSynced
roleBaseSynced cache.InformerSynced federatedWorkspaceLister typesv1beta1listers.FederatedWorkspaceLister
workspaceInformer tenantv1alpha1informers.WorkspaceInformer federatedWorkspaceSynced cache.InformerSynced
workspaceLister tenantv1alpha1listers.WorkspaceLister multiClusterEnabled bool
workspaceSynced cache.InformerSynced
federatedWorkspaceInformer typesv1beta1informers.FederatedWorkspaceInformer
federatedWorkspaceLister typesv1beta1listers.FederatedWorkspaceLister
federatedWorkspaceSynced cache.InformerSynced
multiClusterEnabled bool
// workqueue is a rate limited work queue. This is used to queue work to be // workqueue is a rate limited work queue. This is used to queue work to be
// processed instead of performing it as soon as a change happens. This // processed instead of performing it as soon as a change happens. This
// means we can ensure we only process a fixed amount of resources at a // means we can ensure we only process a fixed amount of resources at a
...@@ -96,38 +91,34 @@ func NewController(k8sClient kubernetes.Interface, ksClient kubesphere.Interface ...@@ -96,38 +91,34 @@ func NewController(k8sClient kubernetes.Interface, ksClient kubesphere.Interface
roleBaseInformer iamv1alpha2informers.RoleBaseInformer, roleBaseInformer iamv1alpha2informers.RoleBaseInformer,
workspaceRoleInformer iamv1alpha2informers.WorkspaceRoleInformer, workspaceRoleInformer iamv1alpha2informers.WorkspaceRoleInformer,
federatedWorkspaceInformer typesv1beta1informers.FederatedWorkspaceInformer, federatedWorkspaceInformer typesv1beta1informers.FederatedWorkspaceInformer,
multiClusterEnabled bool) *Controller { multiClusterEnabled bool) *controller {
// Create event broadcaster
// Add sample-controller types to the default Kubernetes Scheme so Events can be
// logged for sample-controller types.
klog.V(4).Info("Creating event broadcaster") klog.V(4).Info("Creating event broadcaster")
eventBroadcaster := record.NewBroadcaster() eventBroadcaster := record.NewBroadcaster()
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})
ctl := &Controller{ ctl := &controller{
k8sClient: k8sClient, k8sClient: k8sClient,
ksClient: ksClient, ksClient: ksClient,
workspaceTemplateInformer: workspaceTemplateInformer, workspaceTemplateLister: workspaceTemplateInformer.Lister(),
workspaceTemplateLister: workspaceTemplateInformer.Lister(), workspaceTemplateSynced: workspaceTemplateInformer.Informer().HasSynced,
workspaceTemplateSynced: workspaceTemplateInformer.Informer().HasSynced, workspaceLister: workspaceInformer.Lister(),
workspaceInformer: workspaceInformer, workspaceSynced: workspaceInformer.Informer().HasSynced,
workspaceLister: workspaceInformer.Lister(), workspaceRoleLister: workspaceRoleInformer.Lister(),
workspaceSynced: workspaceInformer.Informer().HasSynced, workspaceRoleSynced: workspaceRoleInformer.Informer().HasSynced,
workspaceRoleInformer: workspaceRoleInformer, roleBaseLister: roleBaseInformer.Lister(),
workspaceRoleLister: workspaceRoleInformer.Lister(), roleBaseSynced: roleBaseInformer.Informer().HasSynced,
workspaceRoleSynced: workspaceRoleInformer.Informer().HasSynced, multiClusterEnabled: multiClusterEnabled,
roleBaseInformer: roleBaseInformer, workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "WorkspaceTemplate"),
roleBaseLister: roleBaseInformer.Lister(), recorder: recorder,
roleBaseSynced: roleBaseInformer.Informer().HasSynced,
federatedWorkspaceInformer: federatedWorkspaceInformer,
federatedWorkspaceLister: federatedWorkspaceInformer.Lister(),
federatedWorkspaceSynced: federatedWorkspaceInformer.Informer().HasSynced,
multiClusterEnabled: multiClusterEnabled,
workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "WorkspaceTemplate"),
recorder: recorder,
} }
if multiClusterEnabled {
ctl.federatedWorkspaceLister = federatedWorkspaceInformer.Lister()
ctl.federatedWorkspaceSynced = federatedWorkspaceInformer.Informer().HasSynced
}
klog.Info("Setting up event handlers") klog.Info("Setting up event handlers")
workspaceTemplateInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ workspaceTemplateInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: ctl.enqueueWorkspaceTemplate, AddFunc: ctl.enqueueWorkspaceTemplate,
...@@ -139,7 +130,7 @@ func NewController(k8sClient kubernetes.Interface, ksClient kubesphere.Interface ...@@ -139,7 +130,7 @@ func NewController(k8sClient kubernetes.Interface, ksClient kubesphere.Interface
return ctl return ctl
} }
func (c *Controller) Run(threadiness int, stopCh <-chan struct{}) error { func (c *controller) Run(threadiness int, stopCh <-chan struct{}) error {
defer utilruntime.HandleCrash() defer utilruntime.HandleCrash()
defer c.workqueue.ShutDown() defer c.workqueue.ShutDown()
...@@ -170,7 +161,7 @@ func (c *Controller) Run(threadiness int, stopCh <-chan struct{}) error { ...@@ -170,7 +161,7 @@ func (c *Controller) Run(threadiness int, stopCh <-chan struct{}) error {
return nil return nil
} }
func (c *Controller) enqueueWorkspaceTemplate(obj interface{}) { func (c *controller) enqueueWorkspaceTemplate(obj interface{}) {
var key string var key string
var err error var err error
if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil { if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil {
...@@ -180,51 +171,31 @@ func (c *Controller) enqueueWorkspaceTemplate(obj interface{}) { ...@@ -180,51 +171,31 @@ func (c *Controller) enqueueWorkspaceTemplate(obj interface{}) {
c.workqueue.Add(key) c.workqueue.Add(key)
} }
func (c *Controller) runWorker() { func (c *controller) runWorker() {
for c.processNextWorkItem() { for c.processNextWorkItem() {
} }
} }
func (c *Controller) processNextWorkItem() bool { func (c *controller) processNextWorkItem() bool {
obj, shutdown := c.workqueue.Get() obj, shutdown := c.workqueue.Get()
if shutdown { if shutdown {
return false return false
} }
// We wrap this block in a func so we can defer c.workqueue.Done.
err := func(obj interface{}) error { err := func(obj interface{}) error {
// We call Done here so the workqueue knows we have finished
// processing this item. We also must remember to call Forget if we
// do not want this work item being re-queued. For example, we do
// not call Forget if a transient error occurs, instead the item is
// put back on the workqueue and attempted again after a back-off
// period.
defer c.workqueue.Done(obj) defer c.workqueue.Done(obj)
var key string var key string
var ok bool var ok bool
// We expect strings to come off the workqueue. These are of the
// form namespace/name. We do this as the delayed nature of the
// workqueue means the items in the informer cache may actually be
// more up to date that when the item was initially put onto the
// workqueue.
if key, ok = obj.(string); !ok { if key, ok = obj.(string); !ok {
// As the item in the workqueue is actually invalid, we call
// Forget here else we'd go into a loop of attempting to
// process a work item that is invalid.
c.workqueue.Forget(obj) c.workqueue.Forget(obj)
utilruntime.HandleError(fmt.Errorf("expected string in workqueue but got %#v", obj)) utilruntime.HandleError(fmt.Errorf("expected string in workqueue but got %#v", obj))
return nil return nil
} }
// Run the reconcile, passing it the namespace/name string of the
// Foo resource to be synced.
if err := c.reconcile(key); err != nil { if err := c.reconcile(key); err != nil {
// Put the item back on the workqueue to handle any transient errors.
c.workqueue.AddRateLimited(key) c.workqueue.AddRateLimited(key)
return fmt.Errorf("error syncing '%s': %s, requeuing", key, err.Error()) return fmt.Errorf("error syncing '%s': %s, requeuing", key, err.Error())
} }
// Finally, if no error occurs we Forget this item so it does not
// get queued again until another change happens.
c.workqueue.Forget(obj) c.workqueue.Forget(obj)
klog.Infof("Successfully synced %s:%s", "key", key) klog.Infof("Successfully synced %s:%s", "key", key)
return nil return nil
...@@ -241,7 +212,7 @@ func (c *Controller) processNextWorkItem() bool { ...@@ -241,7 +212,7 @@ func (c *Controller) processNextWorkItem() bool {
// syncHandler compares the actual state with the desired, and attempts to // syncHandler compares the actual state with the desired, and attempts to
// converge the two. It then updates the Status block of the Foo resource // converge the two. It then updates the Status block of the Foo resource
// with the current status of the resource. // with the current status of the resource.
func (c *Controller) reconcile(key string) error { func (c *controller) reconcile(key string) error {
workspaceTemplate, err := c.workspaceTemplateLister.Get(key) workspaceTemplate, err := c.workspaceTemplateLister.Get(key)
if err != nil { if err != nil {
// The user may no longer exist, in which case we stop // The user may no longer exist, in which case we stop
...@@ -280,11 +251,11 @@ func (c *Controller) reconcile(key string) error { ...@@ -280,11 +251,11 @@ func (c *Controller) reconcile(key string) error {
return nil return nil
} }
func (c *Controller) Start(stopCh <-chan struct{}) error { func (c *controller) Start(stopCh <-chan struct{}) error {
return c.Run(4, stopCh) return c.Run(4, stopCh)
} }
func (c *Controller) multiClusterSync(workspaceTemplate *tenantv1alpha2.WorkspaceTemplate) error { func (c *controller) multiClusterSync(workspaceTemplate *tenantv1alpha2.WorkspaceTemplate) error {
// multi cluster environment, synchronize workspaces with kubefed // multi cluster environment, synchronize workspaces with kubefed
federatedWorkspace, err := c.federatedWorkspaceLister.Get(workspaceTemplate.Name) federatedWorkspace, err := c.federatedWorkspaceLister.Get(workspaceTemplate.Name)
if err != nil { if err != nil {
...@@ -298,7 +269,7 @@ func (c *Controller) multiClusterSync(workspaceTemplate *tenantv1alpha2.Workspac ...@@ -298,7 +269,7 @@ func (c *Controller) multiClusterSync(workspaceTemplate *tenantv1alpha2.Workspac
// update spec // update spec
if !reflect.DeepEqual(federatedWorkspace.Spec, workspaceTemplate.Spec) { if !reflect.DeepEqual(federatedWorkspace.Spec, workspaceTemplate.Spec) {
federatedWorkspace.Spec = workspaceTemplate.Spec federatedWorkspace.Spec = workspaceTemplate.Spec
if err := c.updateFederatedWorkspace(federatedWorkspace); err != nil { if err = c.updateFederatedWorkspace(federatedWorkspace); err != nil {
klog.Error(err) klog.Error(err)
return err return err
} }
...@@ -307,7 +278,7 @@ func (c *Controller) multiClusterSync(workspaceTemplate *tenantv1alpha2.Workspac ...@@ -307,7 +278,7 @@ func (c *Controller) multiClusterSync(workspaceTemplate *tenantv1alpha2.Workspac
return nil return nil
} }
func (c *Controller) createFederatedWorkspace(workspaceTemplate *tenantv1alpha2.WorkspaceTemplate) error { func (c *controller) createFederatedWorkspace(workspaceTemplate *tenantv1alpha2.WorkspaceTemplate) error {
federatedWorkspace := &typesv1beta1.FederatedWorkspace{ federatedWorkspace := &typesv1beta1.FederatedWorkspace{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: workspaceTemplate.Name, Name: workspaceTemplate.Name,
...@@ -330,7 +301,7 @@ func (c *Controller) createFederatedWorkspace(workspaceTemplate *tenantv1alpha2. ...@@ -330,7 +301,7 @@ func (c *Controller) createFederatedWorkspace(workspaceTemplate *tenantv1alpha2.
return nil return nil
} }
func (c *Controller) sync(workspaceTemplate *tenantv1alpha2.WorkspaceTemplate) error { func (c *controller) sync(workspaceTemplate *tenantv1alpha2.WorkspaceTemplate) error {
workspace, err := c.workspaceLister.Get(workspaceTemplate.Name) workspace, err := c.workspaceLister.Get(workspaceTemplate.Name)
if err != nil { if err != nil {
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
...@@ -355,7 +326,7 @@ func (c *Controller) sync(workspaceTemplate *tenantv1alpha2.WorkspaceTemplate) e ...@@ -355,7 +326,7 @@ func (c *Controller) sync(workspaceTemplate *tenantv1alpha2.WorkspaceTemplate) e
return nil return nil
} }
func (c *Controller) createWorkspace(workspaceTemplate *tenantv1alpha2.WorkspaceTemplate) error { func (c *controller) createWorkspace(workspaceTemplate *tenantv1alpha2.WorkspaceTemplate) error {
workspace := &tenantv1alpha1.Workspace{ workspace := &tenantv1alpha1.Workspace{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: workspaceTemplate.Name, Name: workspaceTemplate.Name,
...@@ -382,7 +353,7 @@ func (c *Controller) createWorkspace(workspaceTemplate *tenantv1alpha2.Workspace ...@@ -382,7 +353,7 @@ func (c *Controller) createWorkspace(workspaceTemplate *tenantv1alpha2.Workspace
return nil return nil
} }
func (c *Controller) updateWorkspace(workspace *tenantv1alpha1.Workspace) error { func (c *controller) updateWorkspace(workspace *tenantv1alpha1.Workspace) error {
_, err := c.ksClient.TenantV1alpha1().Workspaces().Update(workspace) _, err := c.ksClient.TenantV1alpha1().Workspaces().Update(workspace)
if err != nil { if err != nil {
klog.Error(err) klog.Error(err)
...@@ -391,8 +362,8 @@ func (c *Controller) updateWorkspace(workspace *tenantv1alpha1.Workspace) error ...@@ -391,8 +362,8 @@ func (c *Controller) updateWorkspace(workspace *tenantv1alpha1.Workspace) error
return nil return nil
} }
func (r *Controller) initRoles(workspace *tenantv1alpha2.WorkspaceTemplate) error { func (c *controller) initRoles(workspace *tenantv1alpha2.WorkspaceTemplate) error {
roleBases, err := r.roleBaseLister.List(labels.Everything()) roleBases, err := c.roleBaseLister.List(labels.Everything())
if err != nil { if err != nil {
klog.Error(err) klog.Error(err)
return err return err
...@@ -407,10 +378,10 @@ func (r *Controller) initRoles(workspace *tenantv1alpha2.WorkspaceTemplate) erro ...@@ -407,10 +378,10 @@ func (r *Controller) initRoles(workspace *tenantv1alpha2.WorkspaceTemplate) erro
// make sure workspace label always exist // make sure workspace label always exist
role.Labels[tenantv1alpha1.WorkspaceLabel] = workspace.Name role.Labels[tenantv1alpha1.WorkspaceLabel] = workspace.Name
role.Name = roleName role.Name = roleName
old, err := r.workspaceRoleLister.Get(roleName) old, err := c.workspaceRoleLister.Get(roleName)
if err != nil { if err != nil {
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
_, err = r.ksClient.IamV1alpha2().WorkspaceRoles().Create(&role) _, err = c.ksClient.IamV1alpha2().WorkspaceRoles().Create(&role)
if err != nil { if err != nil {
klog.Error(err) klog.Error(err)
return err return err
...@@ -425,7 +396,7 @@ func (r *Controller) initRoles(workspace *tenantv1alpha2.WorkspaceTemplate) erro ...@@ -425,7 +396,7 @@ func (r *Controller) initRoles(workspace *tenantv1alpha2.WorkspaceTemplate) erro
updated.Labels = role.Labels updated.Labels = role.Labels
updated.Annotations = role.Annotations updated.Annotations = role.Annotations
updated.Rules = role.Rules updated.Rules = role.Rules
_, err = r.ksClient.IamV1alpha2().WorkspaceRoles().Update(updated) _, err = c.ksClient.IamV1alpha2().WorkspaceRoles().Update(updated)
if err != nil { if err != nil {
klog.Error(err) klog.Error(err)
return err return err
...@@ -436,25 +407,25 @@ func (r *Controller) initRoles(workspace *tenantv1alpha2.WorkspaceTemplate) erro ...@@ -436,25 +407,25 @@ func (r *Controller) initRoles(workspace *tenantv1alpha2.WorkspaceTemplate) erro
return nil return nil
} }
func (r *Controller) resetWorkspaceOwner(workspace *tenantv1alpha2.WorkspaceTemplate) error { func (c *controller) resetWorkspaceOwner(workspace *tenantv1alpha2.WorkspaceTemplate) error {
workspace = workspace.DeepCopy() workspace = workspace.DeepCopy()
workspace.Spec.Template.Spec.Manager = "" workspace.Spec.Template.Spec.Manager = ""
_, err := r.ksClient.TenantV1alpha2().WorkspaceTemplates().Update(workspace) _, err := c.ksClient.TenantV1alpha2().WorkspaceTemplates().Update(workspace)
klog.V(4).Infof("update workspace after manager has been deleted") klog.V(4).Infof("update workspace after manager has been deleted")
return err return err
} }
func (r *Controller) initManagerRoleBinding(workspace *tenantv1alpha2.WorkspaceTemplate) error { func (c *controller) initManagerRoleBinding(workspace *tenantv1alpha2.WorkspaceTemplate) error {
manager := workspace.Spec.Template.Spec.Manager manager := workspace.Spec.Template.Spec.Manager
if manager == "" { if manager == "" {
return nil return nil
} }
user, err := r.ksClient.IamV1alpha2().Users().Get(manager, metav1.GetOptions{}) user, err := c.ksClient.IamV1alpha2().Users().Get(manager, metav1.GetOptions{})
if err != nil { if err != nil {
// skip if user has been deleted // skip if user has been deleted
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
return r.resetWorkspaceOwner(workspace) return c.resetWorkspaceOwner(workspace)
} }
klog.Error(err) klog.Error(err)
return err return err
...@@ -462,7 +433,7 @@ func (r *Controller) initManagerRoleBinding(workspace *tenantv1alpha2.WorkspaceT ...@@ -462,7 +433,7 @@ func (r *Controller) initManagerRoleBinding(workspace *tenantv1alpha2.WorkspaceT
// skip if user has been deleted // skip if user has been deleted
if !user.DeletionTimestamp.IsZero() { if !user.DeletionTimestamp.IsZero() {
return r.resetWorkspaceOwner(workspace) return c.resetWorkspaceOwner(workspace)
} }
workspaceAdminRoleName := fmt.Sprintf(iamv1alpha2.WorkspaceAdminFormat, workspace.Name) workspaceAdminRoleName := fmt.Sprintf(iamv1alpha2.WorkspaceAdminFormat, workspace.Name)
...@@ -487,7 +458,7 @@ func (r *Controller) initManagerRoleBinding(workspace *tenantv1alpha2.WorkspaceT ...@@ -487,7 +458,7 @@ func (r *Controller) initManagerRoleBinding(workspace *tenantv1alpha2.WorkspaceT
}, },
}, },
} }
_, err = r.ksClient.IamV1alpha2().WorkspaceRoleBindings().Create(managerRoleBinding) _, err = c.ksClient.IamV1alpha2().WorkspaceRoleBindings().Create(managerRoleBinding)
if err != nil { if err != nil {
if errors.IsAlreadyExists(err) { if errors.IsAlreadyExists(err) {
return nil return nil
...@@ -499,7 +470,7 @@ func (r *Controller) initManagerRoleBinding(workspace *tenantv1alpha2.WorkspaceT ...@@ -499,7 +470,7 @@ func (r *Controller) initManagerRoleBinding(workspace *tenantv1alpha2.WorkspaceT
return nil return nil
} }
func (c *Controller) updateFederatedWorkspace(workspace *typesv1beta1.FederatedWorkspace) error { func (c *controller) updateFederatedWorkspace(workspace *typesv1beta1.FederatedWorkspace) error {
_, err := c.ksClient.TypesV1beta1().FederatedWorkspaces().Update(workspace) _, err := c.ksClient.TypesV1beta1().FederatedWorkspaces().Update(workspace)
if err != nil { if err != nil {
klog.Error(err) klog.Error(err)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册