Skip to content

Commit 08835f8

Browse files
committed
Metrics for SyncSet and SelectorSyncSets
merging 8659 and 9545 Metrics for SyncSet and SelectorSyncSets
1 parent 87d18c1 commit 08835f8

File tree

19 files changed

+1053
-16
lines changed

19 files changed

+1053
-16
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ require (
5959
github.com/openshift/api v0.0.0-20240103200955-7ca3a4634e46
6060
github.com/openshift/client-go v0.0.0-20221019143426-16aed247da5c
6161
github.com/openshift/cloud-credential-operator v0.0.0-00010101000000-000000000000
62-
github.com/openshift/hive/apis v0.0.0-20240812130639-bdf9d08a060a
62+
github.com/openshift/hive/apis v0.0.0-20240821011206-1ec27ad45d5a
6363
github.com/openshift/library-go v0.0.0-20220525173854-9b950a41acdc
6464
github.com/openshift/machine-config-operator v0.0.1-0.20230519222939-1abc13efbb0d
6565
github.com/pires/go-proxyproto v0.6.2
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package frontend
2+
3+
// Copyright (c) Microsoft Corporation.
4+
// Licensed under the Apache License 2.0.
5+
6+
import (
7+
"context"
8+
"net/http"
9+
"path/filepath"
10+
"strings"
11+
12+
"github.com/sirupsen/logrus"
13+
"github.com/ugorji/go/codec"
14+
15+
"github.com/Azure/ARO-RP/pkg/api"
16+
"github.com/Azure/ARO-RP/pkg/frontend/middleware"
17+
)
18+
19+
func (f *frontend) getAdminHiveSyncsetResources(w http.ResponseWriter, r *http.Request) {
20+
ctx := r.Context()
21+
log := ctx.Value(middleware.ContextKeyLog).(*logrus.Entry)
22+
clusterdeployment := strings.TrimPrefix(filepath.Dir(r.URL.Path), "/admin")
23+
b, err := f._getAdminHiveSyncsetResources(ctx, clusterdeployment)
24+
25+
if cloudErr, ok := err.(*api.CloudError); ok {
26+
api.WriteCloudError(w, cloudErr)
27+
return
28+
}
29+
30+
adminReply(log, w, nil, b, err)
31+
}
32+
33+
func (f *frontend) _getAdminHiveSyncsetResources(ctx context.Context, namespace string) ([]byte, error) {
34+
// we have to check if the frontend has a valid clustermanager since hive is not everywhere.
35+
if f.hiveClusterManager == nil {
36+
return nil, api.NewCloudError(http.StatusInternalServerError, api.CloudErrorCodeInternalServerError, "", "hive is not enabled")
37+
}
38+
39+
dbOpenShiftClusters, err := f.dbGroup.OpenShiftClusters()
40+
if err != nil {
41+
return nil, api.NewCloudError(http.StatusInternalServerError, api.CloudErrorCodeInternalServerError, "", err.Error())
42+
}
43+
44+
doc, err := dbOpenShiftClusters.Get(ctx, namespace)
45+
if err != nil {
46+
return nil, api.NewCloudError(http.StatusNotFound, api.CloudErrorCodeNotFound, "", "cluster not found")
47+
}
48+
49+
if doc.OpenShiftCluster.Properties.HiveProfile.Namespace == "" {
50+
return nil, api.NewCloudError(http.StatusNoContent, api.CloudErrorCodeResourceNotFound, "", "cluster is not managed by hive")
51+
}
52+
53+
cd, err := f.hiveClusterManager.GetSyncSetResources(ctx, doc)
54+
if err != nil {
55+
return nil, api.NewCloudError(http.StatusNotFound, api.CloudErrorCodeNotFound, "", "cluster deployment not found")
56+
}
57+
58+
var b []byte
59+
err = codec.NewEncoderBytes(&b, &codec.JsonHandle{}).Encode(cd)
60+
if err != nil {
61+
return nil, api.NewCloudError(http.StatusInternalServerError, api.CloudErrorCodeInternalServerError, "", "unable to marshal response")
62+
}
63+
64+
return b, nil
65+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package frontend
2+
3+
// Copyright (c) Microsoft Corporation.
4+
// Licensed under the Apache License 2.0.
5+
6+
import (
7+
"context"
8+
"fmt"
9+
"net/http"
10+
"strings"
11+
"testing"
12+
13+
"github.com/golang/mock/gomock"
14+
"github.com/openshift/hive/apis/hiveinternal/v1alpha1"
15+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16+
17+
"github.com/Azure/ARO-RP/pkg/api"
18+
"github.com/Azure/ARO-RP/pkg/metrics/noop"
19+
mock_env "github.com/Azure/ARO-RP/pkg/util/mocks/env"
20+
mock_hive "github.com/Azure/ARO-RP/pkg/util/mocks/hive"
21+
)
22+
23+
func TestGetAdminHiveSyncsetResources(t *testing.T) {
24+
fakeNamespace := "aro-00000000-0000-0000-0000-000000000000"
25+
ctx := context.Background()
26+
clusterSyncsetTest := &v1alpha1.ClusterSync{
27+
ObjectMeta: metav1.ObjectMeta{
28+
Name: "clustersync1",
29+
Namespace: fakeNamespace,
30+
},
31+
}
32+
33+
type test struct {
34+
name string
35+
namespace string
36+
hiveEnabled bool
37+
mocks func(*test, *mock_hive.MockClusterManager)
38+
wantStatusCode int
39+
wantResponse []byte
40+
wantError string
41+
}
42+
43+
for _, tt := range []*test{
44+
{
45+
name: "Cluster SyncSets must be namespaced",
46+
namespace: "",
47+
hiveEnabled: true,
48+
mocks: func(tt *test, s *mock_hive.MockClusterManager) {},
49+
wantStatusCode: http.StatusInternalServerError,
50+
wantError: "500: InternalServerError: : hive is not enabled", //"404: NotFound: : hive is not enabled",
51+
},
52+
{
53+
name: "List ClusterSync resources successfully",
54+
namespace: "hive",
55+
wantError: "",
56+
mocks: func(tt *test, s *mock_hive.MockClusterManager) {
57+
s.EXPECT().
58+
GetSyncSetResources(gomock.Any(), gomock.Any()).
59+
Return(&clusterSyncsetTest, nil).Times(1)
60+
},
61+
wantStatusCode: http.StatusOK,
62+
},
63+
{
64+
name: "Hive is not enabled",
65+
namespace: fakeNamespace,
66+
mocks: nil,
67+
hiveEnabled: false,
68+
wantStatusCode: http.StatusInternalServerError,
69+
wantError: "500: InternalServerError: : hive is not enabled",
70+
},
71+
} {
72+
t.Run(tt.name, func(t *testing.T) {
73+
ti := newTestInfra(t).WithOpenShiftClusters().WithSubscriptions()
74+
defer ti.done()
75+
76+
_env := ti.env.(*mock_env.MockInterface)
77+
var f *frontend
78+
var err error
79+
if tt.hiveEnabled {
80+
s := mock_hive.NewMockClusterManager(ti.controller) //NewMockSyncSetResourceManager(ti.controller)
81+
tt.mocks(tt, s)
82+
f, err = NewFrontend(ctx, ti.audit, ti.log, _env, ti.dbGroup, api.APIs, &noop.Noop{}, &noop.Noop{}, nil, nil, nil, nil, nil, nil)
83+
} else {
84+
f, err = NewFrontend(ctx, ti.audit, ti.log, _env, ti.dbGroup, api.APIs, &noop.Noop{}, &noop.Noop{}, nil, nil, nil, nil, nil, nil)
85+
}
86+
if err != nil {
87+
t.Fatal(err)
88+
}
89+
90+
clusterSyncSet, err := f._getAdminHiveSyncsetResources(ctx, tt.namespace)
91+
cloudErr, isCloudErr := err.(*api.CloudError)
92+
if tt.wantError != "" && isCloudErr && cloudErr != nil {
93+
if tt.wantError != cloudErr.Error() {
94+
fmt.Println("first condition")
95+
fmt.Println(tt.wantError)
96+
fmt.Println(cloudErr)
97+
t.Fatalf("got %q but wanted %q", cloudErr.Error(), tt.wantError)
98+
}
99+
if tt.wantStatusCode != 0 && tt.wantStatusCode != cloudErr.StatusCode {
100+
fmt.Println("second condition")
101+
fmt.Println(tt.wantError)
102+
fmt.Println(cloudErr)
103+
t.Fatalf("got %q but wanted %q", cloudErr.Error(), tt.wantError)
104+
}
105+
}
106+
107+
if !strings.EqualFold(string(clusterSyncSet), string(tt.wantResponse)) {
108+
t.Fatalf("got %q and expected %q", clusterSyncSet, tt.wantResponse)
109+
}
110+
})
111+
}
112+
}

pkg/frontend/frontend.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,8 @@ func (f *frontend) chiAuthenticatedRoutes(router chi.Router) {
307307

308308
r.Get("/clusterdeployment", f.getAdminHiveClusterDeployment)
309309

310+
r.Get("/clustersync", f.getAdminHiveSyncsetResources)
311+
310312
r.With(f.maintenanceMiddleware.UnplannedMaintenanceSignal).Post("/redeployvm", f.postAdminOpenShiftClusterRedeployVM)
311313

312314
r.With(f.maintenanceMiddleware.UnplannedMaintenanceSignal).Post("/stopvm", f.postAdminOpenShiftClusterStopVM)

pkg/hive/manager.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ import (
77
"context"
88
"errors"
99
"fmt"
10+
"log"
1011
"sort"
1112

1213
hivev1 "github.com/openshift/hive/apis/hive/v1"
14+
hivev1alpha1 "github.com/openshift/hive/apis/hiveinternal/v1alpha1"
1315
"github.com/sirupsen/logrus"
1416
corev1 "k8s.io/api/core/v1"
1517
kerrors "k8s.io/apimachinery/pkg/api/errors"
@@ -42,6 +44,7 @@ type ClusterManager interface {
4244
IsClusterInstallationComplete(ctx context.Context, doc *api.OpenShiftClusterDocument) (bool, error)
4345
GetClusterDeployment(ctx context.Context, doc *api.OpenShiftClusterDocument) (*hivev1.ClusterDeployment, error)
4446
ResetCorrelationData(ctx context.Context, doc *api.OpenShiftClusterDocument) error
47+
GetSyncSetResources(ctx context.Context, doc *api.OpenShiftClusterDocument) (*hivev1alpha1.ClusterSync, error)
4548
}
4649

4750
type clusterManager struct {
@@ -262,3 +265,19 @@ func (hr *clusterManager) installLogsForLatestDeployment(ctx context.Context, cd
262265

263266
return latestProvision.Spec.InstallLog, nil
264267
}
268+
269+
func (hr *clusterManager) GetSyncSetResources(ctx context.Context, doc *api.OpenShiftClusterDocument) (*hivev1alpha1.ClusterSync, error) {
270+
clusterSync := &hivev1alpha1.ClusterSync{}
271+
272+
key := client.ObjectKey{
273+
Name: ClusterDeploymentName, // "cluster",
274+
Namespace: doc.OpenShiftCluster.Properties.HiveProfile.Namespace,
275+
}
276+
277+
err := hr.hiveClientset.Get(ctx, key, clusterSync)
278+
if err != nil {
279+
log.Fatalf("Error getting ClusterSync resources: %s", err.Error())
280+
}
281+
282+
return clusterSync, nil
283+
}

pkg/hive/manager_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"testing"
1111

1212
hivev1 "github.com/openshift/hive/apis/hive/v1"
13+
hivev1alpha1 "github.com/openshift/hive/apis/hiveinternal/v1alpha1"
1314
"github.com/sirupsen/logrus"
1415
corev1 "k8s.io/api/core/v1"
1516
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -548,3 +549,52 @@ func TestGetClusterDeployment(t *testing.T) {
548549
})
549550
}
550551
}
552+
553+
func TestGetClusterSyncforClusterDeployment(t *testing.T) {
554+
fakeNamespace := "aro-00000000-0000-0000-0000-000000000000"
555+
doc := &api.OpenShiftClusterDocument{
556+
OpenShiftCluster: &api.OpenShiftCluster{
557+
Properties: api.OpenShiftClusterProperties{
558+
HiveProfile: api.HiveProfile{
559+
Namespace: fakeNamespace,
560+
},
561+
},
562+
},
563+
}
564+
565+
cs := &hivev1alpha1.ClusterSync{
566+
ObjectMeta: metav1.ObjectMeta{
567+
Name: ClusterDeploymentName,
568+
Namespace: fakeNamespace,
569+
},
570+
}
571+
572+
for _, tt := range []struct {
573+
name string
574+
wantErr string
575+
}{
576+
{name: "syncset exists and returned"},
577+
{name: "selectorsyncsets exists and returned"},
578+
} {
579+
t.Run(tt.name, func(t *testing.T) {
580+
fakeClientBuilder := fake.NewClientBuilder()
581+
if tt.wantErr == "" {
582+
fakeClientBuilder = fakeClientBuilder.WithRuntimeObjects(cs)
583+
}
584+
c := clusterManager{
585+
hiveClientset: fakeClientBuilder.Build(),
586+
log: logrus.NewEntry(logrus.StandardLogger()),
587+
}
588+
589+
result, err := c.GetSyncSetResources(context.Background(), doc)
590+
if err != nil && err.Error() != tt.wantErr ||
591+
err == nil && tt.wantErr != "" {
592+
t.Fatal(err)
593+
}
594+
595+
if result != nil && result.Name != cs.Name && result.Namespace != cs.Namespace {
596+
t.Fatal("Unexpected cluster sync returned", result)
597+
}
598+
})
599+
}
600+
}

pkg/monitor/cluster/cluster.go

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
2323

2424
"github.com/Azure/ARO-RP/pkg/api"
25+
"github.com/Azure/ARO-RP/pkg/hive"
2526
"github.com/Azure/ARO-RP/pkg/metrics"
2627
"github.com/Azure/ARO-RP/pkg/monitor/dimension"
2728
"github.com/Azure/ARO-RP/pkg/monitor/emitter"
@@ -60,10 +61,12 @@ type Monitor struct {
6061
arodl *appsv1.DeploymentList
6162
}
6263

63-
wg *sync.WaitGroup
64+
wg *sync.WaitGroup
65+
hiveClusterManager hive.ClusterManager
66+
doc *api.OpenShiftClusterDocument
6467
}
6568

66-
func NewMonitor(log *logrus.Entry, restConfig *rest.Config, oc *api.OpenShiftCluster, m metrics.Emitter, hiveRestConfig *rest.Config, hourlyRun bool, wg *sync.WaitGroup) (*Monitor, error) {
69+
func NewMonitor(log *logrus.Entry, restConfig *rest.Config, oc *api.OpenShiftCluster, doc *api.OpenShiftClusterDocument, m metrics.Emitter, hiveRestConfig *rest.Config, hourlyRun bool, wg *sync.WaitGroup, hiveClusterManager hive.ClusterManager) (*Monitor, error) {
6770
r, err := azure.ParseResourceID(oc.ID)
6871
if err != nil {
6972
return nil, err
@@ -126,16 +129,18 @@ func NewMonitor(log *logrus.Entry, restConfig *rest.Config, oc *api.OpenShiftClu
126129
oc: oc,
127130
dims: dims,
128131

129-
restconfig: restConfig,
130-
cli: cli,
131-
configcli: configcli,
132-
maocli: maocli,
133-
mcocli: mcocli,
134-
arocli: arocli,
135-
m: m,
136-
ocpclientset: ocpclientset,
137-
hiveclientset: hiveclientset,
138-
wg: wg,
132+
restconfig: restConfig,
133+
cli: cli,
134+
configcli: configcli,
135+
maocli: maocli,
136+
mcocli: mcocli,
137+
arocli: arocli,
138+
m: m,
139+
ocpclientset: ocpclientset,
140+
hiveclientset: hiveclientset,
141+
wg: wg,
142+
hiveClusterManager: hiveClusterManager,
143+
doc: doc,
139144
}, nil
140145
}
141146

@@ -208,6 +213,7 @@ func (mon *Monitor) Monitor(ctx context.Context) (errs []error) {
208213
mon.emitJobConditions,
209214
mon.emitSummary,
210215
mon.emitHiveRegistrationStatus,
216+
mon.emitClusterSync,
211217
mon.emitOperatorFlagsAndSupportBanner,
212218
mon.emitMaintenanceState,
213219
mon.emitCertificateExpirationStatuses,

0 commit comments

Comments
 (0)