Skip to content

Commit 3419695

Browse files
authored
fix: namespace cache delete actions (#5887)
* namespace cache operations on cluster deletion * wip * fixing nil value of k8s service * k8s informer factory nil handling * common function for cluster secret
1 parent 0282dee commit 3419695

File tree

8 files changed

+74
-25
lines changed

8 files changed

+74
-25
lines changed

cmd/external-app/wire_gen.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/cluster/ClusterService.go

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ const (
5656
CLUSTER_MODIFY_EVENT_SECRET_TYPE = "cluster.request/modify"
5757
CLUSTER_ACTION_ADD = "add"
5858
CLUSTER_ACTION_UPDATE = "update"
59-
SECRET_NAME = "cluster-event"
6059
SECRET_FIELD_CLUSTER_ID = "cluster_id"
6160
SECRET_FIELD_UPDATED_ON = "updated_on"
6261
SECRET_FIELD_ACTION = "action"
@@ -167,7 +166,7 @@ type ClusterService interface {
167166
FindAllExceptVirtual() ([]*ClusterBean, error)
168167
FindAllWithoutConfig() ([]*ClusterBean, error)
169168
FindAllActive() ([]ClusterBean, error)
170-
DeleteFromDb(bean *ClusterBean, userId int32) error
169+
DeleteFromDb(bean *ClusterBean, userId int32) (string, error)
171170

172171
FindById(id int) (*ClusterBean, error)
173172
FindByIdWithoutConfig(id int) (*ClusterBean, error)
@@ -331,7 +330,7 @@ func (impl *ClusterServiceImpl) Save(parent context.Context, bean *ClusterBean,
331330
return bean, nil
332331
}
333332
//creating cluster secret, this secret will be read informer in kubelink to know that a new cluster has been added
334-
secretName := fmt.Sprintf("%s-%v", SECRET_NAME, bean.Id)
333+
secretName := ParseSecretNameForKubelinkInformer(bean.Id)
335334

336335
data := make(map[string][]byte)
337336
data[SECRET_FIELD_CLUSTER_ID] = []byte(fmt.Sprintf("%v", bean.Id))
@@ -572,7 +571,7 @@ func (impl *ClusterServiceImpl) Update(ctx context.Context, bean *ClusterBean, u
572571
}
573572
// below secret will act as an event for informer running on secret object in kubelink
574573
if bean.HasConfigOrUrlChanged {
575-
secretName := fmt.Sprintf("%s-%v", SECRET_NAME, bean.Id)
574+
secretName := ParseSecretNameForKubelinkInformer(bean.Id)
576575
secret, err := impl.K8sUtil.GetSecret(DEFAULT_NAMESPACE, secretName, k8sClient)
577576
statusError, _ := err.(*errors.StatusError)
578577
if err != nil && statusError.Status().Code != http.StatusNotFound {
@@ -675,29 +674,29 @@ func (impl *ClusterServiceImpl) buildInformer() {
675674
impl.K8sInformerFactory.BuildInformer(clusterInfo)
676675
}
677676

678-
func (impl *ClusterServiceImpl) DeleteFromDb(bean *ClusterBean, userId int32) error {
677+
func (impl *ClusterServiceImpl) DeleteFromDb(bean *ClusterBean, userId int32) (string, error) {
679678
existingCluster, err := impl.clusterRepository.FindById(bean.Id)
680679
if err != nil {
681680
impl.logger.Errorw("No matching entry found for delete.", "id", bean.Id)
682-
return err
681+
return "", err
683682
}
684683
deleteReq := existingCluster
685684
deleteReq.UpdatedOn = time.Now()
686685
deleteReq.UpdatedBy = userId
687686
err = impl.clusterRepository.MarkClusterDeleted(deleteReq)
688687
if err != nil {
689688
impl.logger.Errorw("error in deleting cluster", "id", bean.Id, "err", err)
690-
return err
689+
return "", err
691690
}
692691
k8sClient, err := impl.K8sUtil.GetCoreV1ClientInCluster()
693692
if err != nil {
694693
impl.logger.Errorw("error in getting in cluster k8s client", "err", err, "clusterName", bean.ClusterName)
695-
return nil
694+
return "", nil
696695
}
697-
secretName := fmt.Sprintf("%s-%v", SECRET_NAME, bean.Id)
696+
secretName := ParseSecretNameForKubelinkInformer(bean.Id)
698697
err = impl.K8sUtil.DeleteSecret(DEFAULT_NAMESPACE, secretName, k8sClient)
699698
impl.logger.Errorw("error in deleting secret", "error", err)
700-
return nil
699+
return existingCluster.ClusterName, nil
701700
}
702701

703702
func (impl *ClusterServiceImpl) CheckIfConfigIsValid(cluster *ClusterBean) error {

pkg/cluster/ClusterServiceExtended.go

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -381,26 +381,19 @@ func (impl *ClusterServiceImplExtended) Save(ctx context.Context, bean *ClusterB
381381
return clusterBean, nil
382382
}
383383

384-
func (impl ClusterServiceImplExtended) DeleteFromDb(bean *ClusterBean, userId int32) error {
384+
func (impl ClusterServiceImplExtended) DeleteFromDb(bean *ClusterBean, userId int32) (string, error) {
385385
existingCluster, err := impl.clusterRepository.FindById(bean.Id)
386386
if err != nil {
387387
impl.logger.Errorw("No matching entry found for delete.", "id", bean.Id)
388-
return err
388+
return "", err
389389
}
390390
deleteReq := existingCluster
391391
deleteReq.UpdatedOn = time.Now()
392392
deleteReq.UpdatedBy = userId
393393
err = impl.clusterRepository.MarkClusterDeleted(deleteReq)
394394
if err != nil {
395395
impl.logger.Errorw("error in deleting cluster", "id", bean.Id, "err", err)
396-
return err
396+
return "", err
397397
}
398-
k8sClient, err := impl.ClusterServiceImpl.K8sUtil.GetCoreV1ClientInCluster()
399-
if err != nil {
400-
impl.logger.Errorw("error in creating k8s client set", "err", err, "clusterName", bean.ClusterName)
401-
}
402-
secretName := fmt.Sprintf("%s-%v", "cluster-event", bean.Id)
403-
err = impl.K8sUtil.DeleteSecret("default", secretName, k8sClient)
404-
impl.logger.Errorw("error in deleting secret", "error", err)
405-
return nil
398+
return existingCluster.ClusterName, nil
406399
}

pkg/cluster/clusterUtil.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package cluster
2+
3+
import "fmt"
4+
5+
const (
6+
SECRET_NAME = "cluster-event"
7+
)
8+
9+
func ParseSecretNameForKubelinkInformer(clusterId int) string {
10+
return fmt.Sprintf("%s-%d", SECRET_NAME, clusterId)
11+
}

pkg/delete/DeleteService.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ package delete
1818

1919
import (
2020
"fmt"
21+
"github.com/devtron-labs/common-lib/utils/k8s"
2122
dockerRegistryRepository "github.com/devtron-labs/devtron/internal/sql/repository/dockerRegistry"
2223
"github.com/devtron-labs/devtron/pkg/appStore/installedApp/repository"
2324
"github.com/devtron-labs/devtron/pkg/chartRepo"
2425
"github.com/devtron-labs/devtron/pkg/cluster"
2526
"github.com/devtron-labs/devtron/pkg/cluster/repository/bean"
27+
"github.com/devtron-labs/devtron/pkg/k8s/informer"
2628
"github.com/devtron-labs/devtron/pkg/pipeline"
2729
"github.com/devtron-labs/devtron/pkg/pipeline/types"
2830
"github.com/devtron-labs/devtron/pkg/team"
@@ -37,6 +39,7 @@ type DeleteService interface {
3739
DeleteChartRepo(deleteRequest *chartRepo.ChartRepoDto) error
3840
DeleteDockerRegistryConfig(deleteRequest *types.DockerArtifactStoreBean) error
3941
CanDeleteChartRegistryPullConfig(storeId string) bool
42+
DeleteClusterSecret(deleteRequest *cluster.ClusterBean, err error) error
4043
}
4144

4245
type DeleteServiceImpl struct {
@@ -48,6 +51,8 @@ type DeleteServiceImpl struct {
4851
installedAppRepository repository.InstalledAppRepository
4952
dockerRegistryConfig pipeline.DockerRegistryConfig
5053
dockerRegistryRepository dockerRegistryRepository.DockerArtifactStoreRepository
54+
K8sUtil k8s.K8sService
55+
k8sInformerFactory informer.K8sInformerFactory
5156
}
5257

5358
func NewDeleteServiceImpl(logger *zap.SugaredLogger,
@@ -58,6 +63,8 @@ func NewDeleteServiceImpl(logger *zap.SugaredLogger,
5863
installedAppRepository repository.InstalledAppRepository,
5964
dockerRegistryConfig pipeline.DockerRegistryConfig,
6065
dockerRegistryRepository dockerRegistryRepository.DockerArtifactStoreRepository,
66+
k8sInformerFactory informer.K8sInformerFactory,
67+
K8sUtil k8s.K8sService,
6168
) *DeleteServiceImpl {
6269
return &DeleteServiceImpl{
6370
logger: logger,
@@ -68,18 +75,38 @@ func NewDeleteServiceImpl(logger *zap.SugaredLogger,
6875
installedAppRepository: installedAppRepository,
6976
dockerRegistryConfig: dockerRegistryConfig,
7077
dockerRegistryRepository: dockerRegistryRepository,
78+
K8sUtil: K8sUtil,
79+
k8sInformerFactory: k8sInformerFactory,
7180
}
7281
}
7382

7483
func (impl DeleteServiceImpl) DeleteCluster(deleteRequest *cluster.ClusterBean, userId int32) error {
75-
err := impl.clusterService.DeleteFromDb(deleteRequest, userId)
84+
clusterName, err := impl.clusterService.DeleteFromDb(deleteRequest, userId)
7685
if err != nil {
7786
impl.logger.Errorw("error im deleting cluster", "err", err, "deleteRequest", deleteRequest)
7887
return err
7988
}
89+
err = impl.DeleteClusterSecret(deleteRequest, err)
90+
if err != nil {
91+
impl.logger.Errorw("error in deleting cluster secret", "clusterId", deleteRequest.Id, "error", err)
92+
return err
93+
}
94+
impl.k8sInformerFactory.DeleteClusterFromCache(clusterName)
8095
return nil
8196
}
8297

98+
func (impl DeleteServiceImpl) DeleteClusterSecret(deleteRequest *cluster.ClusterBean, err error) error {
99+
// kubelink informers are listening this secret, deleting this secret will inform kubelink that this cluster is deleted
100+
k8sClient, err := impl.K8sUtil.GetCoreV1ClientInCluster()
101+
if err != nil {
102+
impl.logger.Errorw("error in getting in cluster k8s client", "err", err, "clusterName", deleteRequest.ClusterName)
103+
return nil
104+
}
105+
secretName := cluster.ParseSecretNameForKubelinkInformer(deleteRequest.Id)
106+
err = impl.K8sUtil.DeleteSecret(cluster.DEFAULT_NAMESPACE, secretName, k8sClient)
107+
return err
108+
}
109+
83110
func (impl DeleteServiceImpl) DeleteEnvironment(deleteRequest *bean.EnvironmentBean, userId int32) error {
84111
err := impl.environmentService.Delete(deleteRequest, userId)
85112
if err != nil {

pkg/delete/DeleteServiceExtended.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package delete
1818

1919
import (
2020
"fmt"
21+
k8sUtil "github.com/devtron-labs/common-lib/utils/k8s"
2122
"github.com/devtron-labs/devtron/internal/sql/repository/app"
2223
dockerRegistryRepository "github.com/devtron-labs/devtron/internal/sql/repository/dockerRegistry"
2324
"github.com/devtron-labs/devtron/internal/sql/repository/pipelineConfig"
@@ -28,6 +29,7 @@ import (
2829
"github.com/devtron-labs/devtron/pkg/cluster"
2930
"github.com/devtron-labs/devtron/pkg/cluster/repository"
3031
"github.com/devtron-labs/devtron/pkg/cluster/repository/bean"
32+
"github.com/devtron-labs/devtron/pkg/k8s/informer"
3133
"github.com/devtron-labs/devtron/pkg/pipeline"
3234
"github.com/devtron-labs/devtron/pkg/team"
3335
"github.com/go-pg/pg"
@@ -53,6 +55,8 @@ func NewDeleteServiceExtendedImpl(logger *zap.SugaredLogger,
5355
installedAppRepository repository2.InstalledAppRepository,
5456
dockerRegistryConfig pipeline.DockerRegistryConfig,
5557
dockerRegistryRepository dockerRegistryRepository.DockerArtifactStoreRepository,
58+
K8sService k8sUtil.K8sService,
59+
factory informer.K8sInformerFactory,
5660
) *DeleteServiceExtendedImpl {
5761
return &DeleteServiceExtendedImpl{
5862
appRepository: appRepository,
@@ -67,6 +71,8 @@ func NewDeleteServiceExtendedImpl(logger *zap.SugaredLogger,
6771
installedAppRepository: installedAppRepository,
6872
dockerRegistryConfig: dockerRegistryConfig,
6973
dockerRegistryRepository: dockerRegistryRepository,
74+
K8sUtil: K8sService,
75+
k8sInformerFactory: factory,
7076
},
7177
}
7278
}
@@ -82,11 +88,17 @@ func (impl DeleteServiceExtendedImpl) DeleteCluster(deleteRequest *cluster.Clust
8288
impl.logger.Errorw("err in deleting cluster, found env in this cluster", "clusterName", deleteRequest.ClusterName, "err", err)
8389
return &util.ApiError{HttpStatusCode: http.StatusBadRequest, UserMessage: " Please delete all related environments before deleting this cluster"}
8490
}
85-
err = impl.clusterService.DeleteFromDb(deleteRequest, userId)
91+
clusterName, err := impl.clusterService.DeleteFromDb(deleteRequest, userId)
8692
if err != nil {
8793
impl.logger.Errorw("error im deleting cluster", "err", err, "deleteRequest", deleteRequest)
8894
return err
8995
}
96+
err = impl.DeleteClusterSecret(deleteRequest, err)
97+
if err != nil {
98+
impl.logger.Errorw("error in deleting cluster secret", "clusterId", deleteRequest.Id, "error", err)
99+
return err
100+
}
101+
impl.k8sInformerFactory.DeleteClusterFromCache(clusterName)
90102
return nil
91103
}
92104

pkg/k8s/informer/K8sInformerFactory.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ type K8sInformerFactory interface {
4343
GetLatestNamespaceListGroupByCLuster() map[string]map[string]bool
4444
BuildInformer(clusterInfo []*bean.ClusterInfo)
4545
CleanNamespaceInformer(clusterName string)
46+
DeleteClusterFromCache(clusterName string)
4647
}
4748

4849
func NewK8sInformerFactoryImpl(logger *zap.SugaredLogger, globalMapClusterNamespace sync.Map, k8sUtil *k8s.K8sServiceImpl) *K8sInformerFactoryImpl {
@@ -127,3 +128,9 @@ func (impl *K8sInformerFactoryImpl) CleanNamespaceInformer(clusterName string) {
127128
}
128129
return
129130
}
131+
132+
func (impl *K8sInformerFactoryImpl) DeleteClusterFromCache(clusterName string) {
133+
impl.CleanNamespaceInformer(clusterName)
134+
impl.globalMapClusterNamespace.Delete(clusterName)
135+
return
136+
}

wire_gen.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)