mirror of https://github.com/grafana/grafana
commit
c9c18717f5
@ -0,0 +1 @@ |
||||
package auth |
@ -1,7 +1,30 @@ |
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= |
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= |
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= |
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= |
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= |
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= |
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= |
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= |
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= |
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= |
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= |
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= |
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= |
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= |
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= |
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= |
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= |
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240520151616-dc85e6b867a5 h1:Q2RxlXqh1cgzzUgV261vBO2jI5R/3DD1J2pM0nI4NhU= |
||||
google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= |
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= |
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= |
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= |
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= |
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= |
||||
k8s.io/apimachinery v0.29.3 h1:2tbx+5L7RNvqJjn7RIuIKu9XTsIZ9Z5wX2G22XAa5EU= |
||||
k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= |
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= |
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= |
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= |
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= |
||||
|
@ -1,16 +1,16 @@ |
||||
package resource_test |
||||
package api_test |
||||
|
||||
import ( |
||||
"testing" |
||||
|
||||
"github.com/stretchr/testify/require" |
||||
|
||||
"github.com/grafana/grafana/pkg/services/store/resource" |
||||
"github.com/grafana/grafana/pkg/storage/api" |
||||
) |
||||
|
||||
func TestResourceModels(t *testing.T) { |
||||
t.Run("key namespaced path", func(t *testing.T) { |
||||
key := &resource.Key{} |
||||
key := &api.ResourceKey{} |
||||
require.Equal(t, "__cluster__", key.NamespacedPath()) |
||||
|
||||
key.Namespace = "ns" |
@ -0,0 +1,196 @@ |
||||
package api |
||||
|
||||
import ( |
||||
"context" |
||||
"encoding/json" |
||||
"fmt" |
||||
"sync/atomic" |
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils" |
||||
"github.com/grafana/grafana/pkg/infra/appcontext" |
||||
"github.com/grafana/grafana/pkg/services/auth/identity" |
||||
) |
||||
|
||||
// Verify that all required fields are set, and the user has permission to set the common metadata fields
|
||||
type EventValidator interface { |
||||
PrepareCreate(ctx context.Context, req *CreateRequest) (*WriteEvent, error) |
||||
PrepareUpdate(ctx context.Context, req *UpdateRequest, current []byte) (*WriteEvent, error) |
||||
} |
||||
|
||||
type EventValidatorOptions struct { |
||||
// Get the next EventID
|
||||
NextEventID func() int64 |
||||
|
||||
// Check if a user has access to write folders
|
||||
// When this is nil, no resources can have folders configured
|
||||
FolderAccess func(ctx context.Context, user identity.Requester, uid string) bool |
||||
|
||||
// When configured, this will make sure a user is allowed to save to a given origin
|
||||
OriginAccess func(ctx context.Context, user identity.Requester, origin string) bool |
||||
} |
||||
|
||||
type eventValidator struct { |
||||
opts EventValidatorOptions |
||||
} |
||||
|
||||
func NewEventValidator(opts EventValidatorOptions) EventValidator { |
||||
if opts.NextEventID == nil { |
||||
counter := atomic.Int64{} |
||||
opts.NextEventID = func() int64 { |
||||
return counter.Add(1) |
||||
} |
||||
} |
||||
return &eventValidator{opts} |
||||
} |
||||
|
||||
type dummyObject struct { |
||||
metav1.TypeMeta `json:",inline"` |
||||
metav1.ObjectMeta `json:"metadata,omitempty"` |
||||
} |
||||
|
||||
var _ EventValidator = &eventValidator{} |
||||
|
||||
func (v *eventValidator) newEvent(ctx context.Context, key *ResourceKey, value, oldValue []byte) *WriteEvent { |
||||
var err error |
||||
event := &WriteEvent{ |
||||
EventID: v.opts.NextEventID(), |
||||
Key: key, |
||||
Value: value, |
||||
} |
||||
event.Requester, err = appcontext.User(ctx) |
||||
if err != nil { |
||||
return event.BadRequest(err, "unable to get user") |
||||
} |
||||
|
||||
dummy := &dummyObject{} |
||||
err = json.Unmarshal(value, dummy) |
||||
if err != nil { |
||||
return event.BadRequest(err, "error reading json") |
||||
} |
||||
|
||||
obj, err := utils.MetaAccessor(dummy) |
||||
if err != nil { |
||||
return event.BadRequest(err, "invalid object in json") |
||||
} |
||||
if obj.GetUID() == "" { |
||||
return event.BadRequest(nil, "the UID must be set") |
||||
} |
||||
if obj.GetGenerateName() != "" { |
||||
return event.BadRequest(nil, "can not save value with generate name") |
||||
} |
||||
gvk := obj.GetGroupVersionKind() |
||||
if gvk.Kind == "" { |
||||
return event.BadRequest(nil, "expecting resources with a kind in the body") |
||||
} |
||||
if gvk.Version == "" { |
||||
return event.BadRequest(nil, "expecting resources with an apiVersion") |
||||
} |
||||
if gvk.Group != "" && gvk.Group != key.Group { |
||||
return event.BadRequest(nil, "group in key does not match group in the body (%s != %s)", key.Group, gvk.Group) |
||||
} |
||||
if obj.GetName() != key.Name { |
||||
return event.BadRequest(nil, "key name does not match the name in the body") |
||||
} |
||||
if obj.GetNamespace() != key.Namespace { |
||||
return event.BadRequest(nil, "key namespace does not match the namespace in the body") |
||||
} |
||||
folder := obj.GetFolder() |
||||
if folder != "" { |
||||
if v.opts.FolderAccess == nil { |
||||
return event.BadRequest(err, "folders are not supported") |
||||
} else if !v.opts.FolderAccess(ctx, event.Requester, folder) { |
||||
return event.BadRequest(err, "unable to add resource to folder") // 403?
|
||||
} |
||||
} |
||||
origin, err := obj.GetOriginInfo() |
||||
if err != nil { |
||||
return event.BadRequest(err, "invalid origin info") |
||||
} |
||||
if origin != nil && v.opts.OriginAccess != nil { |
||||
if !v.opts.OriginAccess(ctx, event.Requester, origin.Name) { |
||||
return event.BadRequest(err, "not allowed to write resource to origin (%s)", origin.Name) |
||||
} |
||||
} |
||||
event.Object = obj |
||||
|
||||
// This is an update
|
||||
if oldValue != nil { |
||||
dummy := &dummyObject{} |
||||
err = json.Unmarshal(oldValue, dummy) |
||||
if err != nil { |
||||
return event.BadRequest(err, "error reading old json value") |
||||
} |
||||
old, err := utils.MetaAccessor(dummy) |
||||
if err != nil { |
||||
return event.BadRequest(err, "invalid object inside old json") |
||||
} |
||||
if key.Name != old.GetName() { |
||||
return event.BadRequest(err, "the old value has a different name (%s != %s)", key.Name, old.GetName()) |
||||
} |
||||
|
||||
// Can not change creation timestamps+user
|
||||
if obj.GetCreatedBy() != old.GetCreatedBy() { |
||||
return event.BadRequest(err, "can not change the created by metadata (%s != %s)", obj.GetCreatedBy(), old.GetCreatedBy()) |
||||
} |
||||
if obj.GetCreationTimestamp() != old.GetCreationTimestamp() { |
||||
return event.BadRequest(err, "can not change the CreationTimestamp metadata (%v != %v)", obj.GetCreationTimestamp(), old.GetCreationTimestamp()) |
||||
} |
||||
|
||||
oldFolder := obj.GetFolder() |
||||
if oldFolder != folder { |
||||
event.FolderChanged = true |
||||
} |
||||
event.OldObject = old |
||||
} else if folder != "" { |
||||
event.FolderChanged = true |
||||
} |
||||
return event |
||||
} |
||||
|
||||
func (v *eventValidator) PrepareCreate(ctx context.Context, req *CreateRequest) (*WriteEvent, error) { |
||||
event := v.newEvent(ctx, req.Key, req.Value, nil) |
||||
event.Operation = ResourceOperation_CREATED |
||||
if event.Status != nil { |
||||
return event, nil |
||||
} |
||||
|
||||
// Make sure the created by user is accurate
|
||||
//----------------------------------------
|
||||
val := event.Object.GetCreatedBy() |
||||
if val != "" && val != event.Requester.GetUID().String() { |
||||
return event.BadRequest(nil, "created by annotation does not match: metadata.annotations#"+utils.AnnoKeyCreatedBy), nil |
||||
} |
||||
|
||||
// Create can not have updated properties
|
||||
//----------------------------------------
|
||||
if event.Object.GetUpdatedBy() != "" { |
||||
return event.BadRequest(nil, "unexpected metadata.annotations#"+utils.AnnoKeyCreatedBy), nil |
||||
} |
||||
ts, err := event.Object.GetUpdatedTimestamp() |
||||
if err != nil { |
||||
return event.BadRequest(nil, fmt.Sprintf("invalid timestamp: %s", err)), nil |
||||
} |
||||
if ts != nil { |
||||
return event.BadRequest(nil, "unexpected metadata.annotations#"+utils.AnnoKeyUpdatedTimestamp), nil |
||||
} |
||||
return event, nil |
||||
} |
||||
|
||||
func (v *eventValidator) PrepareUpdate(ctx context.Context, req *UpdateRequest, current []byte) (*WriteEvent, error) { |
||||
event := v.newEvent(ctx, req.Key, req.Value, current) |
||||
event.Operation = ResourceOperation_UPDATED |
||||
if event.Status != nil { |
||||
return event, nil |
||||
} |
||||
|
||||
// Make sure the update user is accurate
|
||||
//----------------------------------------
|
||||
val := event.Object.GetUpdatedBy() |
||||
if val != "" && val != event.Requester.GetUID().String() { |
||||
return event.BadRequest(nil, "created by annotation does not match: metadata.annotations#"+utils.AnnoKeyUpdatedBy), nil |
||||
} |
||||
|
||||
return event, nil |
||||
} |
@ -1,156 +0,0 @@ |
||||
module github.com/grafana/grafana/pkg/storage/server |
||||
|
||||
go 1.21.10 |
||||
|
||||
require ( |
||||
github.com/bwmarrin/snowflake v0.3.0 |
||||
github.com/gorilla/mux v1.8.1 |
||||
github.com/grafana/grafana-plugin-sdk-go v0.234.0 |
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240409140820-518d3341d58f |
||||
github.com/prometheus/client_golang v1.19.0 |
||||
github.com/stretchr/testify v1.9.0 |
||||
go.opentelemetry.io/otel/trace v1.26.0 |
||||
golang.org/x/mod v0.18.0 |
||||
k8s.io/apimachinery v0.29.3 |
||||
k8s.io/apiserver v0.29.2 |
||||
k8s.io/client-go v0.29.3 |
||||
k8s.io/component-base v0.29.2 |
||||
k8s.io/klog/v2 v2.120.1 |
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 |
||||
) |
||||
|
||||
require ( |
||||
github.com/BurntSushi/toml v1.3.2 // indirect |
||||
github.com/NYTimes/gziphandler v1.1.1 // indirect |
||||
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9 // indirect |
||||
github.com/apache/arrow/go/v15 v15.0.2 // indirect |
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect |
||||
github.com/beorn7/perks v1.0.1 // indirect |
||||
github.com/blang/semver/v4 v4.0.0 // indirect |
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect |
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect |
||||
github.com/cheekybits/genny v1.0.0 // indirect |
||||
github.com/chromedp/cdproto v0.0.0-20240426225625-909263490071 // indirect |
||||
github.com/coreos/go-semver v0.3.1 // indirect |
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect |
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect |
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect |
||||
github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5 // indirect |
||||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect |
||||
github.com/evanphx/json-patch v5.6.0+incompatible // indirect |
||||
github.com/fatih/color v1.16.0 // indirect |
||||
github.com/felixge/httpsnoop v1.0.4 // indirect |
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect |
||||
github.com/getkin/kin-openapi v0.124.0 // indirect |
||||
github.com/go-logr/logr v1.4.1 // indirect |
||||
github.com/go-logr/stdr v1.2.2 // indirect |
||||
github.com/go-logr/zapr v1.3.0 // indirect |
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect |
||||
github.com/go-openapi/jsonreference v0.20.4 // indirect |
||||
github.com/go-openapi/swag v0.23.0 // indirect |
||||
github.com/goccy/go-json v0.10.2 // indirect |
||||
github.com/gogo/protobuf v1.3.2 // indirect |
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect |
||||
github.com/golang/protobuf v1.5.4 // indirect |
||||
github.com/google/btree v1.1.2 // indirect |
||||
github.com/google/cel-go v0.17.7 // indirect |
||||
github.com/google/flatbuffers v24.3.25+incompatible // indirect |
||||
github.com/google/gnostic-models v0.6.8 // indirect |
||||
github.com/google/go-cmp v0.6.0 // indirect |
||||
github.com/google/gofuzz v1.2.0 // indirect |
||||
github.com/google/pprof v0.0.0-20240416155748-26353dc0451f // indirect |
||||
github.com/google/uuid v1.6.0 // indirect |
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect |
||||
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect |
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect |
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect |
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect |
||||
github.com/hashicorp/go-hclog v1.6.3 // indirect |
||||
github.com/hashicorp/go-plugin v1.6.1 // indirect |
||||
github.com/hashicorp/yamux v0.1.1 // indirect |
||||
github.com/imdario/mergo v0.3.16 // indirect |
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect |
||||
github.com/invopop/yaml v0.3.1 // indirect |
||||
github.com/jonboulle/clockwork v0.4.0 // indirect |
||||
github.com/josharian/intern v1.0.0 // indirect |
||||
github.com/json-iterator/go v1.1.12 // indirect |
||||
github.com/jszwedko/go-datemath v0.1.1-0.20230526204004-640a500621d6 // indirect |
||||
github.com/klauspost/compress v1.17.8 // indirect |
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect |
||||
github.com/magefile/mage v1.15.0 // indirect |
||||
github.com/mailru/easyjson v0.7.7 // indirect |
||||
github.com/mattetti/filebuffer v1.0.1 // indirect |
||||
github.com/mattn/go-colorable v0.1.13 // indirect |
||||
github.com/mattn/go-isatty v0.0.20 // indirect |
||||
github.com/mattn/go-runewidth v0.0.15 // indirect |
||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect |
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect |
||||
github.com/modern-go/reflect2 v1.0.2 // indirect |
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect |
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect |
||||
github.com/oklog/run v1.1.0 // indirect |
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect |
||||
github.com/perimeterx/marshmallow v1.1.5 // indirect |
||||
github.com/pierrec/lz4/v4 v4.1.21 // indirect |
||||
github.com/pkg/errors v0.9.1 // indirect |
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect |
||||
github.com/prometheus/client_model v0.6.1 // indirect |
||||
github.com/prometheus/common v0.53.0 // indirect |
||||
github.com/prometheus/procfs v0.14.0 // indirect |
||||
github.com/rivo/uniseg v0.4.7 // indirect |
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect |
||||
github.com/sirupsen/logrus v1.9.3 // indirect |
||||
github.com/smartystreets/goconvey v1.6.4 // indirect |
||||
github.com/spf13/cobra v1.8.0 // indirect |
||||
github.com/spf13/pflag v1.0.5 // indirect |
||||
github.com/stoewer/go-strcase v1.3.0 // indirect |
||||
github.com/stretchr/objx v0.5.2 // indirect |
||||
github.com/ugorji/go/codec v1.2.11 // indirect |
||||
github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8 // indirect |
||||
github.com/unknwon/com v1.0.1 // indirect |
||||
github.com/unknwon/log v0.0.0-20200308114134-929b1006e34a // indirect |
||||
github.com/urfave/cli v1.22.15 // indirect |
||||
github.com/zeebo/xxh3 v1.0.2 // indirect |
||||
go.etcd.io/etcd/api/v3 v3.5.10 // indirect |
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.10 // indirect |
||||
go.etcd.io/etcd/client/v3 v3.5.10 // indirect |
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 // indirect |
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.51.0 // indirect |
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 // indirect |
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.26.0 // indirect |
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.20.0 // indirect |
||||
go.opentelemetry.io/otel v1.26.0 // indirect |
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect |
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 // indirect |
||||
go.opentelemetry.io/otel/metric v1.26.0 // indirect |
||||
go.opentelemetry.io/otel/sdk v1.26.0 // indirect |
||||
go.opentelemetry.io/proto/otlp v1.2.0 // indirect |
||||
go.uber.org/multierr v1.11.0 // indirect |
||||
go.uber.org/zap v1.26.0 // indirect |
||||
golang.org/x/crypto v0.24.0 // indirect |
||||
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect |
||||
golang.org/x/net v0.26.0 // indirect |
||||
golang.org/x/oauth2 v0.20.0 // indirect |
||||
golang.org/x/sync v0.7.0 // indirect |
||||
golang.org/x/sys v0.21.0 // indirect |
||||
golang.org/x/term v0.21.0 // indirect |
||||
golang.org/x/text v0.16.0 // indirect |
||||
golang.org/x/time v0.5.0 // indirect |
||||
golang.org/x/tools v0.22.0 // indirect |
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect |
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect |
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6 // indirect |
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240520151616-dc85e6b867a5 // indirect |
||||
google.golang.org/grpc v1.64.0 // indirect |
||||
google.golang.org/protobuf v1.34.1 // indirect |
||||
gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect |
||||
gopkg.in/inf.v0 v0.9.1 // indirect |
||||
gopkg.in/yaml.v2 v2.4.0 // indirect |
||||
gopkg.in/yaml.v3 v3.0.1 // indirect |
||||
k8s.io/api v0.29.3 // indirect |
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect |
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0 // indirect |
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect |
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect |
||||
sigs.k8s.io/yaml v1.3.0 // indirect |
||||
) |
Loading…
Reference in new issue