Skip to content

Commit

Permalink
Migrated away from folder ID to folderUID as ID was deprecated.
Browse files Browse the repository at this point in the history
  • Loading branch information
safaci2000 committed Sep 3, 2024
1 parent 34363ed commit aeee7eb
Show file tree
Hide file tree
Showing 18 changed files with 447 additions and 64 deletions.
1 change: 0 additions & 1 deletion internal/service/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (

var (
DefaultFolderName = "General"
DefaultFolderId = int64(0)
searchTypeDashboard = "dash-db"
searchTypeFolder = "dash-folder"
)
Expand Down
32 changes: 27 additions & 5 deletions internal/service/connection_permissions.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package service
import (
"encoding/json"
"fmt"
"github.com/esnet/gdg/internal/tools"
"github.com/esnet/gdg/internal/types"
"github.com/grafana/grafana-openapi-client-go/client/access_control"
"log"
Expand All @@ -25,10 +26,15 @@ const (
connectionResourceType string = "datasources"
)

const connectionPermissionMinVersion = "v10.2.3"

// ListConnectionPermissions lists all connection permission matching the given filter
func (s *DashNGoImpl) ListConnectionPermissions(filter filters.Filter) []types.ConnectionPermissionItem {
if !s.IsEnterprise() {
log.Fatal("Requires Enterprise to be enabled. Please check your GDG configuration and try again")
} else if !tools.ValidateMinimumVersion(connectionPermissionMinVersion, s) {
slog.Warn("Permission with connection is broken prior to 10.2.3. GDG won't support a prior version. Listing is allowed, but all other operations won't work.",
slog.Any("Your Grafana Version", "v"+s.GetServerInfo()["Version"].(string)))
}
result := make([]types.ConnectionPermissionItem, 0)
connections := s.ListConnections(filter)
Expand Down Expand Up @@ -57,6 +63,9 @@ func (s *DashNGoImpl) DownloadConnectionPermissions(filter filters.Filter) []str
err error
dataFiles []string
)
if !tools.ValidateMinimumVersion(connectionPermissionMinVersion, s) {
log.Fatalf("Permission with connection is broken prior to 10.2.3. GDG won't support a prior version. Listing is allowed, but all other operations won't work. Your Grafana version is: v%s", s.GetServerInfo()["Version"].(string))
}
currentPermissions := s.ListConnectionPermissions(filter)
for _, connection := range currentPermissions {
if dsPacked, err = json.MarshalIndent(connection, "", " "); err != nil {
Expand All @@ -75,9 +84,16 @@ func (s *DashNGoImpl) DownloadConnectionPermissions(filter filters.Filter) []str

// UploadConnectionPermissions upload connection permissions
func (s *DashNGoImpl) UploadConnectionPermissions(filter filters.Filter) []string {
if !tools.ValidateMinimumVersion(connectionPermissionMinVersion, s) {
log.Fatalf("Permission with connection is broken prior to 10.2.3. GDG won't support a prior version. Listing is allowed, but all other operations won't work. Your Grafana version is: v%s", s.GetServerInfo()["Version"].(string))
}
if !s.IsEnterprise() {
log.Fatal("Requires Enterprise to be enabled. Please check your GDG configuration and try again")
}
//if !tools.ValidateMinimumVersion("11.0.0", s) {
// log.Fatal("Behavior prior to version 11.0.0 is broken. ")
//
//}
var (
rawFolder []byte
dataFiles []string
Expand Down Expand Up @@ -113,7 +129,6 @@ func (s *DashNGoImpl) UploadConnectionPermissions(filter filters.Filter) []strin
continue
}

success := true
var removePermissionError error
// Delete datasource Permissions
for _, p := range permissions.GetPayload() {
Expand All @@ -129,11 +144,11 @@ func (s *DashNGoImpl) UploadConnectionPermissions(filter filters.Filter) []strin
continue
}

success = true
success := true
for _, permission := range newEntries.Permissions {
err = s.updatedConnectionPermission(newEntries.Connection, permission, permission.Permission)
if err != nil {
slog.Error("Failed to update folder permissions")
slog.Error("Failed to update connection permissions", slog.Any("userId", permission.UserLogin), slog.Any("team", permission.Team), slog.Any("role", permission.BuiltInRole), slog.Any("permission", permission.Permission))
success = false
}

Expand All @@ -149,6 +164,9 @@ func (s *DashNGoImpl) UploadConnectionPermissions(filter filters.Filter) []strin

// DeleteAllConnectionPermissions clear all non-default permissions from all connections
func (s *DashNGoImpl) DeleteAllConnectionPermissions(filter filters.Filter) []string {
if !tools.ValidateMinimumVersion(connectionPermissionMinVersion, s) {
log.Fatalf("Permission with connection is broken prior to 10.2.3. GDG won't support a prior version. Listing is allowed, but all other operations won't work. Your Grafana version is: v%s", s.GetServerInfo()["Version"].(string))
}
dataSources := make([]string, 0)
connectionPermissions := s.ListConnectionPermissions(filter)
for _, conn := range connectionPermissions {
Expand Down Expand Up @@ -188,6 +206,10 @@ func (s *DashNGoImpl) updatedConnectionPermission(key *models.DataSourceListItem
connectionId := key.UID
switch permType := getPermissionType(*perm); permType {
case ConnectionRolePermission:
if perm.Permission == "Admin" {
slog.Info("Skipping modifications to admin role permission")
return nil
}
//update User Role
//POST /api/access-control/datasources/:uid/builtInRoles/:builtinRoleName
p := access_control.NewSetResourcePermissionsForBuiltInRoleParams()
Expand All @@ -203,8 +225,8 @@ func (s *DashNGoImpl) updatedConnectionPermission(key *models.DataSourceListItem
return err
}
case ConnectionUserPermission:
if permission == "" && perm.UserLogin == "admin" && perm.UserID == 1 {
slog.Info("Skipping revoking access to grafana admin from connection")
if perm.UserLogin == "admin" && perm.UserID == 1 {
slog.Info("Skipping modifications to admin user permission")
return nil
}
//POST /api/access-control/datasources/:uid/users/:id
Expand Down
24 changes: 12 additions & 12 deletions internal/service/dashboards.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,15 +310,15 @@ func (s *DashNGoImpl) DownloadDashboards(filter filters.Filter) []string {
}

// createFolder Creates a new folder with the given name.
func (s *DashNGoImpl) createdFolder(folderName string) (int64, error) {
func (s *DashNGoImpl) createdFolder(folderName string) (string, error) {
request := &models.CreateFolderCommand{
Title: folderName,
}
folder, err := s.GetClient().Folders.CreateFolder(request)
if err != nil {
return 0, err
return "", err
}
return folder.GetPayload().ID, nil
return folder.GetPayload().UID, nil

}

Expand All @@ -329,7 +329,7 @@ func (s *DashNGoImpl) UploadDashboards(filterReq filters.Filter) {
var (
rawBoard []byte
folderName string
folderId int64
folderUid string
)
path := config.Config().GetDefaultGrafanaConfig().GetPath(config.DashboardResource)
filesInDir, err := s.storage.FindAllFiles(path, true)
Expand All @@ -339,7 +339,7 @@ func (s *DashNGoImpl) UploadDashboards(filterReq filters.Filter) {
//Delete all dashboards that match prior to import
s.DeleteAllDashboards(filterReq)

folderMap := getFolderNameIDMap(s.ListFolder(NewFolderFilter()))
folderUidMap := getFolderNameUIDMap(s.ListFolder(NewFolderFilter()))

// Fallback on defaults
if filterReq == nil {
Expand Down Expand Up @@ -397,7 +397,6 @@ func (s *DashNGoImpl) UploadDashboards(filterReq filters.Filter) {
}

if folderName == "" || folderName == DefaultFolderName {
folderId = DefaultFolderId
folderName = DefaultFolderName
}
if !slices.Contains(validFolders, folderName) && !config.Config().GetDefaultGrafanaConfig().GetFilterOverrides().IgnoreDashboardFilters {
Expand All @@ -411,19 +410,20 @@ func (s *DashNGoImpl) UploadDashboards(filterReq filters.Filter) {
}

if folderName == DefaultFolderName {
folderId = DefaultFolderId
folderUid = ""
} else {

if val, ok := folderMap[folderName]; ok {
folderId = val
if val, ok := folderUidMap[folderName]; ok {
//folderId = val
folderUid = val
} else {
if filterReq.ValidateAll(validateMap) {
id, folderErr := s.createdFolder(folderName)
if folderErr != nil {
log.Panic("Unable to create required folder")
} else {
folderMap[folderName] = id
folderId = id
folderUidMap[folderName] = id
folderUid = id
}
}
}
Expand All @@ -439,7 +439,7 @@ func (s *DashNGoImpl) UploadDashboards(filterReq filters.Filter) {
//zero out ID. Can't create a new dashboard if an ID already exists.
delete(data, "id")
importDashReq := &models.ImportDashboardRequest{
FolderID: folderId,
FolderUID: folderUid,
Overwrite: true,
Dashboard: data,
}
Expand Down
9 changes: 9 additions & 0 deletions internal/service/folders.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,15 @@ func getFolderNameIDMap(folders []*models.Hit) map[string]int64 {
return folderMap
}

// getFolderNameUIDMap helper function to build a mapping for name to folderID
func getFolderNameUIDMap(folders []*models.Hit) map[string]string {
var folderMap = make(map[string]string)
for _, folder := range folders {
folderMap[folder.Title] = folder.UID
}
return folderMap
}

// Creates a reverse look up map, where the values are the keys and the keys are the values.
func reverseLookUp[T comparable, Y comparable](m map[T]Y) map[Y]T {
reverse := make(map[Y]T, 0)
Expand Down
10 changes: 8 additions & 2 deletions internal/service/gdg_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,15 @@ func newInstance() *DashNGoImpl {
obj.debug = config.Config().IsDebug()
obj.apiDebug = config.Config().IsApiDebug()
if obj.apiDebug {
os.Setenv("DEBUG", "1")
err := os.Setenv("DEBUG", "1")
if err != nil {
slog.Debug("unable to set debug env value", slog.Any("err", err))
}
} else {
os.Setenv("DEBUG", "0")
err := os.Setenv("DEBUG", "0")
if err != nil {
slog.Debug("unable to set debug env value", slog.Any("err", err))
}
}
obj.Login()
configureStorage(obj)
Expand Down
4 changes: 2 additions & 2 deletions internal/service/libraryelements.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func (s *DashNGoImpl) DownloadLibraryElements(filter filters.Filter) []string {
dataFiles []string
)

folderMap := reverseLookUp(getFolderNameIDMap(s.ListFolder(nil)))
folderMap := reverseLookUp(getFolderNameUIDMap(s.ListFolder(nil)))
listing = s.ListLibraryElements(filter)
for _, item := range listing {
if dsPacked, err = json.MarshalIndent(item, "", " "); err != nil {
Expand All @@ -92,7 +92,7 @@ func (s *DashNGoImpl) DownloadLibraryElements(filter filters.Filter) []string {
}
folderName := DefaultFolderName

if val, ok := folderMap[item.FolderID]; ok {
if val, ok := folderMap[item.FolderUID]; ok {
folderName = val
}

Expand Down
77 changes: 77 additions & 0 deletions internal/service/mocks/LicenseApi.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions pkg/test_tooling/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
const (
GrafanaTestVersionEnv = "GRAFANA_TEST_VERSION"

// #nosec G101
EnableTokenTestsEnv = "TEST_TOKEN_CONFIG"
)

Expand Down Expand Up @@ -74,7 +75,7 @@ func InitTest(t *testing.T, cfgName *string, useEnterprise bool) (service.Grafan
tokenCfg, err := os.CreateTemp("config", "token*.yml")
assert.Nil(t, err, "Unable to create token configuration file")
newCfg := tokenCfg.Name()
err = os.WriteFile(newCfg, updatedCfg, 0644)
err = os.WriteFile(newCfg, updatedCfg, 0600)
assert.Nil(t, err)

cleanUp := func() error {
Expand All @@ -99,7 +100,7 @@ func CreateSimpleClient(t *testing.T, cfgName *string, container testcontainers.
assert.Nil(t, err)
dockerContainer, ok := container.(*testcontainers.DockerContainer)
if ok {
slog.Info("Grafana Test container running", slog.String("host", grafanaHost), slog.String("imageVersion", dockerContainer.Image))
slog.Info("Grafana Test container running", slog.String("host", grafanaHost+"/login"), slog.String("imageVersion", dockerContainer.Image))
}

config.InitGdgConfig(*cfgName, "'")
Expand Down
7 changes: 5 additions & 2 deletions pkg/test_tooling/containers/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ func SetupGrafanaLicense() (map[string]string, error) {
func SetupGrafanaContainer(additionalEnvProps map[string]string, version, imageSuffix string) (testcontainers.Container, func()) {
retry := func() (testcontainers.Container, func(), error) {
defaultProps := map[string]string{
"GF_INSTALL_PLUGINS": "grafana-googlesheets-datasource",
"GF_AUTH_ANONYMOUS_ENABLED": "true",
"GF_INSTALL_PLUGINS": "grafana-googlesheets-datasource",
"GF_AUTH_ANONYMOUS_ENABLED": "true",
"GF_SECURITY_ADMIN_PASSWORD": "admin", // This is a no-op right now, but we should trickle this up to
// allow setting grafana admin credentials.
}
if version == "" {
version = os.Getenv(defaultGrafanaVersionEnv)
Expand Down Expand Up @@ -103,6 +105,7 @@ func SetupGrafanaContainer(additionalEnvProps map[string]string, version, imageS
return grafanaC, cancel, nil
}

//retry a few times just in case.
for i := 0; i < 3; i++ {
container, cancelFn, err := retry()
if err == nil {
Expand Down
16 changes: 8 additions & 8 deletions test/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ func TestMain(m *testing.M) {
if err != nil {
panic(err)
}

err = godotenv.Load(".env")
//set global log level
slog.SetLogLoggerLevel(slog.LevelDebug) // Set global log level to Debug
grafanaTestVersions := []string{"10.0.0-ubuntu", "11.1.4-ubuntu"}
grafanaTestVersions := []string{"10.2.3-ubuntu", "11.1.5-ubuntu"}
testModes := []string{"basicAuth", "token"}
////Hack while Debugging
//if true {
// slog.Debug("Limiting to single testMode and grafana version", slog.Any("grafanaVersion", grafanaTestVersions[1]), slog.String("testMode", testModes[0]))
// grafanaTestVersions = grafanaTestVersions[1:]
// testModes = testModes[0:1]
//}
if os.Getenv("DEVELOPER") == "1" {
slog.Debug("Limiting to single testMode and grafana version", slog.Any("grafanaVersion", grafanaTestVersions[1]), slog.String("testMode", testModes[0]))
grafanaTestVersions = grafanaTestVersions[1:]
testModes = testModes[0:1]
}

err = godotenv.Load(".env")
for _, version := range grafanaTestVersions {
for _, i := range testModes {
os.Setenv(test_tooling.GrafanaTestVersionEnv, version)
Expand Down
Loading

0 comments on commit aeee7eb

Please sign in to comment.