-
Notifications
You must be signed in to change notification settings - Fork 178
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implements: 1. Geneva Action to list selectorsyncsets for a given hive instance 2. Geneva Action to retrieve an individual selectorsyncset on a given hive instance 3. Geneva Action to list syncsets for a cluster defined by resource id in a hive instance 4. Geneva Action to retrieve an individual syncsets on a given hive instance How to call: List selector/syncsets - /admin/hivesyncset?namespace={namespace}?isSyncset Get a selector/syncset - /admin/hivesyncset/syncsetname/{syncsetname}?namespace={namespace}?isSyncSet Notes: 1. namespace should be "" for selectorsyncsets 2. namespace cannot be "" for syncsets 3. isSyncSet can be true/false, setting it changes from using default selectorsyncset to syncset
- Loading branch information
1 parent
817438f
commit 0ff61e8
Showing
47 changed files
with
745 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package frontend | ||
|
||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the Apache License 2.0. | ||
|
||
import ( | ||
"context" | ||
"net/http" | ||
"reflect" | ||
|
||
"github.com/go-chi/chi/v5" | ||
hivev1 "github.com/openshift/hive/apis/hive/v1" | ||
"github.com/sirupsen/logrus" | ||
"github.com/ugorji/go/codec" | ||
|
||
"github.com/Azure/ARO-RP/pkg/api" | ||
"github.com/Azure/ARO-RP/pkg/frontend/middleware" | ||
) | ||
|
||
func (f *frontend) getAdminHiveSyncSet(w http.ResponseWriter, r *http.Request) { | ||
ctx := r.Context() | ||
log := ctx.Value(middleware.ContextKeyLog).(*logrus.Entry) | ||
syncsetname := chi.URLParam(r, "syncsetname") | ||
isSyncSet := r.URL.Query().Has("isSyncSet") | ||
namespace := r.URL.Query().Get("namespace") | ||
b, err := f._getAdminHiveSyncSet(ctx, namespace, syncsetname, isSyncSet) | ||
|
||
if cloudErr, ok := err.(*api.CloudError); ok { | ||
api.WriteCloudError(w, cloudErr) | ||
return | ||
} | ||
|
||
adminReply(log, w, nil, b, err) | ||
} | ||
|
||
func (f *frontend) _getAdminHiveSyncSet(ctx context.Context, namespace string, syncsetname string, isSyncSet bool) ([]byte, error) { | ||
// we have to check if the frontend has a valid syncSetManager since hive is not everywhere. | ||
if f.hiveSyncSetManager == nil { | ||
return nil, api.NewCloudError(http.StatusInternalServerError, api.CloudErrorCodeInternalServerError, "", "hive is not enabled") | ||
} | ||
|
||
ssType := reflect.TypeOf(hivev1.SelectorSyncSet{}) | ||
if isSyncSet { | ||
ssType = reflect.TypeOf(hivev1.SyncSet{}) | ||
} | ||
if isSyncSet && namespace == "" { | ||
return nil, api.NewCloudError(http.StatusBadRequest, api.CloudErrorCodeInvalidRequestContent, "", "namespace cannot be null for getting a syncset") | ||
} | ||
if !isSyncSet && namespace != "" { | ||
return nil, api.NewCloudError(http.StatusBadRequest, api.CloudErrorCodeInvalidRequestContent, "", "namespace should be null for getting a selectorsyncset") | ||
} | ||
if syncsetname == "" { | ||
return nil, api.NewCloudError(http.StatusBadRequest, api.CloudErrorCodeInvalidRequestContent, "", "syncsetname cannot be null") | ||
} | ||
|
||
ss, err := f.hiveSyncSetManager.Get(ctx, namespace, syncsetname, ssType) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var b []byte | ||
err = codec.NewEncoderBytes(&b, &codec.JsonHandle{}).Encode(ss) | ||
if err != nil { | ||
return nil, api.NewCloudError(http.StatusInternalServerError, api.CloudErrorCodeInternalServerError, "", "unable to marshal response") | ||
} | ||
|
||
return b, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
package frontend | ||
|
||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the Apache License 2.0. | ||
|
||
import ( | ||
"context" | ||
"reflect" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/golang/mock/gomock" | ||
hivev1 "github.com/openshift/hive/apis/hive/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
|
||
"github.com/Azure/ARO-RP/pkg/api" | ||
"github.com/Azure/ARO-RP/pkg/metrics/noop" | ||
mock_env "github.com/Azure/ARO-RP/pkg/util/mocks/env" | ||
mock_hive "github.com/Azure/ARO-RP/pkg/util/mocks/hive" | ||
) | ||
|
||
func Test_getAdminHiveSyncSet(t *testing.T) { | ||
fakeUUID := "00000000-0000-0000-0000-000000000000" | ||
ctx := context.Background() | ||
syncsetTest := hivev1.SyncSet{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "syncset-01", | ||
}, | ||
} | ||
selectorSyncSetTest := hivev1.SelectorSyncSet{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "selectorsyncset-01", | ||
}, | ||
} | ||
type test struct { | ||
name string | ||
namespace string | ||
syncsetname string | ||
isSyncSet bool | ||
hiveEnabled bool | ||
mocks func(*test, *mock_hive.MockSyncSetManager) | ||
wantStatusCode int | ||
wantResponse []byte | ||
wantError string | ||
} | ||
|
||
for _, tt := range []*test{ | ||
{ | ||
name: "selectorSyncSets are not namespaced", | ||
namespace: "aro-" + fakeUUID, | ||
syncsetname: "syncsetTest", | ||
isSyncSet: false, | ||
hiveEnabled: true, | ||
mocks: func(tt *test, s *mock_hive.MockSyncSetManager) {}, | ||
wantStatusCode: 400, | ||
wantError: "400: InvalidRequestContent: : namespace should be null for getting a selectorsyncset", | ||
}, | ||
{ | ||
name: "SyncSets must be namespaced", | ||
namespace: "", | ||
syncsetname: "syncsetTest", | ||
isSyncSet: true, | ||
hiveEnabled: true, | ||
mocks: func(tt *test, s *mock_hive.MockSyncSetManager) {}, | ||
wantStatusCode: 400, | ||
wantError: "400: InvalidRequestContent: : namespace cannot be null for getting a syncset", | ||
}, | ||
{ | ||
name: "syncset name is must", | ||
namespace: "", | ||
syncsetname: "", | ||
isSyncSet: false, | ||
hiveEnabled: true, | ||
mocks: func(tt *test, s *mock_hive.MockSyncSetManager) {}, | ||
wantStatusCode: 400, | ||
wantError: "400: InvalidRequestContent: : syncsetname cannot be null", | ||
}, | ||
{ | ||
name: "get a Selectorsyncset", | ||
namespace: "", | ||
syncsetname: "selectorSyncSetTest", | ||
isSyncSet: false, | ||
hiveEnabled: true, | ||
mocks: func(tt *test, s *mock_hive.MockSyncSetManager) { | ||
s.EXPECT(). | ||
Get(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Eq(reflect.TypeOf(hivev1.SelectorSyncSet{}))). | ||
Return(&selectorSyncSetTest, nil).Times(1) | ||
}, | ||
wantStatusCode: 200, | ||
wantResponse: []byte(`{"metadata":{"name":"selectorsyncset-01"}}`), | ||
wantError: "", | ||
}, | ||
{ | ||
name: "get a syncset", | ||
namespace: "aro-" + fakeUUID, | ||
syncsetname: "syncSetTest", | ||
isSyncSet: true, | ||
hiveEnabled: true, | ||
mocks: func(tt *test, s *mock_hive.MockSyncSetManager) { | ||
s.EXPECT(). | ||
Get(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Eq(reflect.TypeOf(hivev1.SyncSet{}))). | ||
Return(&syncsetTest, nil).Times(1) | ||
}, | ||
wantStatusCode: 200, | ||
wantResponse: []byte(`{"metadata":{"name":"syncset-01"}}`), | ||
wantError: "", | ||
}, | ||
{ | ||
name: "Hive is not enabled selector/syncsets", | ||
namespace: "aro-" + fakeUUID, | ||
syncsetname: "syncSetTest", | ||
mocks: nil, | ||
isSyncSet: false, | ||
hiveEnabled: false, | ||
wantStatusCode: 500, | ||
wantError: "500: InternalServerError: : hive is not enabled", | ||
}, | ||
} { | ||
t.Run(tt.name, func(t *testing.T) { | ||
ti := newTestInfra(t).WithOpenShiftClusters().WithSubscriptions() | ||
defer ti.done() | ||
|
||
_env := ti.env.(*mock_env.MockInterface) | ||
var f *frontend | ||
var err error | ||
if tt.hiveEnabled { | ||
s := mock_hive.NewMockSyncSetManager(ti.controller) | ||
tt.mocks(tt, s) | ||
f, err = NewFrontend(ctx, ti.audit, ti.log, _env, ti.dbGroup, api.APIs, &noop.Noop{}, &noop.Noop{}, nil, nil, s, nil, nil, nil, nil) | ||
} else { | ||
f, err = NewFrontend(ctx, ti.audit, ti.log, _env, ti.dbGroup, api.APIs, &noop.Noop{}, &noop.Noop{}, nil, nil, nil, nil, nil, nil, nil) | ||
} | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
hiveSyncSet, err := f._getAdminHiveSyncSet(ctx, tt.namespace, tt.syncsetname, tt.isSyncSet) | ||
cloudErr, isCloudErr := err.(*api.CloudError) | ||
if tt.wantError != "" && isCloudErr && cloudErr != nil { | ||
if tt.wantError != cloudErr.Error() { | ||
t.Fatalf("got %q but wanted %q", cloudErr.Error(), tt.wantError) | ||
} | ||
if tt.wantStatusCode != 0 && tt.wantStatusCode != cloudErr.StatusCode { | ||
t.Fatalf("got %q but wanted %q", cloudErr.Error(), tt.wantError) | ||
} | ||
} | ||
|
||
if !strings.EqualFold(string(hiveSyncSet), string(tt.wantResponse)) { | ||
t.Fatalf("got %q and expected %q", hiveSyncSet, tt.wantResponse) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package frontend | ||
|
||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the Apache License 2.0. | ||
|
||
import ( | ||
"context" | ||
"net/http" | ||
"reflect" | ||
|
||
hivev1 "github.com/openshift/hive/apis/hive/v1" | ||
"github.com/sirupsen/logrus" | ||
"github.com/ugorji/go/codec" | ||
|
||
"github.com/Azure/ARO-RP/pkg/api" | ||
"github.com/Azure/ARO-RP/pkg/frontend/middleware" | ||
) | ||
|
||
func (f *frontend) listAdminHiveSyncSet(w http.ResponseWriter, r *http.Request) { | ||
ctx := r.Context() | ||
log := ctx.Value(middleware.ContextKeyLog).(*logrus.Entry) | ||
namespace := r.URL.Query().Get("namespace") | ||
label := r.URL.Query().Get("lable") | ||
isSyncSet := r.URL.Query().Has("isSyncSet") | ||
b, err := f._listAdminHiveSyncSet(ctx, namespace, label, isSyncSet) | ||
|
||
if cloudErr, ok := err.(*api.CloudError); ok { | ||
api.WriteCloudError(w, cloudErr) | ||
return | ||
} | ||
|
||
adminReply(log, w, nil, b, err) | ||
} | ||
|
||
func (f *frontend) _listAdminHiveSyncSet(ctx context.Context, namespace string, label string, isSyncSet bool) ([]byte, error) { | ||
// we have to check if the frontend has a valid syncSetManager since hive is not everywhere. | ||
if f.hiveSyncSetManager == nil { | ||
return nil, api.NewCloudError(http.StatusInternalServerError, api.CloudErrorCodeInternalServerError, "", "hive is not enabled") | ||
} | ||
|
||
// defaults to listing selectorSyncSets for an AKS instance | ||
ssType := reflect.TypeOf(hivev1.SelectorSyncSetList{}) | ||
if isSyncSet { | ||
ssType = reflect.TypeOf(hivev1.SyncSetList{}) | ||
} | ||
if isSyncSet && namespace == "" { | ||
return nil, api.NewCloudError(http.StatusBadRequest, api.CloudErrorCodeInvalidRequestContent, "", "namespace cannot be null for listing syncsets") | ||
} | ||
if !isSyncSet && namespace != "" { | ||
return nil, api.NewCloudError(http.StatusBadRequest, api.CloudErrorCodeInvalidRequestContent, "", "namespace should be null for listing selectorsyncsets") | ||
} | ||
|
||
ss, err := f.hiveSyncSetManager.List(ctx, namespace, label, ssType) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var b []byte | ||
err = codec.NewEncoderBytes(&b, &codec.JsonHandle{}).Encode(ss) | ||
if err != nil { | ||
return nil, api.NewCloudError(http.StatusInternalServerError, api.CloudErrorCodeInternalServerError, "", "unable to marshal response") | ||
} | ||
|
||
return b, nil | ||
} |
Oops, something went wrong.