with context
This commit is contained in:
@@ -42,7 +42,7 @@ func (r *converter) asDataSource(ds *datasources.DataSource) (*datasourceV0.Data
|
|||||||
Generation: int64(ds.Version),
|
Generation: int64(ds.Version),
|
||||||
},
|
},
|
||||||
Spec: datasourceV0.UnstructuredSpec{},
|
Spec: datasourceV0.UnstructuredSpec{},
|
||||||
Secure: ToInlineSecureValues(ds.Type, ds.UID, maps.Keys(ds.SecureJsonData)),
|
Secure: ToInlineSecureValues(ds.UID, maps.Keys(ds.SecureJsonData)),
|
||||||
}
|
}
|
||||||
obj.UID = gapiutil.CalculateClusterWideUID(obj)
|
obj.UID = gapiutil.CalculateClusterWideUID(obj)
|
||||||
obj.Spec.SetTitle(ds.Name).
|
obj.Spec.SetTitle(ds.Name).
|
||||||
@@ -82,18 +82,11 @@ func (r *converter) asDataSource(ds *datasources.DataSource) (*datasourceV0.Data
|
|||||||
|
|
||||||
// ToInlineSecureValues converts secure json into InlineSecureValues with reference names
|
// ToInlineSecureValues converts secure json into InlineSecureValues with reference names
|
||||||
// The names are predictable and can be used while we implement dual writing for secrets
|
// The names are predictable and can be used while we implement dual writing for secrets
|
||||||
func ToInlineSecureValues(dsType string, dsUID string, keys iter.Seq[string]) common.InlineSecureValues {
|
func ToInlineSecureValues(dsUID string, keys iter.Seq[string]) common.InlineSecureValues {
|
||||||
values := make(common.InlineSecureValues)
|
values := make(common.InlineSecureValues)
|
||||||
for k := range keys {
|
for k := range keys {
|
||||||
h := sha256.New()
|
|
||||||
h.Write([]byte(dsType)) // plugin id
|
|
||||||
h.Write([]byte("|"))
|
|
||||||
h.Write([]byte(dsUID)) // unique identifier
|
|
||||||
h.Write([]byte("|"))
|
|
||||||
h.Write([]byte(k)) // property name
|
|
||||||
n := hex.EncodeToString(h.Sum(nil))
|
|
||||||
values[k] = common.InlineSecureValue{
|
values[k] = common.InlineSecureValue{
|
||||||
Name: "ds-" + n[0:10], // predictable name for dual writing
|
Name: getLegacySecureValueName(dsUID, k),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(values) == 0 {
|
if len(values) == 0 {
|
||||||
@@ -102,6 +95,15 @@ func ToInlineSecureValues(dsType string, dsUID string, keys iter.Seq[string]) co
|
|||||||
return values
|
return values
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getLegacySecureValueName(dsUID string, key string) string {
|
||||||
|
h := sha256.New()
|
||||||
|
h.Write([]byte(dsUID)) // unique identifier
|
||||||
|
h.Write([]byte("|"))
|
||||||
|
h.Write([]byte(key)) // property name
|
||||||
|
n := hex.EncodeToString(h.Sum(nil))
|
||||||
|
return "ds-" + n[0:10] // predictable name for dual writing
|
||||||
|
}
|
||||||
|
|
||||||
func (r *converter) toAddCommand(ds *datasourceV0.DataSource) (*datasources.AddDataSourceCommand, error) {
|
func (r *converter) toAddCommand(ds *datasourceV0.DataSource) (*datasources.AddDataSourceCommand, error) {
|
||||||
if r.group != "" && ds.APIVersion != "" && !strings.HasPrefix(ds.APIVersion, r.group) {
|
if r.group != "" && ds.APIVersion != "" && !strings.HasPrefix(ds.APIVersion, r.group) {
|
||||||
return nil, fmt.Errorf("expecting APIGroup: %s", r.group)
|
return nil, fmt.Errorf("expecting APIGroup: %s", r.group)
|
||||||
|
|||||||
@@ -11,9 +11,11 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
|
|
||||||
|
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
||||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||||
"github.com/grafana/grafana/pkg/apis/datasource/v0alpha1"
|
"github.com/grafana/grafana/pkg/apis/datasource/v0alpha1"
|
||||||
"github.com/grafana/grafana/pkg/infra/metrics/metricutil"
|
"github.com/grafana/grafana/pkg/infra/metrics/metricutil"
|
||||||
|
"github.com/grafana/grafana/pkg/storage/legacysql/dualwrite"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -90,6 +92,20 @@ func (s *legacyStorage) Create(ctx context.Context, obj runtime.Object, createVa
|
|||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("expected a datasource object")
|
return nil, fmt.Errorf("expected a datasource object")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify the secure value commands
|
||||||
|
for _, v := range ds.Secure {
|
||||||
|
if v.Create.IsZero() {
|
||||||
|
return nil, fmt.Errorf("secure values must use create when creating a new datasource")
|
||||||
|
}
|
||||||
|
if v.Remove {
|
||||||
|
return nil, fmt.Errorf("secure values can not use remove when creating a new datasource")
|
||||||
|
}
|
||||||
|
if v.Name != "" {
|
||||||
|
return nil, fmt.Errorf("secure values can not specify a name when creating a new datasource")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return s.datasources.CreateDataSource(ctx, ds)
|
return s.datasources.CreateDataSource(ctx, ds)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,6 +138,25 @@ func (s *legacyStorage) Update(ctx context.Context, name string, objInfo rest.Up
|
|||||||
return nil, false, fmt.Errorf("expected a datasource object (old)")
|
return nil, false, fmt.Errorf("expected a datasource object (old)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Expose any secure value changes to the dual writer
|
||||||
|
var secureChanges common.InlineSecureValues
|
||||||
|
for k, v := range ds.Secure {
|
||||||
|
if v.Remove || v.Create != "" {
|
||||||
|
if secureChanges == nil {
|
||||||
|
secureChanges = make(common.InlineSecureValues)
|
||||||
|
}
|
||||||
|
secureChanges[k] = v
|
||||||
|
dualwrite.SetUpdatedSecureValues(ctx, ds.Secure)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The legacy store must use fixed names generated by the internal system
|
||||||
|
// we can not support external shared secrets when using the SQL backing for datasources
|
||||||
|
validName := getLegacySecureValueName(name, k)
|
||||||
|
if v.Name != validName {
|
||||||
|
return nil, false, fmt.Errorf("invalid secure value name %q, expected %q", v.Name, validName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Keep all the old secure values
|
// Keep all the old secure values
|
||||||
if len(oldDS.Secure) > 0 {
|
if len(oldDS.Secure) > 0 {
|
||||||
for k, v := range oldDS.Secure {
|
for k, v := range oldDS.Secure {
|
||||||
|
|||||||
@@ -16,14 +16,15 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
|
|
||||||
"github.com/grafana/grafana-app-sdk/logging"
|
"github.com/grafana/grafana-app-sdk/logging"
|
||||||
|
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
||||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||||
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
|
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_ grafanarest.Storage = (*dualWriter)(nil)
|
_ grafanarest.Storage = (*dualWriter)(nil)
|
||||||
tracer = otel.Tracer("github.com/grafana/grafana/pkg/storage/legacysql/dualwrite")
|
|
||||||
|
tracer = otel.Tracer("github.com/grafana/grafana/pkg/storage/legacysql/dualwrite")
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -385,6 +386,7 @@ func (d *dualWriter) Update(ctx context.Context, name string, objInfo rest.Updat
|
|||||||
// but legacy failed, the user would get a failure, but see the update did apply to the source
|
// but legacy failed, the user would get a failure, but see the update did apply to the source
|
||||||
// of truth, and be less likely to retry to save (and get the stores in sync again)
|
// of truth, and be less likely to retry to save (and get the stores in sync again)
|
||||||
|
|
||||||
|
ctx = addToContext(ctx)
|
||||||
legacyInfo := objInfo
|
legacyInfo := objInfo
|
||||||
legacyForceCreate := forceAllowCreate
|
legacyForceCreate := forceAllowCreate
|
||||||
unifiedInfo := objInfo
|
unifiedInfo := objInfo
|
||||||
@@ -516,9 +518,10 @@ func (d *dualWriter) ConvertToTable(ctx context.Context, object runtime.Object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
type wrappedUpdateInfo struct {
|
type wrappedUpdateInfo struct {
|
||||||
objInfo rest.UpdatedObjectInfo
|
objInfo rest.UpdatedObjectInfo
|
||||||
legacyLabels map[string]string
|
legacyLabels map[string]string
|
||||||
legacyAnnotations map[string]string
|
legacyAnnotations map[string]string
|
||||||
|
updatedSecureValues common.InlineSecureValues
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preconditions implements rest.UpdatedObjectInfo.
|
// Preconditions implements rest.UpdatedObjectInfo.
|
||||||
@@ -561,6 +564,13 @@ func (w *wrappedUpdateInfo) UpdatedObject(ctx context.Context, oldObj runtime.Ob
|
|||||||
|
|
||||||
meta.SetResourceVersion("")
|
meta.SetResourceVersion("")
|
||||||
meta.SetUID("")
|
meta.SetUID("")
|
||||||
|
|
||||||
|
if w.updatedSecureValues != nil {
|
||||||
|
if err = meta.SetSecureValues(w.updatedSecureValues); err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to set secure values on duplicate object %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return obj, err
|
return obj, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user