mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
SupportBundles: Add LDAP bundle collector (#63128)
* fix non-cfg fields used in ldap * fix non-cfg fields * add ldap support bundle * add note on match * add censoring and docs
This commit is contained in:
parent
e42eaeb175
commit
7862ae8abf
@ -30,6 +30,7 @@ A support bundle can include any of the following components:
|
|||||||
- **Basic information**: Basic information about the Grafana instance (version, memory usage, and so on)
|
- **Basic information**: Basic information about the Grafana instance (version, memory usage, and so on)
|
||||||
- **Settings**: Settings for the Grafana instance
|
- **Settings**: Settings for the Grafana instance
|
||||||
- **SAML**: Healthcheck connection and metadata for SAML (only displayed if SAML is enabled)
|
- **SAML**: Healthcheck connection and metadata for SAML (only displayed if SAML is enabled)
|
||||||
|
- **LDAP**: Healthcheck connection and metadata for LDAP (only displayed if LDAP is enabled)
|
||||||
|
|
||||||
## Steps
|
## Steps
|
||||||
|
|
||||||
|
@ -19,12 +19,22 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/ldap/multildap"
|
"github.com/grafana/grafana/pkg/services/ldap/multildap"
|
||||||
"github.com/grafana/grafana/pkg/services/login"
|
"github.com/grafana/grafana/pkg/services/login"
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
|
"github.com/grafana/grafana/pkg/services/supportbundles"
|
||||||
"github.com/grafana/grafana/pkg/services/user"
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
"github.com/grafana/grafana/pkg/web"
|
"github.com/grafana/grafana/pkg/web"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
getLDAPConfig = multildap.GetConfig
|
||||||
|
newLDAP = multildap.New
|
||||||
|
|
||||||
|
errOrganizationNotFound = func(orgId int64) error {
|
||||||
|
return fmt.Errorf("unable to find organization with ID '%d'", orgId)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
cfg *setting.Cfg
|
cfg *setting.Cfg
|
||||||
userService user.Service
|
userService user.Service
|
||||||
@ -38,7 +48,8 @@ type Service struct {
|
|||||||
|
|
||||||
func ProvideService(cfg *setting.Cfg, router routing.RouteRegister, accessControl ac.AccessControl,
|
func ProvideService(cfg *setting.Cfg, router routing.RouteRegister, accessControl ac.AccessControl,
|
||||||
userService user.Service, authInfoService login.AuthInfoService, ldapGroupsService ldap.Groups,
|
userService user.Service, authInfoService login.AuthInfoService, ldapGroupsService ldap.Groups,
|
||||||
loginService login.Service, orgService org.Service, sessionService auth.UserTokenService) *Service {
|
loginService login.Service, orgService org.Service,
|
||||||
|
sessionService auth.UserTokenService, bundleRegistry supportbundles.Service) *Service {
|
||||||
s := &Service{
|
s := &Service{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
userService: userService,
|
userService: userService,
|
||||||
@ -60,18 +71,20 @@ func ProvideService(cfg *setting.Cfg, router routing.RouteRegister, accessContro
|
|||||||
adminRoute.Get("/ldap/status", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionLDAPStatusRead)), routing.Wrap(s.GetLDAPStatus))
|
adminRoute.Get("/ldap/status", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionLDAPStatusRead)), routing.Wrap(s.GetLDAPStatus))
|
||||||
}, middleware.ReqSignedIn)
|
}, middleware.ReqSignedIn)
|
||||||
|
|
||||||
|
if cfg.LDAPEnabled {
|
||||||
|
bundleRegistry.RegisterSupportItemCollector(supportbundles.Collector{
|
||||||
|
UID: "auth-ldap",
|
||||||
|
DisplayName: "LDAP",
|
||||||
|
Description: "LDAP authentication healthcheck and configuration data",
|
||||||
|
IncludedByDefault: false,
|
||||||
|
Default: false,
|
||||||
|
Fn: s.supportBundleCollector,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
getLDAPConfig = multildap.GetConfig
|
|
||||||
newLDAP = multildap.New
|
|
||||||
|
|
||||||
errOrganizationNotFound = func(orgId int64) error {
|
|
||||||
return fmt.Errorf("unable to find organization with ID '%d'", orgId)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// LDAPAttribute is a serializer for user attributes mapped from LDAP. Is meant to display both the serialized value and the LDAP key we received it from.
|
// LDAPAttribute is a serializer for user attributes mapped from LDAP. Is meant to display both the serialized value and the LDAP key we received it from.
|
||||||
type LDAPAttribute struct {
|
type LDAPAttribute struct {
|
||||||
ConfigAttributeValue string `json:"cfgAttrValue"`
|
ConfigAttributeValue string `json:"cfgAttrValue"`
|
||||||
@ -159,11 +172,11 @@ func (user *LDAPUserDTO) FetchOrgs(ctx context.Context, orga org.Service) error
|
|||||||
// 403: forbiddenError
|
// 403: forbiddenError
|
||||||
// 500: internalServerError
|
// 500: internalServerError
|
||||||
func (s *Service) ReloadLDAPCfg(c *contextmodel.ReqContext) response.Response {
|
func (s *Service) ReloadLDAPCfg(c *contextmodel.ReqContext) response.Response {
|
||||||
if !ldap.IsEnabled() {
|
if !s.cfg.LDAPEnabled {
|
||||||
return response.Error(http.StatusBadRequest, "LDAP is not enabled", nil)
|
return response.Error(http.StatusBadRequest, "LDAP is not enabled", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := ldap.ReloadConfig()
|
err := ldap.ReloadConfig(s.cfg.LDAPConfigFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.Error(http.StatusInternalServerError, "Failed to reload LDAP config", err)
|
return response.Error(http.StatusInternalServerError, "Failed to reload LDAP config", err)
|
||||||
}
|
}
|
||||||
@ -185,7 +198,7 @@ func (s *Service) ReloadLDAPCfg(c *contextmodel.ReqContext) response.Response {
|
|||||||
// 403: forbiddenError
|
// 403: forbiddenError
|
||||||
// 500: internalServerError
|
// 500: internalServerError
|
||||||
func (s *Service) GetLDAPStatus(c *contextmodel.ReqContext) response.Response {
|
func (s *Service) GetLDAPStatus(c *contextmodel.ReqContext) response.Response {
|
||||||
if !ldap.IsEnabled() {
|
if !s.cfg.LDAPEnabled {
|
||||||
return response.Error(http.StatusBadRequest, "LDAP is not enabled", nil)
|
return response.Error(http.StatusBadRequest, "LDAP is not enabled", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +251,7 @@ func (s *Service) GetLDAPStatus(c *contextmodel.ReqContext) response.Response {
|
|||||||
// 403: forbiddenError
|
// 403: forbiddenError
|
||||||
// 500: internalServerError
|
// 500: internalServerError
|
||||||
func (s *Service) PostSyncUserWithLDAP(c *contextmodel.ReqContext) response.Response {
|
func (s *Service) PostSyncUserWithLDAP(c *contextmodel.ReqContext) response.Response {
|
||||||
if !ldap.IsEnabled() {
|
if !s.cfg.LDAPEnabled {
|
||||||
return response.Error(http.StatusBadRequest, "LDAP is not enabled", nil)
|
return response.Error(http.StatusBadRequest, "LDAP is not enabled", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,7 +347,7 @@ func (s *Service) PostSyncUserWithLDAP(c *contextmodel.ReqContext) response.Resp
|
|||||||
// 403: forbiddenError
|
// 403: forbiddenError
|
||||||
// 500: internalServerError
|
// 500: internalServerError
|
||||||
func (s *Service) GetUserFromLDAP(c *contextmodel.ReqContext) response.Response {
|
func (s *Service) GetUserFromLDAP(c *contextmodel.ReqContext) response.Response {
|
||||||
if !ldap.IsEnabled() {
|
if !s.cfg.LDAPEnabled {
|
||||||
return response.Error(http.StatusBadRequest, "LDAP is not enabled", nil)
|
return response.Error(http.StatusBadRequest, "LDAP is not enabled", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/login/logintest"
|
"github.com/grafana/grafana/pkg/services/login/logintest"
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
||||||
|
"github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest"
|
||||||
"github.com/grafana/grafana/pkg/services/user"
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
"github.com/grafana/grafana/pkg/services/user/usertest"
|
"github.com/grafana/grafana/pkg/services/user/usertest"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
@ -58,6 +59,7 @@ func setupAPITest(t *testing.T, opts ...func(a *Service)) (*Service, *webtest.Se
|
|||||||
t.Helper()
|
t.Helper()
|
||||||
router := routing.NewRouteRegister()
|
router := routing.NewRouteRegister()
|
||||||
cfg := setting.NewCfg()
|
cfg := setting.NewCfg()
|
||||||
|
cfg.LDAPEnabled = true
|
||||||
|
|
||||||
a := ProvideService(cfg,
|
a := ProvideService(cfg,
|
||||||
router,
|
router,
|
||||||
@ -68,6 +70,7 @@ func setupAPITest(t *testing.T, opts ...func(a *Service)) (*Service, *webtest.Se
|
|||||||
&logintest.LoginServiceFake{},
|
&logintest.LoginServiceFake{},
|
||||||
&orgtest.FakeOrgService{},
|
&orgtest.FakeOrgService{},
|
||||||
authtest.NewFakeUserAuthTokenService(),
|
authtest.NewFakeUserAuthTokenService(),
|
||||||
|
supportbundlestest.NewFakeBundleService(),
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
@ -80,9 +83,6 @@ func setupAPITest(t *testing.T, opts ...func(a *Service)) (*Service, *webtest.Se
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGetUserFromLDAPAPIEndpoint_UserNotFound(t *testing.T) {
|
func TestGetUserFromLDAPAPIEndpoint_UserNotFound(t *testing.T) {
|
||||||
setting.LDAPEnabled = true
|
|
||||||
defer func() { setting.LDAPEnabled = false }()
|
|
||||||
|
|
||||||
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
||||||
return &ldap.Config{}, nil
|
return &ldap.Config{}, nil
|
||||||
}
|
}
|
||||||
@ -116,9 +116,6 @@ func TestGetUserFromLDAPAPIEndpoint_UserNotFound(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGetUserFromLDAPAPIEndpoint_OrgNotfound(t *testing.T) {
|
func TestGetUserFromLDAPAPIEndpoint_OrgNotfound(t *testing.T) {
|
||||||
setting.LDAPEnabled = true
|
|
||||||
defer func() { setting.LDAPEnabled = false }()
|
|
||||||
|
|
||||||
isAdmin := true
|
isAdmin := true
|
||||||
userSearchResult := &login.ExternalUserInfo{
|
userSearchResult := &login.ExternalUserInfo{
|
||||||
Name: "John Doe",
|
Name: "John Doe",
|
||||||
@ -193,9 +190,6 @@ func TestGetUserFromLDAPAPIEndpoint_OrgNotfound(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGetUserFromLDAPAPIEndpoint(t *testing.T) {
|
func TestGetUserFromLDAPAPIEndpoint(t *testing.T) {
|
||||||
setting.LDAPEnabled = true
|
|
||||||
defer func() { setting.LDAPEnabled = false }()
|
|
||||||
|
|
||||||
isAdmin := true
|
isAdmin := true
|
||||||
userSearchResult := &login.ExternalUserInfo{
|
userSearchResult := &login.ExternalUserInfo{
|
||||||
Name: "John Doe",
|
Name: "John Doe",
|
||||||
@ -290,9 +284,6 @@ func TestGetUserFromLDAPAPIEndpoint(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGetUserFromLDAPAPIEndpoint_WithTeamHandler(t *testing.T) {
|
func TestGetUserFromLDAPAPIEndpoint_WithTeamHandler(t *testing.T) {
|
||||||
setting.LDAPEnabled = true
|
|
||||||
defer func() { setting.LDAPEnabled = false }()
|
|
||||||
|
|
||||||
isAdmin := true
|
isAdmin := true
|
||||||
userSearchResult := &login.ExternalUserInfo{
|
userSearchResult := &login.ExternalUserInfo{
|
||||||
Name: "John Doe",
|
Name: "John Doe",
|
||||||
@ -381,9 +372,6 @@ func TestGetUserFromLDAPAPIEndpoint_WithTeamHandler(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGetLDAPStatusAPIEndpoint(t *testing.T) {
|
func TestGetLDAPStatusAPIEndpoint(t *testing.T) {
|
||||||
setting.LDAPEnabled = true
|
|
||||||
defer func() { setting.LDAPEnabled = false }()
|
|
||||||
|
|
||||||
pingResult = []*multildap.ServerStatus{
|
pingResult = []*multildap.ServerStatus{
|
||||||
{Host: "10.0.0.3", Port: 361, Available: true, Error: nil},
|
{Host: "10.0.0.3", Port: 361, Available: true, Error: nil},
|
||||||
{Host: "10.0.0.3", Port: 362, Available: true, Error: nil},
|
{Host: "10.0.0.3", Port: 362, Available: true, Error: nil},
|
||||||
@ -427,9 +415,6 @@ func TestGetLDAPStatusAPIEndpoint(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPostSyncUserWithLDAPAPIEndpoint_Success(t *testing.T) {
|
func TestPostSyncUserWithLDAPAPIEndpoint_Success(t *testing.T) {
|
||||||
setting.LDAPEnabled = true
|
|
||||||
defer func() { setting.LDAPEnabled = false }()
|
|
||||||
|
|
||||||
userServiceMock := usertest.NewUserServiceFake()
|
userServiceMock := usertest.NewUserServiceFake()
|
||||||
userServiceMock.ExpectedUser = &user.User{Login: "ldap-daniel", ID: 34}
|
userServiceMock.ExpectedUser = &user.User{Login: "ldap-daniel", ID: 34}
|
||||||
|
|
||||||
@ -471,8 +456,6 @@ func TestPostSyncUserWithLDAPAPIEndpoint_Success(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPostSyncUserWithLDAPAPIEndpoint_WhenUserNotFound(t *testing.T) {
|
func TestPostSyncUserWithLDAPAPIEndpoint_WhenUserNotFound(t *testing.T) {
|
||||||
setting.LDAPEnabled = true
|
|
||||||
defer func() { setting.LDAPEnabled = false }()
|
|
||||||
userServiceMock := usertest.NewUserServiceFake()
|
userServiceMock := usertest.NewUserServiceFake()
|
||||||
userServiceMock.ExpectedError = user.ErrUserNotFound
|
userServiceMock.ExpectedError = user.ErrUserNotFound
|
||||||
|
|
||||||
@ -512,9 +495,6 @@ func TestPostSyncUserWithLDAPAPIEndpoint_WhenUserNotFound(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPostSyncUserWithLDAPAPIEndpoint_WhenGrafanaAdmin(t *testing.T) {
|
func TestPostSyncUserWithLDAPAPIEndpoint_WhenGrafanaAdmin(t *testing.T) {
|
||||||
setting.LDAPEnabled = true
|
|
||||||
defer func() { setting.LDAPEnabled = false }()
|
|
||||||
|
|
||||||
userServiceMock := usertest.NewUserServiceFake()
|
userServiceMock := usertest.NewUserServiceFake()
|
||||||
userServiceMock.ExpectedUser = &user.User{Login: "ldap-daniel", ID: 34}
|
userServiceMock.ExpectedUser = &user.User{Login: "ldap-daniel", ID: 34}
|
||||||
|
|
||||||
@ -553,9 +533,6 @@ func TestPostSyncUserWithLDAPAPIEndpoint_WhenGrafanaAdmin(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPostSyncUserWithLDAPAPIEndpoint_WhenUserNotInLDAP(t *testing.T) {
|
func TestPostSyncUserWithLDAPAPIEndpoint_WhenUserNotInLDAP(t *testing.T) {
|
||||||
setting.LDAPEnabled = true
|
|
||||||
defer func() { setting.LDAPEnabled = false }()
|
|
||||||
|
|
||||||
userServiceMock := usertest.NewUserServiceFake()
|
userServiceMock := usertest.NewUserServiceFake()
|
||||||
userServiceMock.ExpectedUser = &user.User{Login: "ldap-daniel", ID: 34}
|
userServiceMock.ExpectedUser = &user.User{Login: "ldap-daniel", ID: 34}
|
||||||
|
|
||||||
@ -596,8 +573,6 @@ func TestPostSyncUserWithLDAPAPIEndpoint_WhenUserNotInLDAP(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLDAP_AccessControl(t *testing.T) {
|
func TestLDAP_AccessControl(t *testing.T) {
|
||||||
setting.LDAPEnabled = true
|
|
||||||
|
|
||||||
f, errC := os.CreateTemp("", "ldap.toml")
|
f, errC := os.CreateTemp("", "ldap.toml")
|
||||||
require.NoError(t, errC)
|
require.NoError(t, errC)
|
||||||
|
|
||||||
@ -609,16 +584,11 @@ search_filter = "(cn=%s)"
|
|||||||
search_base_dns = ["dc=grafana,dc=org"]`)
|
search_base_dns = ["dc=grafana,dc=org"]`)
|
||||||
require.NoError(t, errF)
|
require.NoError(t, errF)
|
||||||
|
|
||||||
setting.LDAPConfigFile = f.Name()
|
ldapConfigFile := f.Name()
|
||||||
|
|
||||||
errF = f.Close()
|
errF = f.Close()
|
||||||
require.NoError(t, errF)
|
require.NoError(t, errF)
|
||||||
|
|
||||||
defer func() {
|
|
||||||
setting.LDAPEnabled = false
|
|
||||||
setting.LDAPConfigFile = ""
|
|
||||||
}()
|
|
||||||
|
|
||||||
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
||||||
return &ldap.Config{}, nil
|
return &ldap.Config{}, nil
|
||||||
}
|
}
|
||||||
@ -717,6 +687,7 @@ search_base_dns = ["dc=grafana,dc=org"]`)
|
|||||||
t.Run(tt.desc, func(t *testing.T) {
|
t.Run(tt.desc, func(t *testing.T) {
|
||||||
_, server := setupAPITest(t, func(a *Service) {
|
_, server := setupAPITest(t, func(a *Service) {
|
||||||
a.userService = &usertest.FakeUserService{ExpectedUser: &user.User{Login: "ldap-daniel", ID: 1}}
|
a.userService = &usertest.FakeUserService{ExpectedUser: &user.User{Login: "ldap-daniel", ID: 1}}
|
||||||
|
a.cfg.LDAPConfigFilePath = ldapConfigFile
|
||||||
})
|
})
|
||||||
// Add minimal setup to pass handler
|
// Add minimal setup to pass handler
|
||||||
res, err := server.Send(
|
res, err := server.Send(
|
||||||
|
90
pkg/services/ldap/api/support_bundle.go
Normal file
90
pkg/services/ldap/api/support_bundle.go
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/BurntSushi/toml"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/services/supportbundles"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Service) supportBundleCollector(context.Context) (*supportbundles.SupportItem, error) {
|
||||||
|
bWriter := bytes.NewBuffer(nil)
|
||||||
|
bWriter.WriteString("# LDAP information\n\n")
|
||||||
|
|
||||||
|
ldapConfig, err := getLDAPConfig(s.cfg)
|
||||||
|
|
||||||
|
if ldapConfig != nil {
|
||||||
|
bWriter.WriteString("## LDAP Status\n")
|
||||||
|
|
||||||
|
ldapClient := newLDAP(ldapConfig.Servers)
|
||||||
|
|
||||||
|
ldapStatus, err := ldapClient.Ping()
|
||||||
|
if err != nil {
|
||||||
|
bWriter.WriteString(
|
||||||
|
fmt.Sprintf("Unable to ping server\n Err: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, server := range ldapStatus {
|
||||||
|
bWriter.WriteString(fmt.Sprintf("\nHost: %s \n", server.Host))
|
||||||
|
bWriter.WriteString(fmt.Sprintf("Port: %d \n", server.Port))
|
||||||
|
bWriter.WriteString(fmt.Sprintf("Available: %v \n", server.Available))
|
||||||
|
if server.Error != nil {
|
||||||
|
bWriter.WriteString(fmt.Sprintf("Error: %s\n", server.Error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bWriter.WriteString("\n## LDAP Common Configuration issues\n\n")
|
||||||
|
bWriter.WriteString("- Checked for **Mismatched search attributes**\n\n")
|
||||||
|
issue := false
|
||||||
|
for _, server := range ldapConfig.Servers {
|
||||||
|
server.BindPassword = "********" // censor password on config dump
|
||||||
|
server.ClientKey = "********" // censor client key on config dump
|
||||||
|
|
||||||
|
if !strings.Contains(server.SearchFilter, server.Attr.Username) {
|
||||||
|
bWriter.WriteString(fmt.Sprintf(
|
||||||
|
"Search filter does not match username attribute \n"+
|
||||||
|
"Server: %s \n"+
|
||||||
|
"Search filter: %s \n"+
|
||||||
|
"Username attribute: %s \n",
|
||||||
|
server.Host, server.SearchFilter, server.Attr.Username))
|
||||||
|
issue = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !issue {
|
||||||
|
bWriter.WriteString("No issues found\n\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bWriter.WriteString("## LDAP configuration\n\n")
|
||||||
|
|
||||||
|
bWriter.WriteString("```toml\n")
|
||||||
|
errM := toml.NewEncoder(bWriter).Encode(ldapConfig)
|
||||||
|
if errM != nil {
|
||||||
|
bWriter.WriteString(
|
||||||
|
fmt.Sprintf("Unable to encode LDAP configuration \n Err: %s", err))
|
||||||
|
}
|
||||||
|
bWriter.WriteString("```\n\n")
|
||||||
|
|
||||||
|
bWriter.WriteString("## Grafana LDAP configuration\n\n")
|
||||||
|
|
||||||
|
bWriter.WriteString("```ini\n")
|
||||||
|
|
||||||
|
bWriter.WriteString(fmt.Sprintf("enabled = %v\n", s.cfg.LDAPEnabled))
|
||||||
|
bWriter.WriteString(fmt.Sprintf("config_file = %s\n", s.cfg.LDAPConfigFilePath))
|
||||||
|
bWriter.WriteString(fmt.Sprintf("allow_sign_up = %v\n", s.cfg.LDAPAllowSignup))
|
||||||
|
bWriter.WriteString(fmt.Sprintf("sync_cron = %s\n", setting.LDAPSyncCron))
|
||||||
|
bWriter.WriteString(fmt.Sprintf("active_sync_enabled = %v\n", setting.LDAPActiveSyncEnabled))
|
||||||
|
bWriter.WriteString(fmt.Sprintf("skip_org_role_sync = %v\n", setting.LDAPSkipOrgRoleSync))
|
||||||
|
|
||||||
|
bWriter.WriteString("```\n\n")
|
||||||
|
|
||||||
|
return &supportbundles.SupportItem{
|
||||||
|
Filename: "ldap.md",
|
||||||
|
FileBytes: bWriter.Bytes(),
|
||||||
|
}, nil
|
||||||
|
}
|
@ -81,7 +81,7 @@ func SkipOrgRoleSync() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReloadConfig reads the config from the disk and caches it.
|
// ReloadConfig reads the config from the disk and caches it.
|
||||||
func ReloadConfig() error {
|
func ReloadConfig(ldapConfigFilePath string) error {
|
||||||
if !IsEnabled() {
|
if !IsEnabled() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ func ReloadConfig() error {
|
|||||||
defer loadingMutex.Unlock()
|
defer loadingMutex.Unlock()
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
config, err = readConfig(setting.LDAPConfigFile)
|
config, err = readConfig(ldapConfigFilePath)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ func GetConfig(cfg *setting.Cfg) (*Config, error) {
|
|||||||
loadingMutex.Lock()
|
loadingMutex.Lock()
|
||||||
defer loadingMutex.Unlock()
|
defer loadingMutex.Unlock()
|
||||||
|
|
||||||
return readConfig(setting.LDAPConfigFile)
|
return readConfig(cfg.LDAPConfigFilePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func readConfig(configFile string) (*Config, error) {
|
func readConfig(configFile string) (*Config, error) {
|
||||||
|
@ -442,6 +442,7 @@ type Cfg struct {
|
|||||||
// LDAP
|
// LDAP
|
||||||
LDAPEnabled bool
|
LDAPEnabled bool
|
||||||
LDAPSkipOrgRoleSync bool
|
LDAPSkipOrgRoleSync bool
|
||||||
|
LDAPConfigFilePath string
|
||||||
LDAPAllowSignup bool
|
LDAPAllowSignup bool
|
||||||
|
|
||||||
DefaultTheme string
|
DefaultTheme string
|
||||||
@ -1206,6 +1207,7 @@ func (cfg *Cfg) readSAMLConfig() {
|
|||||||
func (cfg *Cfg) readLDAPConfig() {
|
func (cfg *Cfg) readLDAPConfig() {
|
||||||
ldapSec := cfg.Raw.Section("auth.ldap")
|
ldapSec := cfg.Raw.Section("auth.ldap")
|
||||||
LDAPConfigFile = ldapSec.Key("config_file").String()
|
LDAPConfigFile = ldapSec.Key("config_file").String()
|
||||||
|
cfg.LDAPConfigFilePath = LDAPConfigFile
|
||||||
LDAPSyncCron = ldapSec.Key("sync_cron").String()
|
LDAPSyncCron = ldapSec.Key("sync_cron").String()
|
||||||
LDAPEnabled = ldapSec.Key("enabled").MustBool(false)
|
LDAPEnabled = ldapSec.Key("enabled").MustBool(false)
|
||||||
cfg.LDAPEnabled = LDAPEnabled
|
cfg.LDAPEnabled = LDAPEnabled
|
||||||
|
Loading…
Reference in New Issue
Block a user