From e69b768f3649d5adfaeb662dfc24bec8f33524e7 Mon Sep 17 00:00:00 2001 From: Tanmay Satam Date: Thu, 19 Dec 2024 15:58:19 -0500 Subject: [PATCH] Log Hive CD on install failures --- pkg/cluster/gatherlogs.go | 18 ++++++++- pkg/cluster/gatherlogs_test.go | 69 +++++++++++++++++++++++++++++++--- pkg/cluster/install_test.go | 8 ++++ 3 files changed, 89 insertions(+), 6 deletions(-) diff --git a/pkg/cluster/gatherlogs.go b/pkg/cluster/gatherlogs.go index 8fd4bba66ed..b447df2e853 100644 --- a/pkg/cluster/gatherlogs.go +++ b/pkg/cluster/gatherlogs.go @@ -37,9 +37,10 @@ func (m *manager) gatherFailureLogs(ctx context.Context, runType string) { {f: m.logPodLogs, isJSON: false}, } - // only log serial consoles on an install, not on updates/adminUpdates + // only log serial consoles and Hive CD on an install, not on updates/adminUpdates if runType == "install" { s = append(s, diagnosticStep{f: d.LogVMSerialConsole, isJSON: false}) + s = append(s, diagnosticStep{f: m.logClusterDeployment, isJSON: true}) } for _, f := range s { @@ -71,6 +72,21 @@ func (m *manager) gatherFailureLogs(ctx context.Context, runType string) { } } +func (m *manager) logClusterDeployment(ctx context.Context) (interface{}, error) { + if m.doc == nil || m.hiveClusterManager == nil { + return nil, nil + } + + cd, err := m.hiveClusterManager.GetClusterDeployment(ctx, m.doc) + if err != nil { + return nil, err + } + + cd.ManagedFields = nil + + return cd, nil +} + func (m *manager) logClusterVersion(ctx context.Context) (interface{}, error) { if m.configcli == nil { return nil, nil diff --git a/pkg/cluster/gatherlogs_test.go b/pkg/cluster/gatherlogs_test.go index 859e809a45a..510c849d594 100644 --- a/pkg/cluster/gatherlogs_test.go +++ b/pkg/cluster/gatherlogs_test.go @@ -15,22 +15,28 @@ import ( operatorv1 "github.com/openshift/api/operator/v1" configfake "github.com/openshift/client-go/config/clientset/versioned/fake" operatorfake "github.com/openshift/client-go/operator/clientset/versioned/fake" + hivev1 "github.com/openshift/hive/apis/hive/v1" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kruntime "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/kubernetes/fake" + kubernetesfake "k8s.io/client-go/kubernetes/fake" + "github.com/Azure/ARO-RP/pkg/api" + mock_hive "github.com/Azure/ARO-RP/pkg/util/mocks/hive" utilerror "github.com/Azure/ARO-RP/test/util/error" testlog "github.com/Azure/ARO-RP/test/util/log" ) var ( managedFields = []metav1.ManagedFieldsEntry{{Manager: "something"}} - cvv = &configv1.ClusterVersion{ObjectMeta: metav1.ObjectMeta{Name: "version"}} + doc = &api.OpenShiftClusterDocument{} + cd = &hivev1.ClusterDeployment{ObjectMeta: metav1.ObjectMeta{Name: "cluster", ManagedFields: managedFields}} + cvv = &configv1.ClusterVersion{ObjectMeta: metav1.ObjectMeta{Name: "version", ManagedFields: managedFields}} master0Node = &corev1.Node{ ObjectMeta: metav1.ObjectMeta{Name: "cluster-aaaaa-master-0", ManagedFields: managedFields}, Status: corev1.NodeStatus{Conditions: []corev1.NodeCondition{{Type: corev1.NodeReady, Status: corev1.ConditionTrue}}}, @@ -71,6 +77,59 @@ var ( aroOperatorWorkerPod = &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "openshift-azure-operator", Name: "aro-operator-worker-bbbbbbbbb-bbbbb"}, Status: corev1.PodStatus{}} ) +func TestLogClusterDeployment(t *testing.T) { + for _, tt := range []struct { + name string + doc *api.OpenShiftClusterDocument + cd *hivev1.ClusterDeployment + want interface{} + wantErr string + }{ + { + name: "no clusterdoc returns empty", + }, + { + name: "no clusterdeployment returns error", + doc: doc, + wantErr: `clusterdeployments.hive.openshift.io "cluster" not found`, + }, + { + name: "clusterdeployment present returns clusterdeployment without managed fields", + doc: doc, + cd: cd, + want: &hivev1.ClusterDeployment{ObjectMeta: metav1.ObjectMeta{Name: "cluster"}}, + }, + } { + t.Run(tt.name, func(t *testing.T) { + controller := gomock.NewController(t) + defer controller.Finish() + + ctx := context.Background() + _, log := testlog.New() + + mockHiveManager := mock_hive.NewMockClusterManager(controller) + if tt.cd == nil { + mockHiveManager.EXPECT().GetClusterDeployment(gomock.Any(), gomock.Eq(tt.doc)). + Return(nil, fmt.Errorf(`clusterdeployments.hive.openshift.io "cluster" not found`)). + AnyTimes() + } else { + mockHiveManager.EXPECT().GetClusterDeployment(gomock.Any(), gomock.Eq(tt.doc)). + Return(tt.cd, nil) + } + + m := &manager{ + log: log, + hiveClusterManager: mockHiveManager, + doc: tt.doc, + } + + got, gotErr := m.logClusterDeployment(ctx) + utilerror.AssertErrorMessage(t, gotErr, tt.wantErr) + assert.Equal(t, tt.want, got) + }) + } +} + func TestLogClusterVersion(t *testing.T) { for _, tt := range []struct { name string @@ -85,7 +144,7 @@ func TestLogClusterVersion(t *testing.T) { { name: "returns cv resource if present", objects: []kruntime.Object{cvv}, - want: cvv, + want: &configv1.ClusterVersion{ObjectMeta: metav1.ObjectMeta{Name: "version"}}, }, } { t.Run(tt.name, func(t *testing.T) { @@ -139,7 +198,7 @@ func TestLogNodes(t *testing.T) { } { t.Run(tt.name, func(t *testing.T) { ctx := context.Background() - kubernetescli := fake.NewSimpleClientset(tt.objects...) + kubernetescli := kubernetesfake.NewSimpleClientset(tt.objects...) h, log := testlog.New() @@ -276,7 +335,7 @@ func TestLogPodLogs(t *testing.T) { } { t.Run(tt.name, func(t *testing.T) { ctx := context.Background() - kubernetescli := fake.NewSimpleClientset(tt.objects...) + kubernetescli := kubernetesfake.NewSimpleClientset(tt.objects...) h, log := testlog.New() diff --git a/pkg/cluster/install_test.go b/pkg/cluster/install_test.go index 708a12e9d30..8e523127098 100644 --- a/pkg/cluster/install_test.go +++ b/pkg/cluster/install_test.go @@ -140,6 +140,10 @@ func TestStepRunnerWithInstaller(t *testing.T) { "level": gomega.Equal(logrus.InfoLevel), "msg": gomega.Equal(`pkg/cluster/failurediagnostics.(*manager).LogVMSerialConsole: vmclient missing`), }, + { + "level": gomega.Equal(logrus.InfoLevel), + "msg": gomega.Equal(`pkg/cluster.(*manager).logClusterDeployment: null`), + }, }, kubernetescli: fake.NewSimpleClientset(node), configcli: configfake.NewSimpleClientset(clusterVersion, clusterOperator), @@ -230,6 +234,10 @@ func TestStepRunnerWithInstaller(t *testing.T) { "level": gomega.Equal(logrus.InfoLevel), "msg": gomega.Equal(`pkg/cluster/failurediagnostics.(*manager).LogVMSerialConsole: vmclient missing`), }, + { + "level": gomega.Equal(logrus.InfoLevel), + "msg": gomega.Equal(`pkg/cluster.(*manager).logClusterDeployment: null`), + }, }, kubernetescli: fake.NewSimpleClientset(), configcli: configfake.NewSimpleClientset(),