Skip to content

Commit 223a309

Browse files
committed
bug: Argo CD should update the correct cluster connectivity status
Signed-off-by: Chetan Banavikalmutt <[email protected]>
1 parent a00ce82 commit 223a309

File tree

2 files changed

+67
-23
lines changed

2 files changed

+67
-23
lines changed

pkg/cache/cluster.go

+41
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ type ClusterInfo struct {
8989
SyncError error
9090
// APIResources holds list of API resources supported by the cluster
9191
APIResources []kube.APIResourceInfo
92+
// ConnectionStatus indicates the status of the connection with the cluster.
93+
ConnectionStatus ConnectionStatus
9294
}
9395

9496
// OnEventHandler is a function that handles Kubernetes event
@@ -170,16 +172,29 @@ func NewClusterCache(config *rest.Config, opts ...UpdateSettingsFunc) *clusterCa
170172
listRetryLimit: 1,
171173
listRetryUseBackoff: false,
172174
listRetryFunc: ListRetryFuncNever,
175+
connectionStatus: ConnectionStatusUnknown,
173176
}
174177
for i := range opts {
175178
opts[i](cache)
176179
}
177180
return cache
178181
}
179182

183+
// ConnectionStatus indicates the status of the connection with the cluster.
184+
type ConnectionStatus string
185+
186+
const (
187+
ConnectionStatusSuccessful ConnectionStatus = "Successful"
188+
ConnectionStatusFailed ConnectionStatus = "Failed"
189+
ConnectionStatusUnknown ConnectionStatus = "Unknown"
190+
)
191+
180192
type clusterCache struct {
181193
syncStatus clusterCacheSync
182194

195+
// connectionStatus indicates the status of the connection with the cluster.
196+
connectionStatus ConnectionStatus
197+
183198
apisMeta map[schema.GroupKind]*apiMeta
184199
serverVersion string
185200
apiResources []kube.APIResourceInfo
@@ -615,6 +630,25 @@ func (c *clusterCache) watchEvents(ctx context.Context, api kube.APIResourceInfo
615630
if errors.IsNotFound(err) {
616631
c.stopWatching(api.GroupKind, ns)
617632
}
633+
var connectionUpdated bool
634+
if err != nil {
635+
if c.connectionStatus != ConnectionStatusFailed {
636+
c.log.Info("unable to access cluster", "cluster", c.config.Host, "reason", err.Error())
637+
c.connectionStatus = ConnectionStatusFailed
638+
connectionUpdated = true
639+
}
640+
} else if c.connectionStatus != ConnectionStatusSuccessful {
641+
c.connectionStatus = ConnectionStatusSuccessful
642+
connectionUpdated = true
643+
}
644+
645+
if connectionUpdated {
646+
c.Invalidate()
647+
if err := c.EnsureSynced(); err != nil {
648+
return nil, err
649+
}
650+
}
651+
618652
return res, err
619653
},
620654
})
@@ -808,8 +842,14 @@ func (c *clusterCache) sync() error {
808842
version, err := c.kubectl.GetServerVersion(config)
809843

810844
if err != nil {
845+
if c.connectionStatus != ConnectionStatusFailed {
846+
c.log.Info("unable to access cluster", "cluster", c.config.Host, "reason", err.Error())
847+
c.connectionStatus = ConnectionStatusFailed
848+
}
811849
return err
812850
}
851+
852+
c.connectionStatus = ConnectionStatusSuccessful
813853
c.serverVersion = version
814854
apiResources, err := c.kubectl.GetAPIResources(config, false, NewNoopSettings())
815855
if err != nil {
@@ -1184,6 +1224,7 @@ func (c *clusterCache) GetClusterInfo() ClusterInfo {
11841224
LastCacheSyncTime: c.syncStatus.syncTime,
11851225
SyncError: c.syncStatus.syncError,
11861226
APIResources: c.apiResources,
1227+
ConnectionStatus: c.connectionStatus,
11871228
}
11881229
}
11891230

pkg/cache/cluster_test.go

+26-23
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ package cache
33
import (
44
"context"
55
"fmt"
6-
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
76
"sort"
87
"strings"
98
"testing"
109
"time"
1110

11+
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
12+
1213
"github.com/stretchr/testify/assert"
1314
"github.com/stretchr/testify/require"
1415
appsv1 "k8s.io/api/apps/v1"
@@ -148,6 +149,7 @@ func TestEnsureSynced(t *testing.T) {
148149
}
149150

150151
cluster := newCluster(t, obj1, obj2)
152+
assert.Equal(t, cluster.connectionStatus, ConnectionStatusUnknown)
151153
err := cluster.EnsureSynced()
152154
require.NoError(t, err)
153155

@@ -160,6 +162,7 @@ func TestEnsureSynced(t *testing.T) {
160162
names = append(names, k.Name)
161163
}
162164
assert.ElementsMatch(t, []string{"helm-guestbook1", "helm-guestbook2"}, names)
165+
assert.Equal(t, cluster.connectionStatus, ConnectionStatusSuccessful)
163166
}
164167

165168
func TestStatefulSetOwnershipInferred(t *testing.T) {
@@ -492,23 +495,23 @@ metadata:
492495
func TestGetManagedLiveObjsFailedConversion(t *testing.T) {
493496
cronTabGroup := "stable.example.com"
494497

495-
testCases := []struct{
496-
name string
497-
localConvertFails bool
498+
testCases := []struct {
499+
name string
500+
localConvertFails bool
498501
expectConvertToVersionCalled bool
499-
expectGetResourceCalled bool
502+
expectGetResourceCalled bool
500503
}{
501504
{
502-
name: "local convert fails, so GetResource is called",
503-
localConvertFails: true,
505+
name: "local convert fails, so GetResource is called",
506+
localConvertFails: true,
504507
expectConvertToVersionCalled: true,
505-
expectGetResourceCalled: true,
508+
expectGetResourceCalled: true,
506509
},
507510
{
508-
name: "local convert succeeds, so GetResource is not called",
509-
localConvertFails: false,
511+
name: "local convert succeeds, so GetResource is not called",
512+
localConvertFails: false,
510513
expectConvertToVersionCalled: true,
511-
expectGetResourceCalled: false,
514+
expectGetResourceCalled: false,
512515
},
513516
}
514517

@@ -557,7 +560,6 @@ metadata:
557560
return testCronTab(), nil
558561
})
559562

560-
561563
managedObjs, err := cluster.GetManagedLiveObjs([]*unstructured.Unstructured{targetDeploy}, func(r *Resource) bool {
562564
return true
563565
})
@@ -716,9 +718,10 @@ func TestGetClusterInfo(t *testing.T) {
716718
cluster.serverVersion = "v1.16"
717719
info := cluster.GetClusterInfo()
718720
assert.Equal(t, ClusterInfo{
719-
Server: cluster.config.Host,
720-
APIResources: cluster.apiResources,
721-
K8SVersion: cluster.serverVersion,
721+
Server: cluster.config.Host,
722+
APIResources: cluster.apiResources,
723+
K8SVersion: cluster.serverVersion,
724+
ConnectionStatus: ConnectionStatusUnknown,
722725
}, info)
723726
}
724727

@@ -816,25 +819,25 @@ func testPod() *corev1.Pod {
816819

817820
func testCRD() *apiextensions.CustomResourceDefinition {
818821
return &apiextensions.CustomResourceDefinition{
819-
TypeMeta: metav1.TypeMeta{
822+
TypeMeta: metav1.TypeMeta{
820823
APIVersion: "apiextensions.k8s.io/v1",
821824
},
822825
ObjectMeta: metav1.ObjectMeta{
823826
Name: "crontabs.stable.example.com",
824827
},
825-
Spec: apiextensions.CustomResourceDefinitionSpec{
828+
Spec: apiextensions.CustomResourceDefinitionSpec{
826829
Group: "stable.example.com",
827830
Versions: []apiextensions.CustomResourceDefinitionVersion{
828831
{
829-
Name: "v1",
830-
Served: true,
832+
Name: "v1",
833+
Served: true,
831834
Storage: true,
832835
Schema: &apiextensions.CustomResourceValidation{
833836
OpenAPIV3Schema: &apiextensions.JSONSchemaProps{
834837
Type: "object",
835838
Properties: map[string]apiextensions.JSONSchemaProps{
836839
"cronSpec": {Type: "string"},
837-
"image": {Type: "string"},
840+
"image": {Type: "string"},
838841
"replicas": {Type: "integer"},
839842
},
840843
},
@@ -855,14 +858,14 @@ func testCRD() *apiextensions.CustomResourceDefinition {
855858
func testCronTab() *unstructured.Unstructured {
856859
return &unstructured.Unstructured{Object: map[string]interface{}{
857860
"apiVersion": "stable.example.com/v1",
858-
"kind": "CronTab",
861+
"kind": "CronTab",
859862
"metadata": map[string]interface{}{
860-
"name": "test-crontab",
863+
"name": "test-crontab",
861864
"namespace": "default",
862865
},
863866
"spec": map[string]interface{}{
864867
"cronSpec": "* * * * */5",
865-
"image": "my-awesome-cron-image",
868+
"image": "my-awesome-cron-image",
866869
},
867870
}}
868871
}

0 commit comments

Comments
 (0)