mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: Disable default golangci-lint filter (#29751)
* Disable default golangci-lint filter Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Chore: Fix linter warnings Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
This commit is contained in:
parent
5d4910dd52
commit
c2cad26ca9
@ -1,3 +1,4 @@
|
||||
// Package api contains API logic.
|
||||
package api
|
||||
|
||||
import (
|
||||
@ -7,10 +8,13 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/avatar"
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/middleware"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
var plog = log.New("api")
|
||||
|
||||
// registerRoutes registers all API HTTP routes.
|
||||
func (hs *HTTPServer) registerRoutes() {
|
||||
reqSignedIn := middleware.ReqSignedIn
|
||||
|
@ -136,7 +136,9 @@ func newNotFound() *Avatar {
|
||||
// variable.
|
||||
// nolint:gosec
|
||||
path := filepath.Join(setting.StaticRootPath, "img", "user_profile.png")
|
||||
|
||||
// It's safe to ignore gosec warning G304 since the variable part of the file path comes from a configuration
|
||||
// variable.
|
||||
// nolint:gosec
|
||||
if data, err := ioutil.ReadFile(path); err != nil {
|
||||
log.Errorf(3, "Failed to read user_profile.png, %v", path)
|
||||
} else {
|
||||
@ -212,7 +214,10 @@ func (a *thunderTask) fetch() error {
|
||||
a.Avatar.timestamp = time.Now()
|
||||
|
||||
log.Debugf("avatar.fetch(fetch new avatar): %s", a.Url)
|
||||
req, _ := http.NewRequest("GET", a.Url, nil)
|
||||
req, err := http.NewRequest("GET", a.Url, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/jpeg,image/png,*/*;q=0.8")
|
||||
req.Header.Set("Accept-Encoding", "deflate,sdch")
|
||||
req.Header.Set("Accept-Language", "zh-CN,zh;q=0.8")
|
||||
@ -221,10 +226,13 @@ func (a *thunderTask) fetch() error {
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
a.Avatar.notFound = true
|
||||
return fmt.Errorf("gravatar unreachable, %v", err)
|
||||
return fmt.Errorf("gravatar unreachable: %w", err)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
defer func() {
|
||||
if err := resp.Body.Close(); err != nil {
|
||||
log.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
a.Avatar.notFound = true
|
||||
|
@ -54,7 +54,11 @@ func createExternalDashboardSnapshot(cmd models.CreateDashboardSnapshotCommand)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
defer func() {
|
||||
if err := response.Body.Close(); err != nil {
|
||||
plog.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if response.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("create external snapshot response status code %d", response.StatusCode)
|
||||
@ -178,7 +182,9 @@ func deleteExternalDashboardSnapshot(externalUrl string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
if err := response.Body.Close(); err != nil {
|
||||
plog.Warn("Failed closing response body", "err", err)
|
||||
}
|
||||
|
||||
if response.StatusCode == 200 {
|
||||
return nil
|
||||
|
@ -19,7 +19,7 @@ var (
|
||||
getLDAPConfig = multildap.GetConfig
|
||||
newLDAP = multildap.New
|
||||
|
||||
logger = log.New("LDAP.debug")
|
||||
ldapLogger = log.New("LDAP.debug")
|
||||
|
||||
errOrganizationNotFound = func(orgId int64) error {
|
||||
return fmt.Errorf("unable to find organization with ID '%d'", orgId)
|
||||
@ -117,7 +117,6 @@ func (hs *HTTPServer) GetLDAPStatus(c *models.ReqContext) Response {
|
||||
}
|
||||
|
||||
ldapConfig, err := getLDAPConfig(hs.Cfg)
|
||||
|
||||
if err != nil {
|
||||
return Error(http.StatusBadRequest, "Failed to obtain the LDAP configuration. Please verify the configuration and try again", err)
|
||||
}
|
||||
@ -129,7 +128,6 @@ func (hs *HTTPServer) GetLDAPStatus(c *models.ReqContext) Response {
|
||||
}
|
||||
|
||||
statuses, err := ldap.Ping()
|
||||
|
||||
if err != nil {
|
||||
return Error(http.StatusBadRequest, "Failed to connect to the LDAP server(s)", err)
|
||||
}
|
||||
@ -187,12 +185,11 @@ func (hs *HTTPServer) PostSyncUserWithLDAP(c *models.ReqContext) Response {
|
||||
|
||||
ldapServer := newLDAP(ldapConfig.Servers)
|
||||
user, _, err := ldapServer.User(query.Result.Login)
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, multildap.ErrDidNotFindUser) { // User was not in the LDAP server - we need to take action:
|
||||
if setting.AdminUser == query.Result.Login { // User is *the* Grafana Admin. We cannot disable it.
|
||||
errMsg := fmt.Sprintf(`Refusing to sync grafana super admin "%s" - it would be disabled`, query.Result.Login)
|
||||
logger.Error(errMsg)
|
||||
ldapLogger.Error(errMsg)
|
||||
return Error(http.StatusBadRequest, errMsg, err)
|
||||
}
|
||||
|
||||
@ -210,7 +207,7 @@ func (hs *HTTPServer) PostSyncUserWithLDAP(c *models.ReqContext) Response {
|
||||
return Error(http.StatusBadRequest, "User not found in LDAP. Disabled the user without updating information", nil) // should this be a success?
|
||||
}
|
||||
|
||||
logger.Debug("Failed to sync the user with LDAP", "err", err)
|
||||
ldapLogger.Debug("Failed to sync the user with LDAP", "err", err)
|
||||
return Error(http.StatusBadRequest, "Something went wrong while finding the user in LDAP", err)
|
||||
}
|
||||
|
||||
@ -221,7 +218,6 @@ func (hs *HTTPServer) PostSyncUserWithLDAP(c *models.ReqContext) Response {
|
||||
}
|
||||
|
||||
err = bus.Dispatch(upsertCmd)
|
||||
|
||||
if err != nil {
|
||||
return Error(http.StatusInternalServerError, "Failed to update the user", err)
|
||||
}
|
||||
@ -236,7 +232,6 @@ func (hs *HTTPServer) GetUserFromLDAP(c *models.ReqContext) Response {
|
||||
}
|
||||
|
||||
ldapConfig, err := getLDAPConfig(hs.Cfg)
|
||||
|
||||
if err != nil {
|
||||
return Error(http.StatusBadRequest, "Failed to obtain the LDAP configuration", err)
|
||||
}
|
||||
@ -255,7 +250,7 @@ func (hs *HTTPServer) GetUserFromLDAP(c *models.ReqContext) Response {
|
||||
return Error(http.StatusNotFound, "No user was found in the LDAP server(s) with that username", err)
|
||||
}
|
||||
|
||||
logger.Debug("user found", "user", user)
|
||||
ldapLogger.Debug("user found", "user", user)
|
||||
|
||||
name, surname := splitName(user.Name)
|
||||
|
||||
@ -304,16 +299,14 @@ func (hs *HTTPServer) GetUserFromLDAP(c *models.ReqContext) Response {
|
||||
|
||||
u.OrgRoles = orgRoles
|
||||
|
||||
logger.Debug("mapping org roles", "orgsRoles", u.OrgRoles)
|
||||
ldapLogger.Debug("mapping org roles", "orgsRoles", u.OrgRoles)
|
||||
err = u.FetchOrgs()
|
||||
|
||||
if err != nil {
|
||||
return Error(http.StatusBadRequest, "An organization was not found - Please verify your LDAP configuration", err)
|
||||
}
|
||||
|
||||
cmd := &models.GetTeamsForLDAPGroupCommand{Groups: user.Groups}
|
||||
err = bus.Dispatch(cmd)
|
||||
|
||||
if err != nil && !errors.Is(err, bus.ErrHandlerNotFound) {
|
||||
return Error(http.StatusBadRequest, "Unable to find the teams for this user", err)
|
||||
}
|
||||
|
@ -224,11 +224,11 @@ func buildExternalUserInfo(token *oauth2.Token, userInfo *social.BasicUserInfo,
|
||||
var orgID int64
|
||||
if setting.AutoAssignOrg && setting.AutoAssignOrgId > 0 {
|
||||
orgID = int64(setting.AutoAssignOrgId)
|
||||
logger.Debug("The user has a role assignment and organization membership is auto-assigned",
|
||||
plog.Debug("The user has a role assignment and organization membership is auto-assigned",
|
||||
"role", userInfo.Role, "orgId", orgID)
|
||||
} else {
|
||||
orgID = int64(1)
|
||||
logger.Debug("The user has a role assignment and organization membership is not auto-assigned",
|
||||
plog.Debug("The user has a role assignment and organization membership is not auto-assigned",
|
||||
"role", userInfo.Role, "orgId", orgID)
|
||||
}
|
||||
extUser.OrgRoles[orgID] = rt
|
||||
|
@ -113,7 +113,10 @@ func (provider *accessTokenProvider) getAccessToken(data templateData) (string,
|
||||
params.Add(key, interpolatedParam)
|
||||
}
|
||||
|
||||
getTokenReq, _ := http.NewRequest("POST", urlInterpolated, bytes.NewBufferString(params.Encode()))
|
||||
getTokenReq, err := http.NewRequest("POST", urlInterpolated, bytes.NewBufferString(params.Encode()))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
getTokenReq.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
getTokenReq.Header.Set("Content-Length", strconv.Itoa(len(params.Encode())))
|
||||
|
||||
@ -122,7 +125,11 @@ func (provider *accessTokenProvider) getAccessToken(data templateData) (string,
|
||||
return "", err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
defer func() {
|
||||
if err := resp.Body.Close(); err != nil {
|
||||
logger.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
var token jwtToken
|
||||
if err := json.NewDecoder(resp.Body).Decode(&token); err != nil {
|
||||
|
@ -134,7 +134,11 @@ func staticHandler(ctx *macaron.Context, log *log.Logger, opt StaticOptions) boo
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
defer f.Close()
|
||||
defer func() {
|
||||
if err := f.Close(); err != nil {
|
||||
log.Printf("Failed to close file: %s\n", err)
|
||||
}
|
||||
}()
|
||||
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
@ -154,7 +158,11 @@ func staticHandler(ctx *macaron.Context, log *log.Logger, opt StaticOptions) boo
|
||||
if err != nil {
|
||||
return false // Discard error.
|
||||
}
|
||||
defer f.Close()
|
||||
defer func() {
|
||||
if err := f.Close(); err != nil {
|
||||
log.Printf("Failed to close file: %s", err)
|
||||
}
|
||||
}()
|
||||
|
||||
fi, err = f.Stat()
|
||||
if err != nil || fi.IsDir() {
|
||||
@ -163,7 +171,7 @@ func staticHandler(ctx *macaron.Context, log *log.Logger, opt StaticOptions) boo
|
||||
}
|
||||
|
||||
if !opt.SkipLogging {
|
||||
log.Println("[Static] Serving " + file)
|
||||
log.Printf("[Static] Serving %s\n", file)
|
||||
}
|
||||
|
||||
// Add an Expires header to the static content
|
||||
|
@ -111,11 +111,17 @@ func InstallPlugin(pluginName, version string, c utils.CommandLine, client utils
|
||||
if err != nil {
|
||||
return errutil.Wrap("failed to create temporary file", err)
|
||||
}
|
||||
defer os.Remove(tmpFile.Name())
|
||||
defer func() {
|
||||
if err := os.Remove(tmpFile.Name()); err != nil {
|
||||
logger.Warn("Failed to remove temporary file", "file", tmpFile.Name(), "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
err = client.DownloadFile(pluginName, tmpFile, downloadURL, checksum)
|
||||
if err != nil {
|
||||
tmpFile.Close()
|
||||
if err := tmpFile.Close(); err != nil {
|
||||
logger.Warn("Failed to close file", "err", err)
|
||||
}
|
||||
return errutil.Wrap("failed to download plugin archive", err)
|
||||
}
|
||||
err = tmpFile.Close()
|
||||
@ -228,6 +234,8 @@ func extractFiles(archiveFile string, pluginName string, filePath string, allowS
|
||||
newFile := filepath.Join(filePath, newFileName)
|
||||
|
||||
if zf.FileInfo().IsDir() {
|
||||
// We can ignore gosec G304 here since it makes sense to give all users read access
|
||||
// nolint:gosec
|
||||
if err := os.MkdirAll(newFile, 0755); err != nil {
|
||||
if os.IsPermission(err) {
|
||||
return fmt.Errorf(permissionsDeniedMessage, newFile)
|
||||
@ -240,6 +248,8 @@ func extractFiles(archiveFile string, pluginName string, filePath string, allowS
|
||||
}
|
||||
|
||||
// Create needed directories to extract file
|
||||
// We can ignore gosec G304 here since it makes sense to give all users read access
|
||||
// nolint:gosec
|
||||
if err := os.MkdirAll(filepath.Dir(newFile), 0755); err != nil {
|
||||
return errutil.Wrap("failed to create directory to extract plugin files", err)
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ func setupFakePluginsDir(t *testing.T) (string, func()) {
|
||||
err := os.RemoveAll(dirname)
|
||||
require.Nil(t, err)
|
||||
|
||||
err = os.MkdirAll(dirname, 0774)
|
||||
err = os.MkdirAll(dirname, 0750)
|
||||
require.Nil(t, err)
|
||||
|
||||
return dirname, func() {
|
||||
|
@ -94,14 +94,20 @@ func (client *GrafanaComClient) DownloadFile(pluginName string, tmpFile *os.File
|
||||
if err != nil {
|
||||
return errutil.Wrap("Failed to send request", err)
|
||||
}
|
||||
defer bodyReader.Close()
|
||||
defer func() {
|
||||
if err := bodyReader.Close(); err != nil {
|
||||
logger.Warn("Failed to close body", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
w := bufio.NewWriter(tmpFile)
|
||||
h := md5.New()
|
||||
if _, err = io.Copy(w, io.TeeReader(bodyReader, h)); err != nil {
|
||||
return errutil.Wrap("Failed to compute MD5 checksum", err)
|
||||
}
|
||||
w.Flush()
|
||||
if err := w.Flush(); err != nil {
|
||||
return fmt.Errorf("failed to write to %q: %w", tmpFile.Name(), err)
|
||||
}
|
||||
if len(checksum) > 0 && checksum != fmt.Sprintf("%x", h.Sum(nil)) {
|
||||
return fmt.Errorf("expected MD5 checksum does not match the downloaded archive - please contact security@grafana.com")
|
||||
}
|
||||
@ -131,7 +137,11 @@ func sendRequestGetBytes(client http.Client, repoUrl string, subPaths ...string)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
defer bodyReader.Close()
|
||||
defer func() {
|
||||
if err := bodyReader.Close(); err != nil {
|
||||
logger.Warn("Failed to close stream", "err", err)
|
||||
}
|
||||
}()
|
||||
return ioutil.ReadAll(bodyReader)
|
||||
}
|
||||
|
||||
@ -182,7 +192,11 @@ func handleResponse(res *http.Response) (io.ReadCloser, error) {
|
||||
|
||||
if res.StatusCode/100 == 4 {
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
defer res.Body.Close()
|
||||
defer func() {
|
||||
if err := res.Body.Close(); err != nil {
|
||||
logger.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
if err != nil || len(body) == 0 {
|
||||
return nil, &BadRequestError{Status: res.Status}
|
||||
}
|
||||
|
@ -14,8 +14,9 @@ import (
|
||||
|
||||
func TestHandleResponse(t *testing.T) {
|
||||
t.Run("Returns body if status == 200", func(t *testing.T) {
|
||||
resp := makeResponse(200, "test")
|
||||
defer resp.Body.Close()
|
||||
// The body gets closed within makeResponse
|
||||
// nolint:bodyclose
|
||||
resp := makeResponse(t, 200, "test")
|
||||
bodyReader, err := handleResponse(resp)
|
||||
require.NoError(t, err)
|
||||
body, err := ioutil.ReadAll(bodyReader)
|
||||
@ -24,54 +25,68 @@ func TestHandleResponse(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Returns ErrorNotFound if status == 404", func(t *testing.T) {
|
||||
resp := makeResponse(404, "")
|
||||
defer resp.Body.Close()
|
||||
// The body gets closed within makeResponse
|
||||
// nolint:bodyclose
|
||||
resp := makeResponse(t, 404, "")
|
||||
_, err := handleResponse(resp)
|
||||
assert.Equal(t, ErrNotFoundError, err)
|
||||
})
|
||||
|
||||
t.Run("Returns message from body if status == 400", func(t *testing.T) {
|
||||
resp := makeResponse(400, "{ \"message\": \"error_message\" }")
|
||||
defer resp.Body.Close()
|
||||
// The body gets closed within makeResponse
|
||||
// nolint:bodyclose
|
||||
resp := makeResponse(t, 400, "{ \"message\": \"error_message\" }")
|
||||
_, err := handleResponse(resp)
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, "error_message", asBadRequestError(t, err).Message)
|
||||
})
|
||||
|
||||
t.Run("Returns body if status == 400 and no message key", func(t *testing.T) {
|
||||
resp := makeResponse(400, "{ \"test\": \"test_message\"}")
|
||||
defer resp.Body.Close()
|
||||
// The body gets closed within makeResponse
|
||||
// nolint:bodyclose
|
||||
resp := makeResponse(t, 400, "{ \"test\": \"test_message\"}")
|
||||
_, err := handleResponse(resp)
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, "{ \"test\": \"test_message\"}", asBadRequestError(t, err).Message)
|
||||
})
|
||||
|
||||
t.Run("Returns Bad request error if status == 400 and no body", func(t *testing.T) {
|
||||
resp := makeResponse(400, "")
|
||||
defer resp.Body.Close()
|
||||
// The body gets closed within makeResponse
|
||||
// nolint:bodyclose
|
||||
resp := makeResponse(t, 400, "")
|
||||
_, err := handleResponse(resp)
|
||||
require.Error(t, err)
|
||||
_ = asBadRequestError(t, err)
|
||||
})
|
||||
|
||||
t.Run("Returns error with invalid status if status == 500", func(t *testing.T) {
|
||||
resp := makeResponse(500, "")
|
||||
defer resp.Body.Close()
|
||||
// The body gets closed within makeResponse
|
||||
// nolint:bodyclose
|
||||
resp := makeResponse(t, 500, "")
|
||||
_, err := handleResponse(resp)
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "invalid status")
|
||||
})
|
||||
}
|
||||
|
||||
func makeResponse(status int, body string) *http.Response {
|
||||
func makeResponse(t *testing.T, status int, body string) *http.Response {
|
||||
t.Helper()
|
||||
|
||||
return &http.Response{
|
||||
StatusCode: status,
|
||||
Body: makeBody(body),
|
||||
Body: makeBody(t, body),
|
||||
}
|
||||
}
|
||||
|
||||
func makeBody(body string) io.ReadCloser {
|
||||
return ioutil.NopCloser(bytes.NewReader([]byte(body)))
|
||||
func makeBody(t *testing.T, body string) io.ReadCloser {
|
||||
t.Helper()
|
||||
|
||||
reader := ioutil.NopCloser(bytes.NewReader([]byte(body)))
|
||||
t.Cleanup(func() {
|
||||
err := reader.Close()
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
return reader
|
||||
}
|
||||
|
||||
func asBadRequestError(t *testing.T, err error) *BadRequestError {
|
||||
|
@ -108,7 +108,11 @@ func main() {
|
||||
}
|
||||
|
||||
func executeServer(configFile, homePath, pidFile, packaging string, traceDiagnostics *tracingDiagnostics) error {
|
||||
defer log.Close()
|
||||
defer func() {
|
||||
if err := log.Close(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to close log: %s\n", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if traceDiagnostics.enabled {
|
||||
fmt.Println("diagnostics: tracing enabled", "file", traceDiagnostics.file)
|
||||
@ -183,7 +187,9 @@ func listenToSystemSignals(s *server.Server) {
|
||||
for {
|
||||
select {
|
||||
case <-sighupChan:
|
||||
log.Reload()
|
||||
if err := log.Reload(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to reload loggers: %s\n", err)
|
||||
}
|
||||
case sig := <-signalChan:
|
||||
s.Shutdown(fmt.Sprintf("System signal: %s", sig))
|
||||
}
|
||||
|
@ -70,9 +70,17 @@ func (az *AzureBlobUploader) Upload(ctx context.Context, imageDiskPath string) (
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer func() {
|
||||
if err := resp.Body.Close(); err != nil {
|
||||
logger.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if resp.StatusCode > 400 && resp.StatusCode < 600 {
|
||||
body, _ := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))
|
||||
body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
aerr := &Error{
|
||||
Code: resp.StatusCode,
|
||||
Status: resp.Status,
|
||||
@ -80,7 +88,6 @@ func (az *AzureBlobUploader) Upload(ctx context.Context, imageDiskPath string) (
|
||||
Header: resp.Header,
|
||||
}
|
||||
aerr.parseXML()
|
||||
resp.Body.Close()
|
||||
return "", aerr
|
||||
}
|
||||
|
||||
|
@ -78,10 +78,17 @@ func (u *WebdavUploader) Upload(ctx context.Context, imgToUpload string) (string
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
defer func() {
|
||||
if err := res.Body.Close(); err != nil {
|
||||
logger.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if res.StatusCode != http.StatusCreated {
|
||||
body, _ := ioutil.ReadAll(res.Body)
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to read response body: %w", err)
|
||||
}
|
||||
return "", fmt.Errorf("failed to upload image, statuscode: %d, body: %s", res.StatusCode, body)
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@ -18,7 +19,10 @@ func TestExists_NonExistent(t *testing.T) {
|
||||
func TestExists_Existent(t *testing.T) {
|
||||
f, err := ioutil.TempFile("", "")
|
||||
require.NoError(t, err)
|
||||
defer os.Remove(f.Name())
|
||||
t.Cleanup(func() {
|
||||
err := os.Remove(f.Name())
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
exists, err := Exists(f.Name())
|
||||
require.NoError(t, err)
|
||||
|
@ -55,11 +55,15 @@ func (l *MuxWriter) Write(b []byte) (int, error) {
|
||||
}
|
||||
|
||||
// set os.File in writer.
|
||||
func (l *MuxWriter) SetFd(fd *os.File) {
|
||||
func (l *MuxWriter) setFD(fd *os.File) error {
|
||||
if l.fd != nil {
|
||||
l.fd.Close()
|
||||
if err := l.fd.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
l.fd = fd
|
||||
return nil
|
||||
}
|
||||
|
||||
// create a FileLogWriter returning as LoggerInterface.
|
||||
@ -98,13 +102,17 @@ func (w *FileLogWriter) StartLogger() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w.mw.SetFd(fd)
|
||||
if err := w.mw.setFD(fd); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return w.initFd()
|
||||
}
|
||||
|
||||
func (w *FileLogWriter) docheck(size int) {
|
||||
w.startLock.Lock()
|
||||
defer w.startLock.Unlock()
|
||||
|
||||
if w.Rotate && ((w.Maxlines > 0 && w.maxlinesCurlines >= w.Maxlines) ||
|
||||
(w.Maxsize > 0 && w.maxsizeCursize >= w.Maxsize) ||
|
||||
(w.Daily && time.Now().Day() != w.dailyOpendate)) {
|
||||
@ -119,6 +127,9 @@ func (w *FileLogWriter) docheck(size int) {
|
||||
|
||||
func (w *FileLogWriter) createLogFile() (*os.File, error) {
|
||||
// Open the log file
|
||||
// We can ignore G304 here since we can't unconditionally lock these log files down to be readable only
|
||||
// by the owner
|
||||
// nolint:gosec
|
||||
return os.OpenFile(w.Filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
|
||||
}
|
||||
|
||||
@ -187,7 +198,9 @@ func (w *FileLogWriter) DoRotate() error {
|
||||
defer w.mw.Unlock()
|
||||
|
||||
fd := w.mw.fd
|
||||
fd.Close()
|
||||
if err := fd.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// close fd before rename
|
||||
// Rename the file to its newfound home
|
||||
@ -228,8 +241,8 @@ func (w *FileLogWriter) deleteOldLog() {
|
||||
}
|
||||
|
||||
// destroy file logger, close file writer.
|
||||
func (w *FileLogWriter) Close() {
|
||||
w.mw.fd.Close()
|
||||
func (w *FileLogWriter) Close() error {
|
||||
return w.mw.fd.Close()
|
||||
}
|
||||
|
||||
// flush file logger.
|
||||
@ -242,18 +255,22 @@ func (w *FileLogWriter) Flush() {
|
||||
}
|
||||
|
||||
// Reload file logger
|
||||
func (w *FileLogWriter) Reload() {
|
||||
func (w *FileLogWriter) Reload() error {
|
||||
// block Logger's io.Writer
|
||||
w.mw.Lock()
|
||||
defer w.mw.Unlock()
|
||||
|
||||
// Close
|
||||
fd := w.mw.fd
|
||||
fd.Close()
|
||||
if err := fd.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Open again
|
||||
err := w.StartLogger()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Reload StartLogger: %s\n", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -23,9 +23,10 @@ func TestLogFile(t *testing.T) {
|
||||
require.NotNil(t, fileLogWrite)
|
||||
|
||||
t.Cleanup(func() {
|
||||
fileLogWrite.Close()
|
||||
err := os.Remove(fileLogWrite.Filename)
|
||||
require.NoError(t, err)
|
||||
err := fileLogWrite.Close()
|
||||
assert.NoError(t, err)
|
||||
err = os.Remove(fileLogWrite.Filename)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
fileLogWrite.Filename = "grafana_test.log"
|
||||
|
@ -1,9 +1,9 @@
|
||||
package log
|
||||
|
||||
type DisposableHandler interface {
|
||||
Close()
|
||||
Close() error
|
||||
}
|
||||
|
||||
type ReloadableHandler interface {
|
||||
Reload()
|
||||
Reload() error
|
||||
}
|
||||
|
@ -69,6 +69,10 @@ func Infof(format string, v ...interface{}) {
|
||||
Root.Info(message)
|
||||
}
|
||||
|
||||
func Warn(msg string, v ...interface{}) {
|
||||
Root.Warn(msg, v...)
|
||||
}
|
||||
|
||||
func Warnf(format string, v ...interface{}) {
|
||||
var message string
|
||||
if len(v) > 0 {
|
||||
@ -90,21 +94,33 @@ func Errorf(skip int, format string, v ...interface{}) {
|
||||
|
||||
func Fatalf(skip int, format string, v ...interface{}) {
|
||||
Root.Crit(fmt.Sprintf(format, v...))
|
||||
Close()
|
||||
if err := Close(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to close log: %s\n", err)
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func Close() {
|
||||
func Close() error {
|
||||
var err error
|
||||
for _, logger := range loggersToClose {
|
||||
logger.Close()
|
||||
if e := logger.Close(); e != nil && err == nil {
|
||||
err = e
|
||||
}
|
||||
}
|
||||
loggersToClose = make([]DisposableHandler, 0)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func Reload() {
|
||||
// Reload reloads all loggers.
|
||||
func Reload() error {
|
||||
for _, logger := range loggersToReload {
|
||||
logger.Reload()
|
||||
if err := logger.Reload(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var logLevels = map[string]log15.Lvl{
|
||||
@ -164,7 +180,9 @@ func getLogFormat(format string) log15.Format {
|
||||
}
|
||||
|
||||
func ReadLoggingConfig(modes []string, logsPath string, cfg *ini.File) error {
|
||||
Close()
|
||||
if err := Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defaultLevelName, _ := getLogLevelFromConfig("log", "info", cfg)
|
||||
defaultFilters := getFilters(util.SplitString(cfg.Section("log").Key("filters").String()))
|
||||
|
@ -77,8 +77,8 @@ func (sw *SysLogHandler) Log(r *log15.Record) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (sw *SysLogHandler) Close() {
|
||||
sw.syslog.Close()
|
||||
func (sw *SysLogHandler) Close() error {
|
||||
return sw.syslog.Close()
|
||||
}
|
||||
|
||||
var facilities = map[string]syslog.Priority{
|
||||
|
@ -18,5 +18,6 @@ func (sw *SysLogHandler) Log(r *log15.Record) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sw *SysLogHandler) Close() {
|
||||
func (sw *SysLogHandler) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/cmd/grafana-cli/logger"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
"github.com/prometheus/common/expfmt"
|
||||
@ -201,7 +202,11 @@ func (b *Bridge) Push() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
defer func() {
|
||||
if err := conn.Close(); err != nil {
|
||||
logger.Warn("Failed to close connection", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
return b.writeMetrics(conn, mfs, b.prefix, model.Now())
|
||||
}
|
||||
|
@ -12,14 +12,16 @@ import (
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
"github.com/prometheus/common/model"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCountersAsDelta(t *testing.T) {
|
||||
b, _ := NewBridge(&Config{
|
||||
b, err := NewBridge(&Config{
|
||||
URL: "localhost:12345",
|
||||
CountersAsDelta: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
ty := dto.MetricType(0)
|
||||
mf := &dto.MetricFamily{
|
||||
Type: &ty,
|
||||
@ -442,29 +444,21 @@ func TestSkipNanValues(t *testing.T) {
|
||||
Gatherer: reg,
|
||||
CountersAsDelta: true,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("error creating bridge: %v", err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
// first collect
|
||||
mfs, err := reg.Gather()
|
||||
if err != nil {
|
||||
t.Fatalf("error: %v", err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
var buf bytes.Buffer
|
||||
err = b.writeMetrics(&buf, mfs, "prefix.", model.Time(1477043083))
|
||||
if err != nil {
|
||||
t.Fatalf("error: %v", err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
want := `prefix.http_request_total_sum.constname.constvalue 0 1477043
|
||||
prefix.http_request_total_count.constname.constvalue.count 0 1477043
|
||||
`
|
||||
|
||||
if got := buf.String(); want != got {
|
||||
t.Fatalf("wanted \n%s\n, got \n%s\n", want, got)
|
||||
}
|
||||
assert.Equal(t, want, buf.String())
|
||||
}
|
||||
|
||||
func TestPush(t *testing.T) {
|
||||
@ -489,20 +483,17 @@ func TestPush(t *testing.T) {
|
||||
Gatherer: reg,
|
||||
Prefix: "prefix.",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("error creating bridge: %v", err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
nmg, err := newMockGraphite(port)
|
||||
if err != nil {
|
||||
t.Fatalf("error creating mock graphite: %v", err)
|
||||
}
|
||||
defer nmg.Close()
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
err := nmg.Close()
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
err = b.Push()
|
||||
if err != nil {
|
||||
t.Fatalf("error pushing: %v", err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
wants := []string{
|
||||
"prefix.name.constname.constvalue.labelname.val1.count 1",
|
||||
|
@ -130,7 +130,7 @@ func (ts *TracingService) Run(ctx context.Context) error {
|
||||
|
||||
if ts.closer != nil {
|
||||
ts.log.Info("Closing tracing")
|
||||
ts.closer.Close()
|
||||
return ts.closer.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -58,9 +58,11 @@ func TestInitJaegerCfg_Enabled(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInitJaegerCfg_DisabledViaEnv(t *testing.T) {
|
||||
os.Setenv("JAEGER_DISABLED", "true")
|
||||
err := os.Setenv("JAEGER_DISABLED", "true")
|
||||
require.NoError(t, err)
|
||||
defer func() {
|
||||
os.Unsetenv("JAEGER_DISABLED")
|
||||
err := os.Unsetenv("JAEGER_DISABLED")
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
|
||||
ts := &TracingService{enabled: true}
|
||||
@ -71,9 +73,11 @@ func TestInitJaegerCfg_DisabledViaEnv(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInitJaegerCfg_EnabledViaEnv(t *testing.T) {
|
||||
os.Setenv("JAEGER_DISABLED", "false")
|
||||
err := os.Setenv("JAEGER_DISABLED", "false")
|
||||
require.NoError(t, err)
|
||||
defer func() {
|
||||
os.Unsetenv("JAEGER_DISABLED")
|
||||
err := os.Unsetenv("JAEGER_DISABLED")
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
|
||||
ts := &TracingService{enabled: false}
|
||||
@ -84,12 +88,14 @@ func TestInitJaegerCfg_EnabledViaEnv(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInitJaegerCfg_InvalidEnvVar(t *testing.T) {
|
||||
os.Setenv("JAEGER_DISABLED", "totallybogus")
|
||||
err := os.Setenv("JAEGER_DISABLED", "totallybogus")
|
||||
require.NoError(t, err)
|
||||
defer func() {
|
||||
os.Unsetenv("JAEGER_DISABLED")
|
||||
err := os.Unsetenv("JAEGER_DISABLED")
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
|
||||
ts := &TracingService{}
|
||||
_, err := ts.initJaegerCfg()
|
||||
_, err = ts.initJaegerCfg()
|
||||
require.EqualError(t, err, "cannot parse env var JAEGER_DISABLED=totallybogus: strconv.ParseBool: parsing \"totallybogus\": invalid syntax")
|
||||
}
|
||||
|
@ -50,7 +50,9 @@ func (uss *UsageStatsService) Run(ctx context.Context) error {
|
||||
for {
|
||||
select {
|
||||
case <-onceEveryDayTick.C:
|
||||
uss.sendUsageStats()
|
||||
if err := uss.sendUsageStats(); err != nil {
|
||||
metricsLogger.Warn("Failed to send usage stats", "err", err)
|
||||
}
|
||||
case <-everyMinuteTicker.C:
|
||||
uss.updateTotalStats()
|
||||
case <-ctx.Done():
|
||||
|
@ -186,19 +186,22 @@ func (uss *UsageStatsService) GetUsageReport() (UsageReport, error) {
|
||||
return report, nil
|
||||
}
|
||||
|
||||
func (uss *UsageStatsService) sendUsageStats() {
|
||||
func (uss *UsageStatsService) sendUsageStats() error {
|
||||
if !setting.ReportingEnabled {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
metricsLogger.Debug(fmt.Sprintf("Sending anonymous usage stats to %s", usageStatsURL))
|
||||
|
||||
report, err := uss.GetUsageReport()
|
||||
if err != nil {
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
out, _ := json.MarshalIndent(report, "", " ")
|
||||
out, err := json.MarshalIndent(report, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data := bytes.NewBuffer(out)
|
||||
|
||||
client := http.Client{Timeout: 5 * time.Second}
|
||||
@ -208,8 +211,12 @@ func (uss *UsageStatsService) sendUsageStats() {
|
||||
metricsLogger.Error("Failed to send usage stats", "err", err)
|
||||
return
|
||||
}
|
||||
resp.Body.Close()
|
||||
if err := resp.Body.Close(); err != nil {
|
||||
metricsLogger.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (uss *UsageStatsService) updateTotalStats() {
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
"github.com/grafana/grafana/pkg/services/licensing"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@ -171,11 +172,13 @@ func TestMetrics(t *testing.T) {
|
||||
"grafana_com": true,
|
||||
}
|
||||
|
||||
uss.sendUsageStats()
|
||||
err := uss.sendUsageStats()
|
||||
require.NoError(t, err)
|
||||
|
||||
Convey("Given reporting not enabled and sending usage stats", func() {
|
||||
setting.ReportingEnabled = false
|
||||
uss.sendUsageStats()
|
||||
err := uss.sendUsageStats()
|
||||
require.NoError(t, err)
|
||||
|
||||
Convey("Should not gather stats or call http endpoint", func() {
|
||||
So(getSystemStatsQuery, ShouldBeNil)
|
||||
@ -195,7 +198,8 @@ func TestMetrics(t *testing.T) {
|
||||
setting.Packaging = "deb"
|
||||
|
||||
wg.Add(1)
|
||||
uss.sendUsageStats()
|
||||
err := uss.sendUsageStats()
|
||||
require.NoError(t, err)
|
||||
|
||||
Convey("Should gather stats and call http endpoint", func() {
|
||||
if waitTimeout(&wg, 2*time.Second) {
|
||||
|
@ -56,7 +56,7 @@ func (s *SocialAzureAD) UserInfo(_ *http.Client, token *oauth2.Token) (*BasicUse
|
||||
|
||||
groups := extractGroups(claims)
|
||||
if !s.IsGroupMember(groups) {
|
||||
return nil, ErrMissingGroupMembership
|
||||
return nil, errMissingGroupMembership
|
||||
}
|
||||
|
||||
return &BasicUserInfo{
|
||||
|
@ -14,10 +14,10 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrMissingGroupMembership = &Error{"User not a member of one of the required groups"}
|
||||
errMissingGroupMembership = Error{"user not a member of one of the required groups"}
|
||||
)
|
||||
|
||||
type HttpGetResponse struct {
|
||||
type httpGetResponse struct {
|
||||
Body []byte
|
||||
Headers http.Header
|
||||
}
|
||||
@ -44,20 +44,24 @@ func isEmailAllowed(email string, allowedDomains []string) bool {
|
||||
return valid
|
||||
}
|
||||
|
||||
func HttpGet(client *http.Client, url string) (response HttpGetResponse, err error) {
|
||||
func (s *SocialBase) httpGet(client *http.Client, url string) (response httpGetResponse, err error) {
|
||||
r, err := client.Get(url)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer r.Body.Close()
|
||||
defer func() {
|
||||
if err := r.Body.Close(); err != nil {
|
||||
s.log.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
response = HttpGetResponse{body, r.Header}
|
||||
response = httpGetResponse{body, r.Header}
|
||||
|
||||
if r.StatusCode >= 300 {
|
||||
err = fmt.Errorf(string(response.Body))
|
||||
|
@ -229,7 +229,11 @@ func (s *SocialGenericOAuth) extractFromToken(token *oauth2.Token) *UserInfoJson
|
||||
s.log.Error("Error creating zlib reader", "error", err)
|
||||
return nil
|
||||
}
|
||||
defer fr.Close()
|
||||
defer func() {
|
||||
if err := fr.Close(); err != nil {
|
||||
s.log.Warn("Failed closing zlib reader", "error", err)
|
||||
}
|
||||
}()
|
||||
rawJSON, err = ioutil.ReadAll(fr)
|
||||
if err != nil {
|
||||
s.log.Error("Error decompressing payload", "error", err)
|
||||
@ -251,7 +255,7 @@ func (s *SocialGenericOAuth) extractFromToken(token *oauth2.Token) *UserInfoJson
|
||||
|
||||
func (s *SocialGenericOAuth) extractFromAPI(client *http.Client) *UserInfoJson {
|
||||
s.log.Debug("Getting user info from API")
|
||||
rawUserInfoResponse, err := HttpGet(client, s.apiUrl)
|
||||
rawUserInfoResponse, err := s.httpGet(client, s.apiUrl)
|
||||
if err != nil {
|
||||
s.log.Debug("Error getting user info from API", "url", s.apiUrl, "error", err)
|
||||
return nil
|
||||
@ -347,7 +351,7 @@ func (s *SocialGenericOAuth) FetchPrivateEmail(client *http.Client) (string, err
|
||||
IsConfirmed bool `json:"is_confirmed"`
|
||||
}
|
||||
|
||||
response, err := HttpGet(client, fmt.Sprintf(s.apiUrl+"/emails"))
|
||||
response, err := s.httpGet(client, fmt.Sprintf(s.apiUrl+"/emails"))
|
||||
if err != nil {
|
||||
s.log.Error("Error getting email address", "url", s.apiUrl+"/emails", "error", err)
|
||||
return "", errutil.Wrap("Error getting email address", err)
|
||||
@ -390,7 +394,7 @@ func (s *SocialGenericOAuth) FetchTeamMemberships(client *http.Client) ([]int, b
|
||||
Id int `json:"id"`
|
||||
}
|
||||
|
||||
response, err := HttpGet(client, fmt.Sprintf(s.apiUrl+"/teams"))
|
||||
response, err := s.httpGet(client, fmt.Sprintf(s.apiUrl+"/teams"))
|
||||
if err != nil {
|
||||
s.log.Error("Error getting team memberships", "url", s.apiUrl+"/teams", "error", err)
|
||||
return nil, false
|
||||
@ -419,7 +423,7 @@ func (s *SocialGenericOAuth) FetchOrganizations(client *http.Client) ([]string,
|
||||
Login string `json:"login"`
|
||||
}
|
||||
|
||||
response, err := HttpGet(client, fmt.Sprintf(s.apiUrl+"/orgs"))
|
||||
response, err := s.httpGet(client, fmt.Sprintf(s.apiUrl+"/orgs"))
|
||||
if err != nil {
|
||||
s.log.Error("Error getting organizations", "url", s.apiUrl+"/orgs", "error", err)
|
||||
return nil, false
|
||||
|
@ -29,8 +29,8 @@ type GithubTeam struct {
|
||||
}
|
||||
|
||||
var (
|
||||
ErrMissingTeamMembership = &Error{"User not a member of one of the required teams"}
|
||||
ErrMissingOrganizationMembership = &Error{"User not a member of one of the required organizations"}
|
||||
ErrMissingTeamMembership = Error{"user not a member of one of the required teams"}
|
||||
ErrMissingOrganizationMembership = Error{"user not a member of one of the required organizations"}
|
||||
)
|
||||
|
||||
func (s *SocialGithub) Type() int {
|
||||
@ -86,7 +86,7 @@ func (s *SocialGithub) FetchPrivateEmail(client *http.Client) (string, error) {
|
||||
Verified bool `json:"verified"`
|
||||
}
|
||||
|
||||
response, err := HttpGet(client, fmt.Sprintf(s.apiUrl+"/emails"))
|
||||
response, err := s.httpGet(client, fmt.Sprintf(s.apiUrl+"/emails"))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error getting email address: %s", err)
|
||||
}
|
||||
@ -114,7 +114,7 @@ func (s *SocialGithub) FetchTeamMemberships(client *http.Client) ([]GithubTeam,
|
||||
teams := make([]GithubTeam, 0)
|
||||
|
||||
for hasMore {
|
||||
response, err := HttpGet(client, url)
|
||||
response, err := s.httpGet(client, url)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error getting team memberships: %s", err)
|
||||
}
|
||||
@ -157,16 +157,16 @@ func (s *SocialGithub) FetchOrganizations(client *http.Client, organizationsUrl
|
||||
Login string `json:"login"`
|
||||
}
|
||||
|
||||
response, err := HttpGet(client, organizationsUrl)
|
||||
response, err := s.httpGet(client, organizationsUrl)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error getting organizations: %s", err)
|
||||
return nil, fmt.Errorf("error getting organizations: %s", err)
|
||||
}
|
||||
|
||||
var records []Record
|
||||
|
||||
err = json.Unmarshal(response.Body, &records)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error getting organizations: %s", err)
|
||||
return nil, fmt.Errorf("error getting organizations: %s", err)
|
||||
}
|
||||
|
||||
var logins = make([]string, len(records))
|
||||
@ -184,9 +184,9 @@ func (s *SocialGithub) UserInfo(client *http.Client, token *oauth2.Token) (*Basi
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
response, err := HttpGet(client, s.apiUrl)
|
||||
response, err := s.httpGet(client, s.apiUrl)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error getting user info: %s", err)
|
||||
return nil, fmt.Errorf("error getting user info: %s", err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(response.Body, &data)
|
||||
|
@ -62,7 +62,7 @@ func (s *SocialGitlab) GetGroupsPage(client *http.Client, url string) ([]string,
|
||||
return nil, next
|
||||
}
|
||||
|
||||
response, err := HttpGet(client, url)
|
||||
response, err := s.httpGet(client, url)
|
||||
if err != nil {
|
||||
s.log.Error("Error getting groups from GitLab API", "err", err)
|
||||
return nil, next
|
||||
@ -98,7 +98,7 @@ func (s *SocialGitlab) UserInfo(client *http.Client, token *oauth2.Token) (*Basi
|
||||
State string
|
||||
}
|
||||
|
||||
response, err := HttpGet(client, s.apiUrl+"/user")
|
||||
response, err := s.httpGet(client, s.apiUrl+"/user")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error getting user info: %s", err)
|
||||
}
|
||||
@ -123,7 +123,7 @@ func (s *SocialGitlab) UserInfo(client *http.Client, token *oauth2.Token) (*Basi
|
||||
}
|
||||
|
||||
if !s.IsGroupMember(groups) {
|
||||
return nil, ErrMissingGroupMembership
|
||||
return nil, errMissingGroupMembership
|
||||
}
|
||||
|
||||
return userInfo, nil
|
||||
|
@ -27,7 +27,7 @@ func (s *SocialGoogle) UserInfo(client *http.Client, token *oauth2.Token) (*Basi
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
response, err := HttpGet(client, s.apiUrl)
|
||||
response, err := s.httpGet(client, s.apiUrl)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error getting user info: %s", err)
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ func (s *SocialGrafanaCom) UserInfo(client *http.Client, token *oauth2.Token) (*
|
||||
Orgs []OrgRecord `json:"orgs"`
|
||||
}
|
||||
|
||||
response, err := HttpGet(client, s.url+"/api/oauth2/user")
|
||||
response, err := s.httpGet(client, s.url+"/api/oauth2/user")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error getting user info: %s", err)
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ func (s *SocialOkta) UserInfo(client *http.Client, token *oauth2.Token) (*BasicU
|
||||
|
||||
groups := s.GetGroups(&data)
|
||||
if !s.IsGroupMember(groups) {
|
||||
return nil, ErrMissingGroupMembership
|
||||
return nil, errMissingGroupMembership
|
||||
}
|
||||
|
||||
return &BasicUserInfo{
|
||||
@ -98,7 +98,7 @@ func (s *SocialOkta) UserInfo(client *http.Client, token *oauth2.Token) (*BasicU
|
||||
}
|
||||
|
||||
func (s *SocialOkta) extractAPI(data *OktaUserInfoJson, client *http.Client) error {
|
||||
rawUserInfoResponse, err := HttpGet(client, s.apiUrl)
|
||||
rawUserInfoResponse, err := s.httpGet(client, s.apiUrl)
|
||||
if err != nil {
|
||||
s.log.Debug("Error getting user info response", "url", s.apiUrl, "error", err)
|
||||
return errutil.Wrapf(err, "error getting user info response")
|
||||
|
@ -54,7 +54,7 @@ type Error struct {
|
||||
s string
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
func (e Error) Error() string {
|
||||
return e.s
|
||||
}
|
||||
|
||||
|
@ -35,8 +35,12 @@ func TestMiddlewareDashboardRedirect(t *testing.T) {
|
||||
sc.fakeReqWithParams("GET", "/dashboard/db/dash?orgId=1&panelId=2", map[string]string{}).exec()
|
||||
|
||||
assert.Equal(t, 301, sc.resp.Code)
|
||||
// nolint:bodyclose
|
||||
resp := sc.resp.Result()
|
||||
resp.Body.Close()
|
||||
t.Cleanup(func() {
|
||||
err := resp.Body.Close()
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
redirectURL, err := resp.Location()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, models.GetDashboardUrl(fakeDash.Uid, fakeDash.Slug), redirectURL.Path)
|
||||
@ -54,8 +58,12 @@ func TestMiddlewareDashboardRedirect(t *testing.T) {
|
||||
sc.fakeReqWithParams("GET", "/dashboard-solo/db/dash?orgId=1&panelId=2", map[string]string{}).exec()
|
||||
|
||||
assert.Equal(t, 301, sc.resp.Code)
|
||||
// nolint:bodyclose
|
||||
resp := sc.resp.Result()
|
||||
resp.Body.Close()
|
||||
t.Cleanup(func() {
|
||||
err := resp.Body.Close()
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
redirectURL, err := resp.Location()
|
||||
require.NoError(t, err)
|
||||
expectedURL := models.GetDashboardUrl(fakeDash.Uid, fakeDash.Slug)
|
||||
@ -71,8 +79,12 @@ func TestMiddlewareDashboardRedirect(t *testing.T) {
|
||||
sc.fakeReqWithParams("GET", "/d/asd/dash?orgId=1&panelId=12&fullscreen&edit", map[string]string{}).exec()
|
||||
|
||||
assert.Equal(t, 301, sc.resp.Code)
|
||||
// nolint:bodyclose
|
||||
resp := sc.resp.Result()
|
||||
resp.Body.Close()
|
||||
t.Cleanup(func() {
|
||||
err := resp.Body.Close()
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
redirectURL, err := resp.Location()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "/d/asd/d/asd/dash?editPanel=12&orgId=1", redirectURL.String())
|
||||
|
@ -378,8 +378,10 @@ func TestMiddlewareContext(t *testing.T) {
|
||||
return nil
|
||||
})
|
||||
|
||||
key := fmt.Sprintf(authproxy.CachePrefix, authproxy.HashCacheKey(hdrName+"-"+group))
|
||||
err := sc.remoteCacheService.Set(key, userID, 0)
|
||||
h, err := authproxy.HashCacheKey(hdrName + "-" + group)
|
||||
require.NoError(t, err)
|
||||
key := fmt.Sprintf(authproxy.CachePrefix, h)
|
||||
err = sc.remoteCacheService.Set(key, userID, 0)
|
||||
require.NoError(t, err)
|
||||
sc.fakeReq("GET", "/")
|
||||
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"time"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/securejsondata"
|
||||
@ -223,15 +224,16 @@ func TestDataSourceProxyCache(t *testing.T) {
|
||||
// 2. Get HTTP transport from datasource which uses the test server as backend
|
||||
ds.Url = backend.URL
|
||||
transport, err := ds.GetHttpTransport()
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// 3. Send test request which should have the Authorization header set
|
||||
req := httptest.NewRequest("GET", backend.URL+"/test-headers", nil)
|
||||
res, err := transport.RoundTrip(req)
|
||||
So(err, ShouldBeNil)
|
||||
defer res.Body.Close()
|
||||
t.Cleanup(func() {
|
||||
err := res.Body.Close()
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
So(err, ShouldBeNil)
|
||||
bodyStr := string(body)
|
||||
|
@ -31,7 +31,10 @@ var handshake = goplugin.HandshakeConfig{
|
||||
MagicCookieValue: grpcplugin.MagicCookieValue,
|
||||
}
|
||||
|
||||
func newClientConfig(executablePath string, env []string, logger log.Logger, versionedPlugins map[int]goplugin.PluginSet) *goplugin.ClientConfig {
|
||||
func newClientConfig(executablePath string, env []string, logger log.Logger,
|
||||
versionedPlugins map[int]goplugin.PluginSet) *goplugin.ClientConfig {
|
||||
// We can ignore gosec G201 here, since the dynamic part of executablePath comes from the plugin definition
|
||||
// nolint:gosec
|
||||
cmd := exec.Command(executablePath)
|
||||
cmd.Env = env
|
||||
|
||||
@ -77,7 +80,7 @@ func getV2PluginSet() goplugin.PluginSet {
|
||||
|
||||
// NewBackendPlugin creates a new backend plugin factory used for registering a backend plugin.
|
||||
func NewBackendPlugin(pluginID, executablePath string, startFns PluginStartFuncs) backendplugin.PluginFactoryFunc {
|
||||
return New(PluginDescriptor{
|
||||
return newPlugin(PluginDescriptor{
|
||||
pluginID: pluginID,
|
||||
executablePath: executablePath,
|
||||
managed: true,
|
||||
@ -93,7 +96,7 @@ func NewBackendPlugin(pluginID, executablePath string, startFns PluginStartFuncs
|
||||
|
||||
// NewRendererPlugin creates a new renderer plugin factory used for registering a backend renderer plugin.
|
||||
func NewRendererPlugin(pluginID, executablePath string, startFns PluginStartFuncs) backendplugin.PluginFactoryFunc {
|
||||
return New(PluginDescriptor{
|
||||
return newPlugin(PluginDescriptor{
|
||||
pluginID: pluginID,
|
||||
executablePath: executablePath,
|
||||
managed: false,
|
||||
|
@ -26,8 +26,8 @@ type grpcPlugin struct {
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
// New allocates and returns a new gRPC (external) backendplugin.Plugin.
|
||||
func New(descriptor PluginDescriptor) backendplugin.PluginFactoryFunc {
|
||||
// newPlugin allocates and returns a new gRPC (external) backendplugin.Plugin.
|
||||
func newPlugin(descriptor PluginDescriptor) backendplugin.PluginFactoryFunc {
|
||||
return backendplugin.PluginFactoryFunc(func(pluginID string, logger log.Logger, env []string) (backendplugin.Plugin, error) {
|
||||
return &grpcPlugin{
|
||||
descriptor: descriptor,
|
||||
|
@ -257,6 +257,11 @@ func (m *manager) callResourceInternal(w http.ResponseWriter, req *http.Request,
|
||||
childCtx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
stream := newCallResourceResponseStream(childCtx)
|
||||
defer func() {
|
||||
if err := stream.Close(); err != nil {
|
||||
m.logger.Warn("Failed to close stream", "err", err)
|
||||
}
|
||||
}()
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
var flushStreamErr error
|
||||
@ -265,12 +270,15 @@ func (m *manager) callResourceInternal(w http.ResponseWriter, req *http.Request,
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
innerErr := p.CallResource(req.Context(), crReq, stream)
|
||||
stream.Close()
|
||||
if innerErr != nil {
|
||||
return innerErr
|
||||
if err := p.CallResource(req.Context(), crReq, stream); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := stream.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
return flushStreamErr
|
||||
})
|
||||
}
|
||||
|
@ -95,11 +95,11 @@ func loadPluginDashboard(pluginId, path string) (*models.Dashboard, error) {
|
||||
return nil, PluginNotFoundError{pluginId}
|
||||
}
|
||||
|
||||
dashboardFilePath := filepath.Join(plugin.PluginDir, path)
|
||||
// nolint:gosec
|
||||
// We can ignore the gosec G304 warning on this one because `plugin.PluginDir` is based
|
||||
// on plugin folder structure on disk and not user input. `path` comes from the
|
||||
// `plugin.json` configuration file for the loaded plugin
|
||||
dashboardFilePath := filepath.Join(plugin.PluginDir, path)
|
||||
reader, err := os.Open(dashboardFilePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -335,9 +335,6 @@ func (s *PluginScanner) walker(currentPath string, f os.FileInfo, err error) err
|
||||
return nil
|
||||
}
|
||||
|
||||
// nolint:gosec
|
||||
// We can ignore the gosec G304 warning on this one because `currentPath` is based
|
||||
// on plugin the folder structure on disk and not user input.
|
||||
if err := s.loadPlugin(currentPath); err != nil {
|
||||
s.log.Error("Failed to load plugin", "error", err, "pluginPath", filepath.Dir(currentPath))
|
||||
s.errors = append(s.errors, err)
|
||||
@ -349,6 +346,9 @@ func (s *PluginScanner) walker(currentPath string, f os.FileInfo, err error) err
|
||||
func (s *PluginScanner) loadPlugin(pluginJSONFilePath string) error {
|
||||
s.log.Debug("Loading plugin", "path", pluginJSONFilePath)
|
||||
currentDir := filepath.Dir(pluginJSONFilePath)
|
||||
// nolint:gosec
|
||||
// We can ignore the gosec G304 warning on this one because `currentPath` is based
|
||||
// on plugin the folder structure on disk and not user input.
|
||||
reader, err := os.Open(pluginJSONFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -48,13 +48,15 @@ func (pm *PluginManager) checkForUpdates() {
|
||||
|
||||
pluginSlugs := getAllExternalPluginSlugs()
|
||||
resp, err := httpClient.Get("https://grafana.com/api/plugins/versioncheck?slugIn=" + pluginSlugs + "&grafanaVersion=" + setting.BuildVersion)
|
||||
|
||||
if err != nil {
|
||||
log.Tracef("Failed to get plugins repo from grafana.com, %v", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
defer func() {
|
||||
if err := resp.Body.Close(); err != nil {
|
||||
log.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
@ -91,8 +93,11 @@ func (pm *PluginManager) checkForUpdates() {
|
||||
log.Tracef("Failed to get latest.json repo from github.com: %v", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
defer resp2.Body.Close()
|
||||
defer func() {
|
||||
if err := resp2.Body.Close(); err != nil {
|
||||
pm.log.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
body, err = ioutil.ReadAll(resp2.Body)
|
||||
if err != nil {
|
||||
log.Tracef("Update check failed, reading response from github.com, %v", err.Error())
|
||||
|
@ -341,7 +341,11 @@ func (s *Server) notifySystemd(state string) {
|
||||
s.log.Warn("Failed to connect to systemd", "err", err, "socket", notifySocket)
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
defer func() {
|
||||
if err := conn.Close(); err != nil {
|
||||
s.log.Warn("Failed to close connection", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
_, err = conn.Write([]byte(state))
|
||||
if err != nil {
|
||||
|
@ -19,10 +19,13 @@ func TestAlertingUsageStats(t *testing.T) {
|
||||
|
||||
ae.Bus.AddHandler(func(query *models.GetAllAlertsQuery) error {
|
||||
var createFake = func(file string) *simplejson.Json {
|
||||
// Ignore gosec warning G304 since it's a test
|
||||
// nolint:gosec
|
||||
content, err := ioutil.ReadFile(file)
|
||||
require.NoError(t, err, "expected to be able to read file")
|
||||
|
||||
j, _ := simplejson.NewJson(content)
|
||||
j, err := simplejson.NewJson(content)
|
||||
require.NoError(t, err)
|
||||
return j
|
||||
}
|
||||
|
||||
|
@ -387,8 +387,10 @@ func (pn *PushoverNotifier) genPushoverBody(evalContext *alerting.EvalContext, m
|
||||
if err != nil {
|
||||
return nil, b, err
|
||||
}
|
||||
if err := w.Close(); err != nil {
|
||||
return nil, b, err
|
||||
}
|
||||
|
||||
w.Close()
|
||||
headers := map[string]string{
|
||||
"Content-Type": w.FormDataContentType(),
|
||||
}
|
||||
|
@ -170,6 +170,11 @@ func (tn *TelegramNotifier) buildMessageInlineImage(evalContext *alerting.EvalCo
|
||||
func (tn *TelegramNotifier) generateTelegramCmd(message string, messageField string, apiAction string, extraConf func(writer *multipart.Writer)) (*models.SendWebhookSync, error) {
|
||||
var body bytes.Buffer
|
||||
w := multipart.NewWriter(&body)
|
||||
defer func() {
|
||||
if err := w.Close(); err != nil {
|
||||
tn.log.Warn("Failed to close writer", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
fw, err := w.CreateFormField("chat_id")
|
||||
if err != nil {
|
||||
@ -189,7 +194,9 @@ func (tn *TelegramNotifier) generateTelegramCmd(message string, messageField str
|
||||
|
||||
extraConf(w)
|
||||
|
||||
w.Close()
|
||||
if err := w.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tn.log.Info("Sending telegram notification", "chat_id", tn.ChatID, "bot_token", tn.BotToken, "apiAction", apiAction)
|
||||
url := fmt.Sprintf(telegramAPIURL, tn.BotToken, apiAction)
|
||||
|
@ -65,7 +65,9 @@ func TestInitContextWithAuthProxy_CachedInvalidUserID(t *testing.T) {
|
||||
Logger: log.New("Test"),
|
||||
}
|
||||
req.Header.Set(svc.Cfg.AuthProxyHeaderName, name)
|
||||
key := fmt.Sprintf(authproxy.CachePrefix, authproxy.HashCacheKey(name))
|
||||
h, err := authproxy.HashCacheKey(name)
|
||||
require.NoError(t, err)
|
||||
key := fmt.Sprintf(authproxy.CachePrefix, h)
|
||||
|
||||
t.Logf("Injecting stale user ID in cache with key %q", key)
|
||||
err = svc.RemoteCache.Set(key, int64(33), 0)
|
||||
|
@ -141,25 +141,29 @@ func (auth *AuthProxy) IsAllowedIP() error {
|
||||
))
|
||||
}
|
||||
|
||||
func HashCacheKey(key string) string {
|
||||
func HashCacheKey(key string) (string, error) {
|
||||
hasher := fnv.New128a()
|
||||
// according to the documentation, Hash.Write cannot error, but linter is complaining
|
||||
hasher.Write([]byte(key)) // nolint: errcheck
|
||||
return hex.EncodeToString(hasher.Sum(nil))
|
||||
if _, err := hasher.Write([]byte(key)); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return hex.EncodeToString(hasher.Sum(nil)), nil
|
||||
}
|
||||
|
||||
// getKey forms a key for the cache based on the headers received as part of the authentication flow.
|
||||
// Our configuration supports multiple headers. The main header contains the email or username.
|
||||
// And the additional ones that allow us to specify extra attributes: Name, Email or Groups.
|
||||
func (auth *AuthProxy) getKey() string {
|
||||
func (auth *AuthProxy) getKey() (string, error) {
|
||||
key := strings.TrimSpace(auth.header) // start the key with the main header
|
||||
|
||||
auth.headersIterator(func(_, header string) {
|
||||
key = strings.Join([]string{key, header}, "-") // compose the key with any additional headers
|
||||
})
|
||||
|
||||
hashedKey := HashCacheKey(key)
|
||||
return fmt.Sprintf(CachePrefix, hashedKey)
|
||||
hashedKey, err := HashCacheKey(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf(CachePrefix, hashedKey), nil
|
||||
}
|
||||
|
||||
// Login logs in user ID by whatever means possible.
|
||||
@ -194,7 +198,10 @@ func (auth *AuthProxy) Login(logger log.Logger, ignoreCache bool) (int64, error)
|
||||
|
||||
// GetUserViaCache gets user ID from cache.
|
||||
func (auth *AuthProxy) GetUserViaCache(logger log.Logger) (int64, error) {
|
||||
cacheKey := auth.getKey()
|
||||
cacheKey, err := auth.getKey()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
logger.Debug("Getting user ID via auth cache", "cacheKey", cacheKey)
|
||||
userID, err := auth.remoteCache.Get(cacheKey)
|
||||
if err != nil {
|
||||
@ -208,7 +215,10 @@ func (auth *AuthProxy) GetUserViaCache(logger log.Logger) (int64, error) {
|
||||
|
||||
// RemoveUserFromCache removes user from cache.
|
||||
func (auth *AuthProxy) RemoveUserFromCache(logger log.Logger) error {
|
||||
cacheKey := auth.getKey()
|
||||
cacheKey, err := auth.getKey()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Debug("Removing user from auth cache", "cacheKey", cacheKey)
|
||||
if err := auth.remoteCache.Delete(cacheKey); err != nil {
|
||||
return err
|
||||
@ -318,18 +328,20 @@ func (auth *AuthProxy) GetSignedInUser(userID int64) (*models.SignedInUser, erro
|
||||
|
||||
// Remember user in cache
|
||||
func (auth *AuthProxy) Remember(id int64) error {
|
||||
key := auth.getKey()
|
||||
key, err := auth.getKey()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Check if user already in cache
|
||||
userID, _ := auth.remoteCache.Get(key)
|
||||
if userID != nil {
|
||||
userID, err := auth.remoteCache.Get(key)
|
||||
if err == nil && userID != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
expiration := time.Duration(auth.cfg.AuthProxySyncTTL) * time.Minute
|
||||
|
||||
err := auth.remoteCache.Set(key, id, expiration)
|
||||
if err != nil {
|
||||
if err := auth.remoteCache.Set(key, id, expiration); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -87,12 +87,16 @@ func TestMiddlewareContext(t *testing.T) {
|
||||
t.Run("When the cache only contains the main header with a simple cache key", func(t *testing.T) {
|
||||
const id int64 = 33
|
||||
// Set cache key
|
||||
key := fmt.Sprintf(CachePrefix, HashCacheKey(hdrName))
|
||||
err := cache.Set(key, id, 0)
|
||||
h, err := HashCacheKey(hdrName)
|
||||
require.NoError(t, err)
|
||||
key := fmt.Sprintf(CachePrefix, h)
|
||||
err = cache.Set(key, id, 0)
|
||||
require.NoError(t, err)
|
||||
// Set up the middleware
|
||||
auth := prepareMiddleware(t, cache, nil)
|
||||
assert.Equal(t, key, auth.getKey())
|
||||
gotKey, err := auth.getKey()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, key, gotKey)
|
||||
|
||||
gotID, err := auth.Login(logger, false)
|
||||
require.NoError(t, err)
|
||||
@ -104,15 +108,17 @@ func TestMiddlewareContext(t *testing.T) {
|
||||
const id int64 = 33
|
||||
const group = "grafana-core-team"
|
||||
|
||||
key := fmt.Sprintf(CachePrefix, HashCacheKey(hdrName+"-"+group))
|
||||
err := cache.Set(key, id, 0)
|
||||
h, err := HashCacheKey(hdrName + "-" + group)
|
||||
require.NoError(t, err)
|
||||
key := fmt.Sprintf(CachePrefix, h)
|
||||
err = cache.Set(key, id, 0)
|
||||
require.NoError(t, err)
|
||||
|
||||
auth := prepareMiddleware(t, cache, func(req *http.Request, cfg *setting.Cfg) {
|
||||
req.Header.Set("X-WEBAUTH-GROUPS", group)
|
||||
cfg.AuthProxyHeaders = map[string]string{"Groups": "X-WEBAUTH-GROUPS"}
|
||||
})
|
||||
assert.Equal(t, "auth-proxy-sync-ttl:14f69b7023baa0ac98c96b31cec07bc0", auth.getKey())
|
||||
assert.Equal(t, "auth-proxy-sync-ttl:14f69b7023baa0ac98c96b31cec07bc0", key)
|
||||
|
||||
gotID, err := auth.Login(logger, false)
|
||||
require.NoError(t, err)
|
||||
|
@ -64,8 +64,12 @@ func TestTokenRotationAtEndOfRequest(t *testing.T) {
|
||||
ctxHdlr.rotateEndOfRequestFunc(reqContext, uts, token)(reqContext.Resp)
|
||||
|
||||
foundLoginCookie := false
|
||||
// nolint:bodyclose
|
||||
resp := rr.Result()
|
||||
defer resp.Body.Close()
|
||||
t.Cleanup(func() {
|
||||
err := resp.Body.Close()
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
for _, c := range resp.Cookies() {
|
||||
if c.Name == "login_token" {
|
||||
foundLoginCookie = true
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestReadingLDAPSettings(t *testing.T) {
|
||||
@ -14,9 +15,10 @@ func TestReadingLDAPSettings(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestReadingLDAPSettingsWithEnvVariable(t *testing.T) {
|
||||
os.Setenv("ENV_PASSWORD", "MySecret")
|
||||
err := os.Setenv("ENV_PASSWORD", "MySecret")
|
||||
require.NoError(t, err)
|
||||
|
||||
config, err := readConfig("testdata/ldap.toml")
|
||||
assert.Nil(t, err, "No error when reading ldap config")
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, "MySecret", config.Servers[0].BindPassword)
|
||||
}
|
||||
|
@ -76,8 +76,11 @@ func (ns *NotificationService) sendWebRequestSync(ctx context.Context, webhook *
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
defer func() {
|
||||
if err := resp.Body.Close(); err != nil {
|
||||
ns.log.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if resp.StatusCode/100 == 2 {
|
||||
ns.log.Debug("Webhook succeeded", "url", webhook.Url, "statuscode", resp.Status)
|
||||
|
@ -19,10 +19,14 @@ import (
|
||||
|
||||
func TestValues(t *testing.T) {
|
||||
Convey("Values", t, func() {
|
||||
os.Setenv("INT", "1")
|
||||
os.Setenv("STRING", "test")
|
||||
os.Setenv("EMPTYSTRING", "")
|
||||
os.Setenv("BOOL", "true")
|
||||
err := os.Setenv("INT", "1")
|
||||
So(err, ShouldBeNil)
|
||||
err = os.Setenv("STRING", "test")
|
||||
So(err, ShouldBeNil)
|
||||
err = os.Setenv("EMPTYSTRING", "")
|
||||
So(err, ShouldBeNil)
|
||||
err = os.Setenv("BOOL", "true")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("IntValue", func() {
|
||||
type Data struct {
|
||||
@ -240,10 +244,14 @@ func TestValues(t *testing.T) {
|
||||
})
|
||||
|
||||
Reset(func() {
|
||||
os.Unsetenv("INT")
|
||||
os.Unsetenv("STRING")
|
||||
os.Unsetenv("EMPTYSTRING")
|
||||
os.Unsetenv("BOOL")
|
||||
err := os.Unsetenv("INT")
|
||||
So(err, ShouldBeNil)
|
||||
err = os.Unsetenv("STRING")
|
||||
So(err, ShouldBeNil)
|
||||
err = os.Unsetenv("EMPTYSTRING")
|
||||
So(err, ShouldBeNil)
|
||||
err = os.Unsetenv("BOOL")
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -77,7 +77,11 @@ func (rs *RenderingService) renderViaHttp(ctx context.Context, renderKey string,
|
||||
}
|
||||
|
||||
// save response to file
|
||||
defer resp.Body.Close()
|
||||
defer func() {
|
||||
if err := resp.Body.Close(); err != nil {
|
||||
rs.log.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// check for timeout first
|
||||
if errors.Is(reqContext.Err(), context.DeadlineExceeded) {
|
||||
|
@ -15,8 +15,12 @@ func TestDynamicSettingsSupport_Override(t *testing.T) {
|
||||
keyName := "bar"
|
||||
expected := "dynamic value"
|
||||
|
||||
os.Setenv(envKey, expected)
|
||||
defer func() { os.Unsetenv(envKey) }()
|
||||
err := os.Setenv(envKey, expected)
|
||||
require.NoError(t, err)
|
||||
defer func() {
|
||||
err := os.Unsetenv(envKey)
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
|
||||
value := cfg.SectionWithEnvOverrides(sectionName).Key(keyName).MustString("default value")
|
||||
require.Equal(t, expected, value)
|
||||
|
@ -16,7 +16,8 @@ import (
|
||||
func TestExpandVar_EnvSuccessful(t *testing.T) {
|
||||
const key = "GF_TEST_SETTING_EXPANDER_ENV"
|
||||
const expected = "aurora borealis"
|
||||
os.Setenv(key, expected)
|
||||
err := os.Setenv(key, expected)
|
||||
require.NoError(t, err)
|
||||
|
||||
// expanded format
|
||||
{
|
||||
@ -39,12 +40,14 @@ func TestExpandVar_FileSuccessful(t *testing.T) {
|
||||
file := f.Name()
|
||||
|
||||
defer func() {
|
||||
os.Remove(file)
|
||||
err := os.Remove(file)
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
|
||||
_, err = f.WriteString("hello, world")
|
||||
require.NoError(t, err)
|
||||
f.Close()
|
||||
err = f.Close()
|
||||
require.NoError(t, err)
|
||||
|
||||
got, err := ExpandVar(fmt.Sprintf("$__file{%s}", file))
|
||||
assert.NoError(t, err)
|
||||
|
@ -39,7 +39,10 @@ func TestLoadingSettings(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Errorf("failed to load defaults.ini file: %v", err)
|
||||
}
|
||||
defer file.Close()
|
||||
defer func() {
|
||||
err := file.Close()
|
||||
So(err, ShouldBeNil)
|
||||
}()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
@ -51,10 +54,11 @@ func TestLoadingSettings(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Should be able to override via environment variables", func() {
|
||||
os.Setenv("GF_SECURITY_ADMIN_USER", "superduper")
|
||||
err := os.Setenv("GF_SECURITY_ADMIN_USER", "superduper")
|
||||
require.NoError(t, err)
|
||||
|
||||
cfg := NewCfg()
|
||||
err := cfg.Load(&CommandLineArgs{HomePath: "../../"})
|
||||
err = cfg.Load(&CommandLineArgs{HomePath: "../../"})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(AdminUser, ShouldEqual, "superduper")
|
||||
@ -63,29 +67,32 @@ func TestLoadingSettings(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Should replace password when defined in environment", func() {
|
||||
os.Setenv("GF_SECURITY_ADMIN_PASSWORD", "supersecret")
|
||||
err := os.Setenv("GF_SECURITY_ADMIN_PASSWORD", "supersecret")
|
||||
require.NoError(t, err)
|
||||
|
||||
cfg := NewCfg()
|
||||
err := cfg.Load(&CommandLineArgs{HomePath: "../../"})
|
||||
err = cfg.Load(&CommandLineArgs{HomePath: "../../"})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(appliedEnvOverrides, ShouldContain, "GF_SECURITY_ADMIN_PASSWORD=*********")
|
||||
})
|
||||
|
||||
Convey("Should return an error when url is invalid", func() {
|
||||
os.Setenv("GF_DATABASE_URL", "postgres.%31://grafana:secret@postgres:5432/grafana")
|
||||
err := os.Setenv("GF_DATABASE_URL", "postgres.%31://grafana:secret@postgres:5432/grafana")
|
||||
require.NoError(t, err)
|
||||
|
||||
cfg := NewCfg()
|
||||
err := cfg.Load(&CommandLineArgs{HomePath: "../../"})
|
||||
err = cfg.Load(&CommandLineArgs{HomePath: "../../"})
|
||||
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
Convey("Should replace password in URL when url environment is defined", func() {
|
||||
os.Setenv("GF_DATABASE_URL", "mysql://user:secret@localhost:3306/database")
|
||||
err := os.Setenv("GF_DATABASE_URL", "mysql://user:secret@localhost:3306/database")
|
||||
require.NoError(t, err)
|
||||
|
||||
cfg := NewCfg()
|
||||
err := cfg.Load(&CommandLineArgs{HomePath: "../../"})
|
||||
err = cfg.Load(&CommandLineArgs{HomePath: "../../"})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(appliedEnvOverrides, ShouldContain, "GF_DATABASE_URL=mysql://user:-redacted-@localhost:3306/database")
|
||||
@ -186,9 +193,10 @@ func TestLoadingSettings(t *testing.T) {
|
||||
|
||||
Convey("Can use environment variables in config values", func() {
|
||||
if runtime.GOOS == windows {
|
||||
os.Setenv("GF_DATA_PATH", `c:\tmp\env_override`)
|
||||
err := os.Setenv("GF_DATA_PATH", `c:\tmp\env_override`)
|
||||
require.NoError(t, err)
|
||||
cfg := NewCfg()
|
||||
err := cfg.Load(&CommandLineArgs{
|
||||
err = cfg.Load(&CommandLineArgs{
|
||||
HomePath: "../../",
|
||||
Args: []string{"cfg:paths.data=${GF_DATA_PATH}"},
|
||||
})
|
||||
@ -196,9 +204,10 @@ func TestLoadingSettings(t *testing.T) {
|
||||
|
||||
So(cfg.DataPath, ShouldEqual, `c:\tmp\env_override`)
|
||||
} else {
|
||||
os.Setenv("GF_DATA_PATH", "/tmp/env_override")
|
||||
err := os.Setenv("GF_DATA_PATH", "/tmp/env_override")
|
||||
require.NoError(t, err)
|
||||
cfg := NewCfg()
|
||||
err := cfg.Load(&CommandLineArgs{
|
||||
err = cfg.Load(&CommandLineArgs{
|
||||
HomePath: "../../",
|
||||
Args: []string{"cfg:paths.data=${GF_DATA_PATH}"},
|
||||
})
|
||||
|
@ -172,7 +172,11 @@ func (e *ApplicationInsightsDatasource) executeQuery(ctx context.Context, query
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
defer res.Body.Close()
|
||||
defer func() {
|
||||
if err := res.Body.Close(); err != nil {
|
||||
azlog.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -156,8 +156,7 @@ func TestInsightsMetricsResultToFrame(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
res, err := loadInsightsMetricsResponse(tt.testFile)
|
||||
require.NoError(t, err)
|
||||
res := loadInsightsMetricsResponse(t, tt.testFile)
|
||||
|
||||
frame, err := InsightsMetricsResultToFrame(res, tt.metric, tt.agg, tt.dimensions)
|
||||
require.NoError(t, err)
|
||||
@ -171,16 +170,23 @@ func TestInsightsMetricsResultToFrame(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func loadInsightsMetricsResponse(name string) (MetricsResult, error) {
|
||||
var mr MetricsResult
|
||||
func loadInsightsMetricsResponse(t *testing.T, name string) MetricsResult {
|
||||
t.Helper()
|
||||
|
||||
path := filepath.Join("testdata", name)
|
||||
// Ignore gosec warning G304 since it's a test
|
||||
// nolint:gosec
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return mr, err
|
||||
}
|
||||
defer f.Close()
|
||||
require.NoError(t, err)
|
||||
defer func() {
|
||||
err := f.Close()
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
|
||||
d := json.NewDecoder(f)
|
||||
var mr MetricsResult
|
||||
err = d.Decode(&mr)
|
||||
return mr, err
|
||||
require.NoError(t, err)
|
||||
|
||||
return mr
|
||||
}
|
||||
|
@ -264,11 +264,14 @@ func (ar *AzureLogAnalyticsResponse) GetPrimaryResultTable() (*AzureLogAnalytics
|
||||
|
||||
func (e *AzureLogAnalyticsDatasource) unmarshalResponse(res *http.Response) (AzureLogAnalyticsResponse, error) {
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
defer res.Body.Close()
|
||||
|
||||
if err != nil {
|
||||
return AzureLogAnalyticsResponse{}, err
|
||||
}
|
||||
defer func() {
|
||||
if err := res.Body.Close(); err != nil {
|
||||
azlog.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if res.StatusCode/100 != 2 {
|
||||
azlog.Debug("Request failed", "status", res.Status, "body", string(body))
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/xorcare/pointer"
|
||||
)
|
||||
@ -140,8 +141,7 @@ func TestLogTableToFrame(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
res, err := loadLogAnalyticsTestFileWithNumber(tt.testFile)
|
||||
require.NoError(t, err)
|
||||
res := loadLogAnalyticsTestFileWithNumber(t, tt.testFile)
|
||||
frame, err := LogTableToFrame(&res.Tables[0])
|
||||
require.NoError(t, err)
|
||||
|
||||
@ -152,17 +152,22 @@ func TestLogTableToFrame(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func loadLogAnalyticsTestFileWithNumber(name string) (AzureLogAnalyticsResponse, error) {
|
||||
var data AzureLogAnalyticsResponse
|
||||
|
||||
func loadLogAnalyticsTestFileWithNumber(t *testing.T, name string) AzureLogAnalyticsResponse {
|
||||
t.Helper()
|
||||
path := filepath.Join("testdata", name)
|
||||
// Ignore gosec warning G304 since it's a test
|
||||
// nolint:gosec
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return data, err
|
||||
}
|
||||
defer f.Close()
|
||||
require.NoError(t, err)
|
||||
defer func() {
|
||||
err := f.Close()
|
||||
assert.NoError(t, err)
|
||||
}()
|
||||
|
||||
d := json.NewDecoder(f)
|
||||
d.UseNumber()
|
||||
var data AzureLogAnalyticsResponse
|
||||
err = d.Decode(&data)
|
||||
return data, err
|
||||
require.NoError(t, err)
|
||||
return data
|
||||
}
|
||||
|
@ -206,6 +206,11 @@ func (e *AzureMonitorDatasource) executeQuery(ctx context.Context, query *AzureM
|
||||
queryResult.Error = err
|
||||
return queryResult, AzureMonitorResponse{}, nil
|
||||
}
|
||||
defer func() {
|
||||
if err := res.Body.Close(); err != nil {
|
||||
azlog.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
data, err := e.unmarshalResponse(res)
|
||||
if err != nil {
|
||||
@ -256,7 +261,6 @@ func (e *AzureMonitorDatasource) createRequest(ctx context.Context, dsInfo *mode
|
||||
|
||||
func (e *AzureMonitorDatasource) unmarshalResponse(res *http.Response) (AzureMonitorResponse, error) {
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
defer res.Body.Close()
|
||||
if err != nil {
|
||||
return AzureMonitorResponse{}, err
|
||||
}
|
||||
|
@ -433,10 +433,9 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
azData, err := loadTestFile("azuremonitor/" + tt.responseFile)
|
||||
require.NoError(t, err)
|
||||
azData := loadTestFile(t, "azuremonitor/"+tt.responseFile)
|
||||
res := &tsdb.QueryResult{Meta: simplejson.New(), RefId: "A"}
|
||||
err = datasource.parseResponse(res, azData, tt.mockQuery)
|
||||
err := datasource.parseResponse(res, azData, tt.mockQuery)
|
||||
require.NoError(t, err)
|
||||
|
||||
frames, err := res.Dataframes.Decoded()
|
||||
@ -496,14 +495,17 @@ func TestFindClosestAllowIntervalMS(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func loadTestFile(name string) (AzureMonitorResponse, error) {
|
||||
var azData AzureMonitorResponse
|
||||
func loadTestFile(t *testing.T, name string) AzureMonitorResponse {
|
||||
t.Helper()
|
||||
|
||||
path := filepath.Join("testdata", name)
|
||||
// Ignore gosec warning G304 since it's a test
|
||||
// nolint:gosec
|
||||
jsonBody, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return azData, err
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
var azData AzureMonitorResponse
|
||||
err = json.Unmarshal(jsonBody, &azData)
|
||||
return azData, err
|
||||
require.NoError(t, err)
|
||||
return azData
|
||||
}
|
||||
|
@ -132,10 +132,14 @@ func (e *InsightsAnalyticsDatasource) executeQuery(ctx context.Context, query *I
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
defer res.Body.Close()
|
||||
if err != nil {
|
||||
return queryResultError(err)
|
||||
}
|
||||
defer func() {
|
||||
if err := res.Body.Close(); err != nil {
|
||||
azlog.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if res.StatusCode/100 != 2 {
|
||||
azlog.Debug("Request failed", "status", res.Status, "body", string(body))
|
||||
|
@ -482,10 +482,14 @@ func (e *CloudMonitoringExecutor) executeQuery(ctx context.Context, query *cloud
|
||||
|
||||
func (e *CloudMonitoringExecutor) unmarshalResponse(res *http.Response) (cloudMonitoringResponse, error) {
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
defer res.Body.Close()
|
||||
if err != nil {
|
||||
return cloudMonitoringResponse{}, err
|
||||
}
|
||||
defer func() {
|
||||
if err := res.Body.Close(); err != nil {
|
||||
slog.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if res.StatusCode/100 != 2 {
|
||||
slog.Error("Request failed", "status", res.Status, "body", string(body))
|
||||
|
@ -989,6 +989,8 @@ func TestCloudMonitoring(t *testing.T) {
|
||||
func loadTestFile(path string) (cloudMonitoringResponse, error) {
|
||||
var data cloudMonitoringResponse
|
||||
|
||||
// Can ignore gosec warning G304 here since it's a test path
|
||||
// nolint:gosec
|
||||
jsonBody, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return data, err
|
||||
|
@ -226,7 +226,11 @@ func (c *baseClientImpl) ExecuteMultisearch(r *MultiSearchRequest) (*MultiSearch
|
||||
return nil, err
|
||||
}
|
||||
res := clientRes.httpResponse
|
||||
defer res.Body.Close()
|
||||
defer func() {
|
||||
if err := res.Body.Close(); err != nil {
|
||||
clientLog.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
clientLog.Debug("Received multisearch response", "code", res.StatusCode, "status", res.Status, "content-length", res.ContentLength)
|
||||
|
||||
|
@ -133,10 +133,14 @@ func (e *GraphiteExecutor) Query(ctx context.Context, dsInfo *models.DataSource,
|
||||
|
||||
func (e *GraphiteExecutor) parseResponse(res *http.Response) ([]TargetResponseDTO, error) {
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
defer res.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if err := res.Body.Close(); err != nil {
|
||||
glog.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if res.StatusCode/100 != 2 {
|
||||
glog.Info("Request failed", "status", res.Status, "body", string(body))
|
||||
|
@ -82,10 +82,13 @@ func (e *InfluxDBExecutor) Query(ctx context.Context, dsInfo *models.DataSource,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
defer func() {
|
||||
if err := resp.Body.Close(); err != nil {
|
||||
glog.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
if resp.StatusCode/100 != 2 {
|
||||
return nil, fmt.Errorf("InfluxDB returned statuscode invalid status code: %s", resp.Status)
|
||||
return nil, fmt.Errorf("InfluxDB returned error status: %s", resp.Status)
|
||||
}
|
||||
|
||||
var response Response
|
||||
|
@ -110,10 +110,14 @@ func (e *OpenTsdbExecutor) parseResponse(query OpenTsdbQuery, res *http.Response
|
||||
queryRes := tsdb.NewQueryResult()
|
||||
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
defer res.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if err := res.Body.Close(); err != nil {
|
||||
plog.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if res.StatusCode/100 != 2 {
|
||||
plog.Info("Request failed", "status", res.Status, "body", string(body))
|
||||
|
@ -173,8 +173,11 @@ func (e *sqlQueryEndpoint) Query(ctx context.Context, dsInfo *models.DataSource,
|
||||
queryResult.Error = e.queryResultTransformer.TransformQueryError(err)
|
||||
return
|
||||
}
|
||||
|
||||
defer rows.Close()
|
||||
defer func() {
|
||||
if err := rows.Close(); err != nil {
|
||||
e.log.Warn("Failed to close rows", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
format := query.Model.Get("format").MustString("time_series")
|
||||
|
||||
|
@ -57,6 +57,9 @@ enable = [
|
||||
# Disabled linters (might want them later)
|
||||
# "unparam"
|
||||
|
||||
[issues]
|
||||
exclude-use-default = false
|
||||
|
||||
# Enable when appropriate
|
||||
# Poorly chosen identifier
|
||||
[[issues.exclude-rules]]
|
||||
@ -112,3 +115,18 @@ text = "Unknwon` is a misspelling of `Unknown"
|
||||
[[issues.exclude-rules]]
|
||||
linters = ["errorlint"]
|
||||
text = "non-wrapping format verb for fmt.Errorf"
|
||||
|
||||
# TODO: Enable
|
||||
[[issues.exclude-rules]]
|
||||
linters = ["stylecheck"]
|
||||
text = "ST1000"
|
||||
|
||||
# TODO: Enable
|
||||
[[issues.exclude-rules]]
|
||||
linters = ["stylecheck"]
|
||||
text = "ST1020"
|
||||
|
||||
# TODO: Enable
|
||||
[[issues.exclude-rules]]
|
||||
linters = ["stylecheck"]
|
||||
text = "ST1021"
|
||||
|
Loading…
Reference in New Issue
Block a user