grafana/pkg/tsdb/postgres/locker.go
ying-jeanne c57047a420
Postgres: allow providing TLS/SSL certificates as text in addition to file paths (#30353)
* postgres SSL certification

* add back the UI to configure SSL Authentication files by file path

* add backend logic

* correct unittest

* mini changes

* Update public/app/plugins/datasource/postgres/config_ctrl.ts

Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>

* Update public/app/plugins/datasource/postgres/partials/config.html

Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>

* mutex

* check file exist before remove

* change permission

* change default configuremethod to file-path

* Update public/app/plugins/datasource/postgres/partials/config.html

Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>

* Update public/app/plugins/datasource/postgres/partials/config.html

Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>

* Update public/app/plugins/datasource/postgres/partials/config.html

Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>

* Update public/app/plugins/datasource/postgres/partials/config.html

Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>

* rename sslconfiguremethod to sslconfigurationmethod

* frontend update

* solve comments

* Postgres: Convert tests to stdlib

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Postgres: Be consistent about TLS/SSL terminology

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* fix init inconsistancy

* Fix tests

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* naming convention

* Fix tests

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Fix tests

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Undo change

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Fix TLS issue

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Fix tests

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Fix tests

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* change permissions

* Fix data source field names

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Clean up HTML

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Improve popover text

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Fix SSL input bug

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Undo unnecessary change

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Clean up backend code

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Fix build

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* More consistent naming

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Clean up code

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Enforce certificate file permissions

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* add settings

* Undo changes

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* fix windows file path

* PostgresDataSource: Fix mutex usage

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Fix tests

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Update pkg/tsdb/postgres/postgres.go

Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>

* Apply suggestions from code review

Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>

* fix compilation

* fix unittest

* Apply suggestions from code review

Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>

* Apply suggestions from code review

Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>

* mock function

* change kmutex package

* add kmutex into middleware

* lock connection file per datasource

* add unittest regarding concurrency

* version should be equal

* adding unittest

* fix the loop

* fix unitest

* fix postgres unittst

* remove comments

* move dataPath from arg to tlsManager struct field

* Use DecryptedValues method

Use cached decrypted values instead of
using secure json data decrypt which will
decrypt unchanged values over and over again.

* remove unneeded mutex in tests and cleanup tests

* fix the lint

Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>
Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
2021-02-23 22:10:55 +01:00

86 lines
2.1 KiB
Go

package postgres
import (
"fmt"
"sync"
)
// locker is a named reader/writer mutual exclusion lock.
// The lock for each particular key can be held by an arbitrary number of readers or a single writer.
type locker struct {
locks map[interface{}]*sync.RWMutex
locksRW *sync.RWMutex
}
func newLocker() *locker {
return &locker{
locks: make(map[interface{}]*sync.RWMutex),
locksRW: new(sync.RWMutex),
}
}
// Lock locks named rw mutex with specified key for writing.
// If the lock with the same key is already locked for reading or writing,
// Lock blocks until the lock is available.
func (lkr *locker) Lock(key interface{}) {
lk, ok := lkr.getLock(key)
if !ok {
lk = lkr.newLock(key)
}
lk.Lock()
}
// Unlock unlocks named rw mutex with specified key for writing. It is a run-time error if rw is
// not locked for writing on entry to Unlock.
func (lkr *locker) Unlock(key interface{}) {
lk, ok := lkr.getLock(key)
if !ok {
panic(fmt.Errorf("lock for key '%s' not initialized", key))
}
lk.Unlock()
}
// RLock locks named rw mutex with specified key for reading.
//
// It should not be used for recursive read locking for the same key; a blocked Lock
// call excludes new readers from acquiring the lock. See the
// documentation on the golang RWMutex type.
func (lkr *locker) RLock(key interface{}) {
lk, ok := lkr.getLock(key)
if !ok {
lk = lkr.newLock(key)
}
lk.RLock()
}
// RUnlock undoes a single RLock call for specified key;
// it does not affect other simultaneous readers of locker for specified key.
// It is a run-time error if locker for specified key is not locked for reading
func (lkr *locker) RUnlock(key interface{}) {
lk, ok := lkr.getLock(key)
if !ok {
panic(fmt.Errorf("lock for key '%s' not initialized", key))
}
lk.RUnlock()
}
func (lkr *locker) newLock(key interface{}) *sync.RWMutex {
lkr.locksRW.Lock()
defer lkr.locksRW.Unlock()
if lk, ok := lkr.locks[key]; ok {
return lk
}
lk := new(sync.RWMutex)
lkr.locks[key] = lk
return lk
}
func (lkr *locker) getLock(key interface{}) (*sync.RWMutex, bool) {
lkr.locksRW.RLock()
defer lkr.locksRW.RUnlock()
lock, ok := lkr.locks[key]
return lock, ok
}