diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 00000000..f7c6714b --- /dev/null +++ b/.drone.yml @@ -0,0 +1,11 @@ +kind: pipeline +name: default + +steps: +- name: build + image: golang:1.16 + commands: + - make linux + - cp conf/importer-example.yml conf/importer.yml + - ./bin/grafana-dashboard-manager_linux version + diff --git a/.vscode/launch.json b/.vscode/launch.json index 49a8628f..5c8a830d 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,12 +11,11 @@ "mode": "debug", "program": "${workspaceFolder}", "args": [ - "ds", - "export" - //"datasources", - //"list" - //"-f", - //"c3fjqulMz" + "users", + "list", + //"promote", + //"-u", + //"user@domain.com" ] } ] diff --git a/Makefile b/Makefile index 9f937f2e..216ad6d6 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ IMAGE_NAME := "netsage-project/grafana-dashboard-manager" default: test linux: clean - env GOOS='linux' GOARCH='amd64' go build -o grafana-dashboard-manager_linux + env GOOS='linux' GOARCH='amd64' go build -ldflags "-X github.com/netsage-project/grafana-dashboard-manager/version.GitCommit=${GIT_COMMIT}${GIT_DIRTY} -X github.com/netsage-project/grafana-dashboard-manager/version.BuildDate=${BUILD_DATE}" -o bin/${BIN_NAME}_linux help: @echo 'Management commands for grafana-dashboard-manager:' diff --git a/api/user.go b/api/user.go new file mode 100644 index 00000000..1f9d7020 --- /dev/null +++ b/api/user.go @@ -0,0 +1,53 @@ +package api + +import ( + "context" + "errors" + "fmt" + + "github.com/netsage-project/sdk" + "github.com/sirupsen/logrus" +) + +//ListUsers list all grafana users +func ListUsers(client *sdk.Client) []sdk.User { + ctx := context.Background() + users, err := client.GetAllUsers(ctx) + if err != nil { + logrus.Panic("Unable to get users") + } + return users +} + +//PromoteUser promote the user to have Admin Access +func PromoteUser(client *sdk.Client, userLogin string) (*sdk.StatusMessage, error) { + + ctx := context.Background() + //Get all users + users := ListUsers(client) + var user *sdk.User + for _, item := range users { + if item.Login == userLogin { + user = &item + break + } + + } + + if user == nil { + return nil, fmt.Errorf("user: '%s' could not be found", userLogin) + } + + role := sdk.UserPermissions{ + IsGrafanaAdmin: true, + } + msg, err := client.UpdateUserPermissions(ctx, role, user.ID) + if err != nil { + errorMsg := fmt.Sprintf("failed to promote user: '%s'", userLogin) + logrus.Error(errorMsg) + return nil, errors.New(errorMsg) + } + + return &msg, nil + +} diff --git a/cmd/userPromote.go b/cmd/userPromote.go new file mode 100644 index 00000000..97f4053c --- /dev/null +++ b/cmd/userPromote.go @@ -0,0 +1,33 @@ +package cmd + +import ( + "github.com/netsage-project/grafana-dashboard-manager/api" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var promoteUser = &cobra.Command{ + Use: "promote", + Short: "Promote User to Grafana Admin", + Long: `Promote User to Grafana Admin`, + Aliases: []string{"godmode"}, + Run: func(cmd *cobra.Command, args []string) { + + userLogin, _ := cmd.Flags().GetString("user") + + msg, err := api.PromoteUser(client, userLogin) + if err != nil { + logrus.Error(err.Error()) + } else { + logrus.Info(*msg.Message) + logrus.Info("Please note user is a grafana admin, not necessarily an Org admin. You may need to promote yourself manually per org") + } + + }, +} + +func init() { + userCmd.AddCommand(promoteUser) + promoteUser.Flags().StringP("user", "u", "", "user email") + promoteUser.MarkFlagRequired("user") +} diff --git a/cmd/users.go b/cmd/users.go new file mode 100644 index 00000000..e0912fb1 --- /dev/null +++ b/cmd/users.go @@ -0,0 +1,16 @@ +package cmd + +import ( + "github.com/spf13/cobra" +) + +// userCmd represents the version command +var userCmd = &cobra.Command{ + Use: "users", + Short: "Manage users", + Long: `Manage users.`, +} + +func init() { + rootCmd.AddCommand(userCmd) +} diff --git a/cmd/usersList.go b/cmd/usersList.go new file mode 100644 index 00000000..2171e7d2 --- /dev/null +++ b/cmd/usersList.go @@ -0,0 +1,39 @@ +package cmd + +import ( + "strings" + + "github.com/jedib0t/go-pretty/table" + "github.com/netsage-project/grafana-dashboard-manager/api" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var listUserCmd = &cobra.Command{ + Use: "list", + Short: "list users", + Long: `list users`, + Run: func(cmd *cobra.Command, args []string) { + + tableObj.AppendHeader(table.Row{"id", "login", "name", "email", "admin", "grafanaAdmin", "disabled", "authLabels"}) + users := api.ListUsers(client) + if len(users) == 0 { + log.Info("No users found") + } else { + for _, user := range users { + var labels string + if len(user.AuthLabels) > 0 { + labels = strings.Join(user.AuthLabels, ", ") + + } + tableObj.AppendRow(table.Row{user.ID, user.Login, user.Name, user.Email, user.IsAdmin, user.IsAdmin, user.IsDisabled, labels}) + } + tableObj.Render() + } + + }, +} + +func init() { + userCmd.AddCommand(listUserCmd) +} diff --git a/go.mod b/go.mod index d8821c37..b079de56 100644 --- a/go.mod +++ b/go.mod @@ -6,11 +6,11 @@ require ( github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect github.com/go-openapi/errors v0.20.0 // indirect github.com/go-openapi/strfmt v0.20.1 // indirect - github.com/gosimple/slug v1.1.1 + github.com/gosimple/slug v1.9.0 github.com/jedib0t/go-pretty v4.3.0+incompatible github.com/mattn/go-runewidth v0.0.12 // indirect github.com/mitchellh/mapstructure v1.4.1 // indirect - github.com/netsage-project/sdk v0.1.2 + github.com/netsage-project/sdk v0.1.3-0.20210512193805-a3b05178eae0 github.com/rivo/uniseg v0.2.0 // indirect github.com/sirupsen/logrus v1.6.0 github.com/spf13/cobra v1.0.0 diff --git a/go.sum b/go.sum index aa8be4b5..f77bb1ce 100644 --- a/go.sum +++ b/go.sum @@ -126,8 +126,9 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGa github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gosimple/slug v1.1.1 h1:fRu/digW+NMwBIP+RmviTK97Ho/bEj/C9swrCspN3D4= github.com/gosimple/slug v1.1.1/go.mod h1:ER78kgg1Mv0NQGlXiDe57DpCyfbNywXXZ9mIorhxAf0= +github.com/gosimple/slug v1.9.0 h1:r5vDcYrFz9BmfIAMC829un9hq7hKM4cHUrsv36LbEqs= +github.com/gosimple/slug v1.9.0/go.mod h1:AMZ+sOVe65uByN3kgEyf9WEBKBCSS+dJjMX9x4vDJbg= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= @@ -210,8 +211,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/netsage-project/sdk v0.1.2 h1:c9F0zuuvG9fuXc0KfWWlSWS7hEASbbSBfTHHT2HdMyE= -github.com/netsage-project/sdk v0.1.2/go.mod h1:eU/b1Am/74/Z4ZFo+riR0BS3xv2c9SS6jWwL0Hw+Ovg= +github.com/netsage-project/sdk v0.1.3-0.20210512193805-a3b05178eae0 h1:BZALPdt/fTKk4MbjEPN42dVm+DpfHp/CLqirJNdKS+o= +github.com/netsage-project/sdk v0.1.3-0.20210512193805-a3b05178eae0/go.mod h1:eU/b1Am/74/Z4ZFo+riR0BS3xv2c9SS6jWwL0Hw+Ovg= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=