112 lines
3.3 KiB
Go
112 lines
3.3 KiB
Go
package shorturl
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
"k8s.io/apiserver/pkg/registry/rest"
|
|
"sigs.k8s.io/structured-merge-diff/v6/fieldpath"
|
|
|
|
"github.com/grafana/grafana-app-sdk/k8s/apiserver"
|
|
"github.com/grafana/grafana-app-sdk/logging"
|
|
shorturl "github.com/grafana/grafana/apps/shorturl/pkg/apis/shorturl/v1beta1"
|
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
|
"github.com/grafana/grafana/pkg/services/shorturls"
|
|
)
|
|
|
|
type statusDualWriter struct {
|
|
gv schema.GroupVersion
|
|
status *apiserver.StatusREST
|
|
legacy *legacyStorage
|
|
}
|
|
|
|
var (
|
|
_ rest.Patcher = (*statusDualWriter)(nil)
|
|
_ rest.Storage = (*statusDualWriter)(nil)
|
|
_ rest.ResetFieldsStrategy = (*statusDualWriter)(nil)
|
|
)
|
|
|
|
// Destroy implements rest.Storage.
|
|
func (s *statusDualWriter) Destroy() {}
|
|
|
|
// New implements rest.Storage.
|
|
func (s *statusDualWriter) New() runtime.Object {
|
|
return s.legacy.New()
|
|
}
|
|
|
|
// Get implements rest.Patcher.
|
|
func (s *statusDualWriter) Get(ctx context.Context, name string, options *v1.GetOptions) (runtime.Object, error) {
|
|
return s.legacy.Get(ctx, name, options)
|
|
}
|
|
|
|
// Update implements rest.Patcher.
|
|
func (s *statusDualWriter) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *v1.UpdateOptions) (runtime.Object, bool, error) {
|
|
requester, err := identity.GetRequester(ctx)
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
|
|
shortURL, err := s.legacy.service.GetShortURLByUID(ctx, requester, name)
|
|
if err != nil || shortURL == nil {
|
|
if errors.Is(err, shorturls.ErrShortURLNotFound) || err == nil {
|
|
err = k8serrors.NewNotFound(shorturl.ShortURLKind().GroupVersionResource().GroupResource(), name)
|
|
}
|
|
return nil, false, err
|
|
}
|
|
|
|
// This ignores the incoming and updates it directly
|
|
err = s.legacy.service.UpdateLastSeenAt(ctx, shortURL)
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
|
|
getter := func(getter rest.Getter) (*shorturl.ShortURL, error) {
|
|
obj, err := getter.Get(ctx, name, &v1.GetOptions{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
val, ok := obj.(*shorturl.ShortURL)
|
|
if !ok {
|
|
return nil, fmt.Errorf("expected ShortURL but got %T", obj)
|
|
}
|
|
return val, nil
|
|
}
|
|
|
|
legacy, err := getter(s.legacy)
|
|
if err != nil {
|
|
return nil, false, err // unable to get legacy object
|
|
}
|
|
|
|
unified, err := getter(s.status)
|
|
if err != nil {
|
|
logging.FromContext(ctx).Warn("unable to read unified status", "error", err)
|
|
return legacy, false, nil
|
|
}
|
|
|
|
// Use the same status from legacy in unified
|
|
unified.Status = legacy.Status
|
|
|
|
_, _, err = s.status.Update(ctx, name, rest.DefaultUpdatedObjectInfo(unified), createValidation, updateValidation, false, options)
|
|
if err != nil {
|
|
logging.FromContext(ctx).Warn("error updating unified status", "error", err)
|
|
}
|
|
|
|
return legacy, false, err
|
|
}
|
|
|
|
// GetResetFields implements rest.ResetFieldsStrategy
|
|
func (s *statusDualWriter) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set {
|
|
fields := map[fieldpath.APIVersion]*fieldpath.Set{
|
|
fieldpath.APIVersion(s.gv.String()): fieldpath.NewSet(
|
|
fieldpath.MakePathOrDie("spec"),
|
|
fieldpath.MakePathOrDie("metadata"),
|
|
),
|
|
}
|
|
return fields
|
|
}
|