K8s: Namespace parsing updates (default + stack-id) (#76310)
Co-authored-by: Todd Treece <360020+toddtreece@users.noreply.github.com>
This commit is contained in:
co-authored by
Todd Treece
parent
be7fe761a3
commit
2a527aa33b
@@ -8,6 +8,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/playlist"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
type namespaceMapper = func(orgId int64) string
|
||||
@@ -19,6 +20,13 @@ func orgNamespaceMapper(orgId int64) string {
|
||||
return fmt.Sprintf("org-%d", orgId)
|
||||
}
|
||||
|
||||
func getNamespaceMapper(cfg *setting.Cfg) namespaceMapper {
|
||||
if cfg.StackID != "" {
|
||||
return func(orgId int64) string { return "stack-" + cfg.StackID }
|
||||
}
|
||||
return orgNamespaceMapper
|
||||
}
|
||||
|
||||
func convertToK8sResource(v *playlist.PlaylistDTO, namespacer namespaceMapper) *Playlist {
|
||||
spec := Spec{
|
||||
Title: v.Name,
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/playlist"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func TestPlaylistConversion(t *testing.T) {
|
||||
@@ -62,3 +63,36 @@ func TestPlaylistConversion(t *testing.T) {
|
||||
}
|
||||
}`, string(out))
|
||||
}
|
||||
|
||||
func TestNamespaceMapper(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
cfg string
|
||||
orgId int64
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "default namespace",
|
||||
orgId: 1,
|
||||
expected: "default",
|
||||
},
|
||||
{
|
||||
name: "with org",
|
||||
orgId: 123,
|
||||
expected: "org-123",
|
||||
},
|
||||
{
|
||||
name: "with stackId",
|
||||
cfg: "abc",
|
||||
orgId: 123, // ignored
|
||||
expected: "stack-abc",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mapper := getNamespaceMapper(&setting.Cfg{StackID: tt.cfg})
|
||||
require.Equal(t, tt.expected, mapper(tt.orgId))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,13 +22,8 @@ var (
|
||||
)
|
||||
|
||||
type legacyStorage struct {
|
||||
service playlist.Service
|
||||
}
|
||||
|
||||
func newLegacyStorage(s playlist.Service) *legacyStorage {
|
||||
return &legacyStorage{
|
||||
service: s,
|
||||
}
|
||||
service playlist.Service
|
||||
namespacer namespaceMapper
|
||||
}
|
||||
|
||||
func (s *legacyStorage) New() runtime.Object {
|
||||
@@ -56,9 +51,9 @@ func (s *legacyStorage) ConvertToTable(ctx context.Context, object runtime.Objec
|
||||
func (s *legacyStorage) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) {
|
||||
// TODO: handle fetching all available orgs when no namespace is specified
|
||||
// To test: kubectl get playlists --all-namespaces
|
||||
orgId, ok := grafanarequest.OrgIDFrom(ctx)
|
||||
if !ok {
|
||||
orgId = 1 // TODO: default org ID 1 for now
|
||||
info, err := grafanarequest.NamespaceInfoFrom(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
limit := 100
|
||||
@@ -66,7 +61,7 @@ func (s *legacyStorage) List(ctx context.Context, options *internalversion.ListO
|
||||
limit = int(options.Limit)
|
||||
}
|
||||
res, err := s.service.Search(ctx, &playlist.GetPlaylistsQuery{
|
||||
OrgId: orgId,
|
||||
OrgId: info.OrgID,
|
||||
Limit: limit,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -82,12 +77,12 @@ func (s *legacyStorage) List(ctx context.Context, options *internalversion.ListO
|
||||
for _, v := range res {
|
||||
p, err := s.service.Get(ctx, &playlist.GetPlaylistByUidQuery{
|
||||
UID: v.UID,
|
||||
OrgId: orgId, // required
|
||||
OrgId: info.OrgID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
list.Items = append(list.Items, *convertToK8sResource(p, orgNamespaceMapper))
|
||||
list.Items = append(list.Items, *convertToK8sResource(p, s.namespacer))
|
||||
}
|
||||
if len(list.Items) == limit {
|
||||
list.Continue = "<more>" // TODO?
|
||||
@@ -96,14 +91,14 @@ func (s *legacyStorage) List(ctx context.Context, options *internalversion.ListO
|
||||
}
|
||||
|
||||
func (s *legacyStorage) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
|
||||
orgId, ok := grafanarequest.OrgIDFrom(ctx)
|
||||
if !ok {
|
||||
orgId = 1 // TODO: default org ID 1 for now
|
||||
info, err := grafanarequest.NamespaceInfoFrom(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dto, err := s.service.Get(ctx, &playlist.GetPlaylistByUidQuery{
|
||||
UID: name,
|
||||
OrgId: orgId,
|
||||
OrgId: info.OrgID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -112,5 +107,5 @@ func (s *legacyStorage) Get(ctx context.Context, name string, options *metav1.Ge
|
||||
return nil, fmt.Errorf("not found?")
|
||||
}
|
||||
|
||||
return convertToK8sResource(dto, orgNamespaceMapper), nil
|
||||
return convertToK8sResource(dto, s.namespacer), nil
|
||||
}
|
||||
|
||||
@@ -13,18 +13,24 @@ import (
|
||||
grafanaapiserver "github.com/grafana/grafana/pkg/services/grafana-apiserver"
|
||||
grafanarest "github.com/grafana/grafana/pkg/services/grafana-apiserver/rest"
|
||||
"github.com/grafana/grafana/pkg/services/playlist"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
var _ grafanaapiserver.APIGroupBuilder = (*PlaylistAPIBuilder)(nil)
|
||||
|
||||
// This is used just so wire has something unique to return
|
||||
type PlaylistAPIBuilder struct {
|
||||
service playlist.Service
|
||||
service playlist.Service
|
||||
namespacer namespaceMapper
|
||||
}
|
||||
|
||||
func RegisterAPIService(p playlist.Service, apiregistration grafanaapiserver.APIRegistrar) *PlaylistAPIBuilder {
|
||||
func RegisterAPIService(p playlist.Service,
|
||||
apiregistration grafanaapiserver.APIRegistrar,
|
||||
cfg *setting.Cfg,
|
||||
) *PlaylistAPIBuilder {
|
||||
builder := &PlaylistAPIBuilder{
|
||||
service: p,
|
||||
service: p,
|
||||
namespacer: getNamespaceMapper(cfg),
|
||||
}
|
||||
apiregistration.RegisterAPI(builder)
|
||||
return builder
|
||||
@@ -50,7 +56,10 @@ func (b *PlaylistAPIBuilder) GetAPIGroupInfo(
|
||||
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(GroupName, scheme, metav1.ParameterCodec, codecs)
|
||||
storage := map[string]rest.Storage{}
|
||||
|
||||
legacyStore := newLegacyStorage(b.service)
|
||||
legacyStore := &legacyStorage{
|
||||
service: b.service,
|
||||
namespacer: b.namespacer,
|
||||
}
|
||||
storage["playlists"] = legacyStore
|
||||
|
||||
// enable dual writes if a RESTOptionsGetter is provided
|
||||
|
||||
Reference in New Issue
Block a user