mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
K8s: Move the namespace mapper to the same package that resolves them (#77101)
This commit is contained in:
parent
89f63dcddb
commit
7e069f9d91
@ -7,27 +7,11 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/grafana-apiserver/endpoints/request"
|
||||
"github.com/grafana/grafana/pkg/services/playlist"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
type namespaceMapper = func(orgId int64) string
|
||||
|
||||
func orgNamespaceMapper(orgId int64) string {
|
||||
if orgId == 1 {
|
||||
return "default"
|
||||
}
|
||||
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 {
|
||||
func convertToK8sResource(v *playlist.PlaylistDTO, namespacer request.NamespaceMapper) *Playlist {
|
||||
spec := Spec{
|
||||
Title: v.Name,
|
||||
Interval: v.Interval,
|
||||
|
@ -6,8 +6,8 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/grafana-apiserver/endpoints/request"
|
||||
"github.com/grafana/grafana/pkg/services/playlist"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func TestPlaylistConversion(t *testing.T) {
|
||||
@ -24,7 +24,7 @@ func TestPlaylistConversion(t *testing.T) {
|
||||
{Type: "dashboard_by_id", Value: "123"}, // deprecated
|
||||
},
|
||||
}
|
||||
dst := convertToK8sResource(src, orgNamespaceMapper)
|
||||
dst := convertToK8sResource(src, request.GetNamespaceMapper(nil))
|
||||
|
||||
require.Equal(t, "abc", src.Uid)
|
||||
require.Equal(t, "abc", dst.Name)
|
||||
@ -61,36 +61,3 @@ 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))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
|
||||
grafanarequest "github.com/grafana/grafana/pkg/services/grafana-apiserver/endpoints/request"
|
||||
"github.com/grafana/grafana/pkg/services/grafana-apiserver/endpoints/request"
|
||||
"github.com/grafana/grafana/pkg/services/playlist"
|
||||
)
|
||||
|
||||
@ -23,7 +23,7 @@ var (
|
||||
|
||||
type legacyStorage struct {
|
||||
service playlist.Service
|
||||
namespacer namespaceMapper
|
||||
namespacer request.NamespaceMapper
|
||||
tableConverter rest.TableConvertor
|
||||
}
|
||||
|
||||
@ -52,7 +52,7 @@ 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
|
||||
info, err := grafanarequest.NamespaceInfoFrom(ctx, true)
|
||||
info, err := request.NamespaceInfoFrom(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -87,7 +87,7 @@ 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) {
|
||||
info, err := grafanarequest.NamespaceInfoFrom(ctx, true)
|
||||
info, err := request.NamespaceInfoFrom(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
common "k8s.io/kube-openapi/pkg/common"
|
||||
|
||||
grafanaapiserver "github.com/grafana/grafana/pkg/services/grafana-apiserver"
|
||||
"github.com/grafana/grafana/pkg/services/grafana-apiserver/endpoints/request"
|
||||
grafanarest "github.com/grafana/grafana/pkg/services/grafana-apiserver/rest"
|
||||
"github.com/grafana/grafana/pkg/services/grafana-apiserver/utils"
|
||||
"github.com/grafana/grafana/pkg/services/playlist"
|
||||
@ -29,7 +30,7 @@ var _ grafanaapiserver.APIGroupBuilder = (*PlaylistAPIBuilder)(nil)
|
||||
// This is used just so wire has something unique to return
|
||||
type PlaylistAPIBuilder struct {
|
||||
service playlist.Service
|
||||
namespacer namespaceMapper
|
||||
namespacer request.NamespaceMapper
|
||||
gv schema.GroupVersion
|
||||
}
|
||||
|
||||
@ -39,7 +40,7 @@ func RegisterAPIService(p playlist.Service,
|
||||
) *PlaylistAPIBuilder {
|
||||
builder := &PlaylistAPIBuilder{
|
||||
service: p,
|
||||
namespacer: getNamespaceMapper(cfg),
|
||||
namespacer: request.GetNamespaceMapper(cfg),
|
||||
gv: schema.GroupVersion{Group: GroupName, Version: VersionID},
|
||||
}
|
||||
apiregistration.RegisterAPI(builder)
|
||||
|
@ -7,6 +7,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/apiserver/pkg/endpoints/request"
|
||||
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
type NamespaceInfo struct {
|
||||
@ -20,6 +22,22 @@ type NamespaceInfo struct {
|
||||
Value string
|
||||
}
|
||||
|
||||
// NamespaceMapper converts an orgID into a namespace
|
||||
type NamespaceMapper = func(orgId int64) string
|
||||
|
||||
// GetNamespaceMapper returns a function that will convert orgIds into a consistent namespace
|
||||
func GetNamespaceMapper(cfg *setting.Cfg) NamespaceMapper {
|
||||
if cfg != nil && cfg.StackID != "" {
|
||||
return func(orgId int64) string { return "stack-" + cfg.StackID }
|
||||
}
|
||||
return func(orgId int64) string {
|
||||
if orgId == 1 {
|
||||
return "default"
|
||||
}
|
||||
return fmt.Sprintf("org-%d", orgId)
|
||||
}
|
||||
}
|
||||
|
||||
func NamespaceInfoFrom(ctx context.Context, requireOrgID bool) (NamespaceInfo, error) {
|
||||
info, err := ParseNamespace(request.NamespaceValue(ctx))
|
||||
if err == nil && requireOrgID && info.OrgID < 1 {
|
@ -3,19 +3,22 @@ package request_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
grafanarequest "github.com/grafana/grafana/pkg/services/grafana-apiserver/endpoints/request"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/grafana-apiserver/endpoints/request"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func TestParseNamespace(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
namespace string
|
||||
expected grafanarequest.NamespaceInfo
|
||||
expected request.NamespaceInfo
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
name: "empty namespace",
|
||||
expected: grafanarequest.NamespaceInfo{
|
||||
expected: request.NamespaceInfo{
|
||||
OrgID: -1,
|
||||
},
|
||||
},
|
||||
@ -23,7 +26,7 @@ func TestParseNamespace(t *testing.T) {
|
||||
name: "incorrect number of parts",
|
||||
namespace: "org-123-a",
|
||||
expectErr: true,
|
||||
expected: grafanarequest.NamespaceInfo{
|
||||
expected: request.NamespaceInfo{
|
||||
OrgID: -1,
|
||||
},
|
||||
},
|
||||
@ -31,14 +34,14 @@ func TestParseNamespace(t *testing.T) {
|
||||
name: "org id not a number",
|
||||
namespace: "org-invalid",
|
||||
expectErr: true,
|
||||
expected: grafanarequest.NamespaceInfo{
|
||||
expected: request.NamespaceInfo{
|
||||
OrgID: -1,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "valid org id",
|
||||
namespace: "org-123",
|
||||
expected: grafanarequest.NamespaceInfo{
|
||||
expected: request.NamespaceInfo{
|
||||
OrgID: 123,
|
||||
},
|
||||
},
|
||||
@ -46,7 +49,7 @@ func TestParseNamespace(t *testing.T) {
|
||||
name: "org should not be 1 in the namespace",
|
||||
namespace: "org-1",
|
||||
expectErr: true,
|
||||
expected: grafanarequest.NamespaceInfo{
|
||||
expected: request.NamespaceInfo{
|
||||
OrgID: -1,
|
||||
},
|
||||
},
|
||||
@ -54,7 +57,7 @@ func TestParseNamespace(t *testing.T) {
|
||||
name: "can not be negative",
|
||||
namespace: "org--5",
|
||||
expectErr: true,
|
||||
expected: grafanarequest.NamespaceInfo{
|
||||
expected: request.NamespaceInfo{
|
||||
OrgID: -1,
|
||||
},
|
||||
},
|
||||
@ -62,21 +65,21 @@ func TestParseNamespace(t *testing.T) {
|
||||
name: "can not be zero",
|
||||
namespace: "org-0",
|
||||
expectErr: true,
|
||||
expected: grafanarequest.NamespaceInfo{
|
||||
expected: request.NamespaceInfo{
|
||||
OrgID: -1,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "default is org 1",
|
||||
namespace: "default",
|
||||
expected: grafanarequest.NamespaceInfo{
|
||||
expected: request.NamespaceInfo{
|
||||
OrgID: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "valid stack",
|
||||
namespace: "stack-abcdef",
|
||||
expected: grafanarequest.NamespaceInfo{
|
||||
expected: request.NamespaceInfo{
|
||||
OrgID: 1,
|
||||
StackID: "abcdef",
|
||||
},
|
||||
@ -85,7 +88,7 @@ func TestParseNamespace(t *testing.T) {
|
||||
name: "invalid stack id",
|
||||
namespace: "stack-",
|
||||
expectErr: true,
|
||||
expected: grafanarequest.NamespaceInfo{
|
||||
expected: request.NamespaceInfo{
|
||||
OrgID: -1,
|
||||
},
|
||||
},
|
||||
@ -93,7 +96,7 @@ func TestParseNamespace(t *testing.T) {
|
||||
name: "invalid stack id (too short)",
|
||||
namespace: "stack-1",
|
||||
expectErr: true,
|
||||
expected: grafanarequest.NamespaceInfo{
|
||||
expected: request.NamespaceInfo{
|
||||
OrgID: -1,
|
||||
StackID: "1",
|
||||
},
|
||||
@ -101,7 +104,7 @@ func TestParseNamespace(t *testing.T) {
|
||||
{
|
||||
name: "other namespace",
|
||||
namespace: "anything",
|
||||
expected: grafanarequest.NamespaceInfo{
|
||||
expected: request.NamespaceInfo{
|
||||
OrgID: -1,
|
||||
Value: "anything",
|
||||
},
|
||||
@ -110,7 +113,7 @@ func TestParseNamespace(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
info, err := grafanarequest.ParseNamespace(tt.namespace)
|
||||
info, err := request.ParseNamespace(tt.namespace)
|
||||
if tt.expectErr != (err != nil) {
|
||||
t.Errorf("ParseNamespace() returned %+v, expected an error", info)
|
||||
}
|
||||
@ -126,3 +129,36 @@ func TestParseNamespace(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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 := request.GetNamespaceMapper(&setting.Cfg{StackID: tt.cfg})
|
||||
require.Equal(t, tt.expected, mapper(tt.orgId))
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user