diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index ce41a664..fb45d2be 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -20,7 +20,7 @@ jobs: chmod +x /usr/local/bin/kubectl-kuttl - name: create kind cluster - uses: helm/kind-action@v1.10.0 + uses: helm/kind-action@v1.12.0 - name: set up helm uses: azure/setup-helm@v4 diff --git a/Makefile b/Makefile index e3e78b1a..806f8bb3 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ export GO111MODULE := on SHELL=/usr/bin/env bash -ENVTEST_K8S_VERSION = 1.29.0 +ENVTEST_K8S_VERSION = 1.31.0 now := $(shell date -u +%Y-%m-%dT%H:%M:%S%z) gitBranch := $(shell git rev-parse --abbrev-ref HEAD) @@ -191,7 +191,7 @@ mv "$$(echo "$(1)" | sed "s/-$(3)$$//")" $(1) ;\ endef ENVTEST ?= $(LOCALBIN)/setup-envtest-$(ENVTEST_VERSION) -ENVTEST_VERSION ?= release-0.17 +ENVTEST_VERSION ?= release-0.19 .PHONY: envtest envtest: $(ENVTEST) ## Download setup-envtest locally if necessary. diff --git a/cmd/jetstream-controller/main.go b/cmd/jetstream-controller/main.go index 62638feb..32678f32 100644 --- a/cmd/jetstream-controller/main.go +++ b/cmd/jetstream-controller/main.go @@ -18,6 +18,11 @@ import ( "errors" "flag" "fmt" + "os" + "os/signal" + "syscall" + "time" + "github.com/nats-io/nack/controllers/jetstream" "github.com/nats-io/nack/internal/controller" jetstreamnatsiov1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" @@ -29,12 +34,9 @@ import ( clientgoscheme "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" klog "k8s.io/klog/v2" - "os" - "os/signal" + ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/healthz" - "syscall" - "time" ) var ( @@ -155,7 +157,6 @@ func run() error { } func runControlLoop(config *rest.Config, natsCfg *controller.NatsConfig, controllerCfg *controller.Config) error { - // Setup scheme scheme := runtime.NewScheme() utilruntime.Must(clientgoscheme.AddToScheme(scheme)) diff --git a/controllers/jetstream/consumer.go b/controllers/jetstream/consumer.go index 8dba6a89..54024f3c 100644 --- a/controllers/jetstream/consumer.go +++ b/controllers/jetstream/consumer.go @@ -77,7 +77,7 @@ func (c *Controller) processConsumerObject(cns *apis.Consumer, jsm jsmClientFunc // Write this to the cacheDir accDir := filepath.Join(c.cacheDir, ns, spec.Account) - if err := os.MkdirAll(accDir, 0755); err != nil { + if err := os.MkdirAll(accDir, 0o755); err != nil { return err } @@ -101,7 +101,7 @@ func (c *Controller) processConsumerObject(cns *apis.Consumer, jsm jsmClientFunc // Write the user credentials to the cache dir. accDir := filepath.Join(c.cacheDir, ns, spec.Account) - if err := os.MkdirAll(accDir, 0755); err != nil { + if err := os.MkdirAll(accDir, 0o755); err != nil { return err } for k, v := range secret.Data { @@ -352,7 +352,7 @@ func consumerSpecToOpts(spec apis.ConsumerSpec) ([]jsm.ConsumerOption, error) { opts = append(opts, jsm.AcknowledgeExplicit()) case "": default: - return nil, fmt.Errorf("invalid value for 'ackPolicy': '%s'. Must be one of 'none', 'all', 'explicit'.", spec.AckPolicy) + return nil, fmt.Errorf("invalid value for 'ackPolicy': '%s'. Must be one of 'none', 'all', 'explicit'", spec.AckPolicy) } if spec.AckWait != "" { @@ -370,7 +370,7 @@ func consumerSpecToOpts(spec apis.ConsumerSpec) ([]jsm.ConsumerOption, error) { opts = append(opts, jsm.ReplayAsReceived()) case "": default: - return nil, fmt.Errorf("invalid value for 'replayPolicy': '%s'. Must be one of 'instant', 'original'.", spec.ReplayPolicy) + return nil, fmt.Errorf("invalid value for 'replayPolicy': '%s'. Must be one of 'instant', 'original'", spec.ReplayPolicy) } if spec.SampleFreq != "" { diff --git a/controllers/jetstream/controller.go b/controllers/jetstream/controller.go index 8c009537..68c7d458 100644 --- a/controllers/jetstream/controller.go +++ b/controllers/jetstream/controller.go @@ -97,11 +97,11 @@ type Controller struct { strLister listers.StreamLister strSynced cache.InformerSynced - strQueue workqueue.RateLimitingInterface + strQueue workqueue.TypedRateLimitingInterface[any] cnsLister listers.ConsumerLister cnsSynced cache.InformerSynced - cnsQueue workqueue.RateLimitingInterface + cnsQueue workqueue.TypedRateLimitingInterface[any] accLister listers.AccountLister @@ -136,8 +136,8 @@ func NewController(opt Options) *Controller { } ji := opt.JetstreamIface.JetstreamV1beta2() - streamQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "Streams") - consumerQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "Consumers") + streamQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultTypedControllerRateLimiter[any](), "Streams") + consumerQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultTypedControllerRateLimiter[any](), "Consumers") streamInformer.Informer().AddEventHandler( eventHandlers( @@ -155,6 +155,7 @@ func NewController(opt Options) *Controller { if err != nil { panic(err) } + defer os.RemoveAll(cacheDir) return &Controller{ ctx: opt.Ctx, @@ -179,7 +180,6 @@ func NewController(opt Options) *Controller { } func (c *Controller) Run() error { - // Connect to NATS. opts := make([]nats.Option, 0) // Always attempt to have a connection to NATS. @@ -447,7 +447,7 @@ func getStorageType(s string) (jsmapi.StorageType, error) { } } -func enqueueWork(q workqueue.RateLimitingInterface, item interface{}) (err error) { +func enqueueWork(q workqueue.TypedRateLimitingInterface[any], item interface{}) (err error) { key, err := cache.MetaNamespaceKeyFunc(item) if err != nil { return fmt.Errorf("failed to enqueue work: %w", err) @@ -457,10 +457,12 @@ func enqueueWork(q workqueue.RateLimitingInterface, item interface{}) (err error return nil } -type jsmClientFunc func(*natsContext) (jsmClient, error) -type processorFunc func(ns, name string, jmsClient jsmClientFunc) error +type ( + jsmClientFunc func(*natsContext) (jsmClient, error) + processorFunc func(ns, name string, jmsClient jsmClientFunc) error +) -func processQueueNext(q workqueue.RateLimitingInterface, jmsClient jsmClientFunc, process processorFunc) { +func processQueueNext(q workqueue.TypedRateLimitingInterface[any], jmsClient jsmClientFunc, process processorFunc) { item, shutdown := q.Get() if shutdown { return @@ -530,7 +532,7 @@ func shouldEnqueue(prevObj, nextObj interface{}) bool { return markedDelete || specChanged } -func eventHandlers(q workqueue.RateLimitingInterface) cache.ResourceEventHandlerFuncs { +func eventHandlers(q workqueue.TypedRateLimitingInterface[any]) cache.ResourceEventHandlerFuncs { return cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { if err := enqueueWork(q, obj); err != nil { diff --git a/controllers/jetstream/controller_test.go b/controllers/jetstream/controller_test.go index aae4d9b6..0b85f461 100644 --- a/controllers/jetstream/controller_test.go +++ b/controllers/jetstream/controller_test.go @@ -63,7 +63,7 @@ func TestGetStorageType(t *testing.T) { func TestEnqueueWork(t *testing.T) { t.Parallel() - limiter := workqueue.DefaultControllerRateLimiter() + limiter := workqueue.DefaultTypedControllerRateLimiter[any]() q := workqueue.NewNamedRateLimitingQueue(limiter, "StreamsTest") defer q.ShutDown() @@ -97,7 +97,7 @@ func TestProcessQueueNext(t *testing.T) { t.Run("bad item key", func(t *testing.T) { t.Parallel() - limiter := workqueue.DefaultControllerRateLimiter() + limiter := workqueue.DefaultTypedControllerRateLimiter[any]() q := workqueue.NewNamedRateLimitingQueue(limiter, "StreamsTest") defer q.ShutDown() @@ -122,7 +122,7 @@ func TestProcessQueueNext(t *testing.T) { t.Run("process error", func(t *testing.T) { t.Parallel() - limiter := workqueue.DefaultControllerRateLimiter() + limiter := workqueue.DefaultTypedControllerRateLimiter[any]() q := workqueue.NewNamedRateLimitingQueue(limiter, "StreamsTest") defer q.ShutDown() @@ -156,7 +156,7 @@ func TestProcessQueueNext(t *testing.T) { t.Run("process ok", func(t *testing.T) { t.Parallel() - limiter := workqueue.DefaultControllerRateLimiter() + limiter := workqueue.DefaultTypedControllerRateLimiter[any]() q := workqueue.NewNamedRateLimitingQueue(limiter, "StreamsTest") defer q.ShutDown() diff --git a/controllers/jetstream/stream.go b/controllers/jetstream/stream.go index a340b88f..0542b7c8 100644 --- a/controllers/jetstream/stream.go +++ b/controllers/jetstream/stream.go @@ -23,7 +23,6 @@ import ( "time" jsm "github.com/nats-io/jsm.go" - "github.com/nats-io/jsm.go/api" jsmapi "github.com/nats-io/jsm.go/api" apis "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" typed "github.com/nats-io/nack/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2" @@ -331,9 +330,9 @@ func createStream(ctx context.Context, c jsmClient, spec apis.StreamSpec) (err e switch spec.Compression { case "s2": - opts = append(opts, jsm.Compression(api.S2Compression)) + opts = append(opts, jsm.Compression(jsmapi.S2Compression)) case "none": - opts = append(opts, jsm.Compression(api.NoCompression)) + opts = append(opts, jsm.Compression(jsmapi.NoCompression)) } if spec.NoAck { @@ -397,7 +396,7 @@ func createStream(ctx context.Context, c jsmClient, spec apis.StreamSpec) (err e } if spec.SubjectTransform != nil { - opts = append(opts, func(o *api.StreamConfig) error { + opts = append(opts, func(o *jsmapi.StreamConfig) error { o.SubjectTransform = &jsmapi.SubjectTransformConfig{ Source: spec.SubjectTransform.Source, Destination: spec.SubjectTransform.Dest, @@ -533,9 +532,9 @@ func updateStream(ctx context.Context, c jsmClient, spec apis.StreamSpec) (err e switch spec.Compression { case "s2": - config.Compression = api.S2Compression + config.Compression = jsmapi.S2Compression case "none": - config.Compression = api.NoCompression + config.Compression = jsmapi.NoCompression } return js.UpdateConfiguration(config) diff --git a/deploy/crds.yml b/deploy/crds.yml index bcfb9a13..6d5a8bc9 100644 --- a/deploy/crds.yml +++ b/deploy/crds.yml @@ -1013,3 +1013,214 @@ spec: file: description: Credentials file, generated with github.com/nats-io/nsc tool. type: string +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: keyvalues.jetstream.nats.io +spec: + group: jetstream.nats.io + scope: Namespaced + names: + kind: KeyValue + singular: keyvalue + plural: keyvalues + shortNames: + - kv + versions: + - name: v1beta2 + served: true + storage: true + subresources: + status: {} + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + name: + description: A unique name for the Key/Value store. + type: string + description: + description: The description of the Key/Value store. + type: string + maxValueSize: + description: The maximum size of a value in bytes. + type: integer + history: + description: The number of historical values to keep per key. + type: integer + ttl: + description: The time expiry for keys. + type: string + maxBytes: + description: The maximum size of the Key/Value store in bytes. + type: integer + storage: + description: The storage backend to use for the Key/Value store. + type: string + enum: + - file + - memory + replicas: + description: The number of replicas to keep for the Key/Value store in clustered JetStream. + type: integer + minimum: 1 + maximum: 5 + placement: + description: The Key/Value store placement via tags or cluster name. + type: object + properties: + cluster: + type: string + tags: + type: array + items: + type: string + republish: + description: Republish configuration for the Key/Value store. + type: object + properties: + destination: + type: string + description: Messages will be additionally published to this subject after store. + source: + type: string + description: Messages will be published from this subject to the destination subject. + mirror: + description: A Key/Value store mirror. + type: object + properties: + name: + type: string + optStartSeq: + type: integer + optStartTime: + description: Time format must be RFC3339. + type: string + filterSubject: + type: string + externalApiPrefix: + type: string + externalDeliverPrefix: + type: string + subjectTransforms: + description: List of subject transforms for this mirror. + type: array + items: + description: A subject transform pair. + type: object + properties: + source: + description: Source subject. + type: string + dest: + description: Destination subject. + type: string + compression: + description: Key/Value store compression. + type: boolean + sources: + description: A Key/Value store's sources. + type: array + items: + type: object + properties: + name: + type: string + optStartSeq: + type: integer + optStartTime: + description: Time format must be RFC3339. + type: string + filterSubject: + type: string + externalApiPrefix: + type: string + externalDeliverPrefix: + type: string + subjectTransforms: + description: List of subject transforms for this mirror. + type: array + items: + description: A subject transform pair. + type: object + properties: + source: + description: Source subject. + type: string + dest: + description: Destination subject. + type: string + servers: + description: A list of servers for creating stream + type: array + items: + type: string + default: [] + creds: + description: NATS user credentials for connecting to servers. Please make sure your controller has mounted the cerds on its path. + type: string + default: '' + nkey: + description: NATS user NKey for connecting to servers. + type: string + default: '' + tls: + description: A client's TLS certs and keys. + type: object + properties: + clientCert: + description: A client's cert filepath. Should be mounted. + type: string + clientKey: + description: A client's key filepath. Should be mounted. + type: string + rootCas: + description: A list of filepaths to CAs. Should be mounted. + type: array + items: + type: string + account: + description: Name of the account to which the Stream belongs. + type: string + pattern: '^[^.*>]*$' + preventDelete: + description: When true, the managed Stream will not be deleted when the resource is deleted + type: boolean + default: false + preventUpdate: + description: When true, the managed Stream will not be updated when the resource is updated + type: boolean + default: false + status: + type: object + properties: + observedGeneration: + type: integer + conditions: + type: array + items: + type: object + properties: + type: + type: string + status: + type: string + lastTransitionTime: + type: string + reason: + type: string + message: + type: string + additionalPrinterColumns: + - name: State + type: string + description: The current state of the Key/Value store. + jsonPath: .status.conditions[?(@.type == 'Ready')].reason + - name: Key/Value Store Name + type: string + description: The name of the Key/Value store. + jsonPath: .spec.name \ No newline at end of file diff --git a/deploy/rbac.yml b/deploy/rbac.yml index 388afb73..789e4043 100644 --- a/deploy/rbac.yml +++ b/deploy/rbac.yml @@ -31,6 +31,8 @@ rules: resources: - streams - streams/status + - keyvalues + - keyvalues/status - consumers - consumers/status - streamtemplates @@ -48,6 +50,7 @@ rules: - jetstream.nats.io resources: - streams/finalizers + - keyvalues/finalizers - consumers/finalizers - accounts/finalizers verbs: diff --git a/go.mod b/go.mod index 6d8231ed..3ceacd34 100644 --- a/go.mod +++ b/go.mod @@ -1,26 +1,27 @@ module github.com/nats-io/nack -go 1.23 +go 1.23.0 -toolchain go1.23.2 +toolchain go1.23.4 require ( github.com/fsnotify/fsnotify v1.8.0 + github.com/go-logr/logr v1.4.2 github.com/nats-io/jsm.go v0.1.2 - github.com/nats-io/nats-server/v2 v2.10.22 - github.com/nats-io/nats.go v1.37.0 - github.com/onsi/ginkgo/v2 v2.19.0 - github.com/onsi/gomega v1.33.1 + github.com/nats-io/nats-server/v2 v2.10.24 + github.com/nats-io/nats.go v1.38.0 + github.com/onsi/ginkgo/v2 v2.22.2 + github.com/onsi/gomega v1.36.2 github.com/sirupsen/logrus v1.9.3 - github.com/stretchr/testify v1.9.0 - golang.org/x/sync v0.9.0 - k8s.io/api v0.31.2 - k8s.io/apimachinery v0.31.2 - k8s.io/client-go v0.31.2 - k8s.io/code-generator v0.31.2 + github.com/stretchr/testify v1.10.0 + golang.org/x/sync v0.10.0 + k8s.io/api v0.32.0 + k8s.io/apimachinery v0.32.0 + k8s.io/client-go v0.32.0 + k8s.io/code-generator v0.32.0 k8s.io/klog/v2 v2.130.1 - sigs.k8s.io/controller-runtime v0.19.2 - sigs.k8s.io/structured-merge-diff/v4 v4.4.3 + sigs.k8s.io/controller-runtime v0.19.3 + sigs.k8s.io/structured-merge-diff/v4 v4.5.0 ) require ( @@ -29,66 +30,61 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/emicklei/go-restful/v3 v3.12.1 // indirect - github.com/evanphx/json-patch v5.9.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect github.com/expr-lang/expr v1.16.9 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/go-logr/logr v1.4.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.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // 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/gnostic-models v0.6.8 // indirect + github.com/google/gnostic-models v0.6.9 // 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-20240727154555-813a5fbdbec8 // indirect + github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect github.com/google/uuid v1.6.0 // indirect - github.com/imdario/mergo v0.3.16 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.11 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/minio/highwayhash v1.0.3 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/nats-io/jwt/v2 v2.7.2 // indirect - github.com/nats-io/nkeys v0.4.7 // indirect + github.com/nats-io/jwt/v2 v2.7.3 // indirect + github.com/nats-io/nkeys v0.4.9 // indirect github.com/nats-io/nuid v1.0.1 // 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_golang v1.19.1 // indirect + github.com/prometheus/client_golang v1.20.5 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/common v0.61.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/x448/float16 v0.8.4 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/crypto v0.29.0 // indirect - golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect golang.org/x/mod v0.22.0 // indirect - golang.org/x/net v0.31.0 // indirect + golang.org/x/net v0.33.0 // indirect golang.org/x/oauth2 v0.24.0 // indirect - golang.org/x/sys v0.27.0 // indirect - golang.org/x/term v0.26.0 // indirect - golang.org/x/text v0.20.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.8.0 // indirect - golang.org/x/tools v0.27.0 // indirect + golang.org/x/tools v0.28.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/protobuf v1.35.2 // indirect + google.golang.org/protobuf v1.36.1 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // 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/apiextensions-apiserver v0.31.0 // indirect + k8s.io/apiextensions-apiserver v0.32.0 // indirect k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9 // indirect - k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect - k8s.io/utils v0.0.0-20241104163129-6fe5fd82f078 // indirect + k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 // indirect + k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index 27b2f751..d89930d8 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,8 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= -github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k= +github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/expr-lang/expr v1.16.9 h1:WUAzmR0JNI9JCiF0/ewwHB1gmcGw5wW7nWt8gc6PpCI= @@ -34,24 +34,20 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= -github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= +github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= -github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -64,8 +60,10 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/minio/highwayhash v1.0.3 h1:kbnuUMoHYyVl7szWjSxJnxw11k2U709jqFPPmIUyD6Q= github.com/minio/highwayhash v1.0.3/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -77,31 +75,31 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/nats-io/jsm.go v0.1.2 h1:T4Fq88a03sPAPWYwrOLQ85oanYsC2Bs6517rUiWBMpQ= github.com/nats-io/jsm.go v0.1.2/go.mod h1:tnubE70CAKi5TNfQiq6XHFqWTuSIe1H7X4sDwfq6ZK8= -github.com/nats-io/jwt/v2 v2.7.2 h1:SCRjfDLJ2q8naXp8YlGJJS5/yj3wGSODFYVi4nnwVMw= -github.com/nats-io/jwt/v2 v2.7.2/go.mod h1:kB6QUmqHG6Wdrzj0KP2L+OX4xiTPBeV+NHVstFaATXU= -github.com/nats-io/nats-server/v2 v2.10.22 h1:Yt63BGu2c3DdMoBZNcR6pjGQwk/asrKU7VX846ibxDA= -github.com/nats-io/nats-server/v2 v2.10.22/go.mod h1:X/m1ye9NYansUXYFrbcDwUi/blHkrgHh2rgCJaakonk= -github.com/nats-io/nats.go v1.37.0 h1:07rauXbVnnJvv1gfIyghFEo6lUcYRY0WXc3x7x0vUxE= -github.com/nats-io/nats.go v1.37.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8= -github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI= -github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc= +github.com/nats-io/jwt/v2 v2.7.3 h1:6bNPK+FXgBeAqdj4cYQ0F8ViHRbi7woQLq4W29nUAzE= +github.com/nats-io/jwt/v2 v2.7.3/go.mod h1:GvkcbHhKquj3pkioy5put1wvPxs78UlZ7D/pY+BgZk4= +github.com/nats-io/nats-server/v2 v2.10.24 h1:KcqqQAD0ZZcG4yLxtvSFJY7CYKVYlnlWoAiVZ6i/IY4= +github.com/nats-io/nats-server/v2 v2.10.24/go.mod h1:olvKt8E5ZlnjyqBGbAXtxvSQKsPodISK5Eo/euIta4s= +github.com/nats-io/nats.go v1.38.0 h1:A7P+g7Wjp4/NWqDOOP/K6hfhr54DvdDQUznt5JFg9XA= +github.com/nats-io/nats.go v1.38.0/go.mod h1:IGUM++TwokGnXPs82/wCuiHS02/aKrdYUQkU8If6yjw= +github.com/nats-io/nkeys v0.4.9 h1:qe9Faq2Gxwi6RZnZMXfmGMZkg3afLLOtrU+gDZJ35b0= +github.com/nats-io/nkeys v0.4.9/go.mod h1:jcMqs+FLG+W5YO36OX6wFIFcmpdAns+w1Wm6D3I/evE= github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= -github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= -github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= -github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU= +github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk= +github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= +github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ= +github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= @@ -113,8 +111,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -123,15 +121,15 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= -golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= -golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo= +golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= @@ -140,44 +138,44 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= -golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= -golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= +golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= +golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= -google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= +google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -185,34 +183,32 @@ gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSP gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.31.2 h1:3wLBbL5Uom/8Zy98GRPXpJ254nEFpl+hwndmk9RwmL0= -k8s.io/api v0.31.2/go.mod h1:bWmGvrGPssSK1ljmLzd3pwCQ9MgoTsRCuK35u6SygUk= -k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24kyLSk= -k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk= -k8s.io/apimachinery v0.31.2 h1:i4vUt2hPK56W6mlT7Ry+AO8eEsyxMD1U44NR22CLTYw= -k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= -k8s.io/client-go v0.31.2 h1:Y2F4dxU5d3AQj+ybwSMqQnpZH9F30//1ObxOKlTI9yc= -k8s.io/client-go v0.31.2/go.mod h1:NPa74jSVR/+eez2dFsEIHNa+3o09vtNaWwWwb1qSxSs= -k8s.io/code-generator v0.31.2 h1:xLWxG0HEpMSHfcM//3u3Ro2Hmc6AyyLINQS//Z2GEOI= -k8s.io/code-generator v0.31.2/go.mod h1:eEQHXgBU/m7LDaToDoiz3t97dUUVyOblQdwOr8rivqc= +k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE= +k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0= +k8s.io/apiextensions-apiserver v0.32.0 h1:S0Xlqt51qzzqjKPxfgX1xh4HBZE+p8KKBq+k2SWNOE0= +k8s.io/apiextensions-apiserver v0.32.0/go.mod h1:86hblMvN5yxMvZrZFX2OhIHAuFIMJIZ19bTvzkP+Fmw= +k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg= +k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/client-go v0.32.0 h1:DimtMcnN/JIKZcrSrstiwvvZvLjG0aSxy8PxN8IChp8= +k8s.io/client-go v0.32.0/go.mod h1:boDWvdM1Drk4NJj/VddSLnx59X3OPgwrOo0vGbtq9+8= +k8s.io/code-generator v0.32.0 h1:s0lNN8VSWny8LBz5t5iy7MCdgwdOhdg7vAGVxvS+VWU= +k8s.io/code-generator v0.32.0/go.mod h1:b7Q7KMZkvsYFy72A79QYjiv4aTz3GvW0f1T3UfhFq4s= k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9 h1:si3PfKm8dDYxgfbeA6orqrtLkvvIeH8UqffFJDl0bz4= k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y= -k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4= -k8s.io/utils v0.0.0-20241104163129-6fe5fd82f078 h1:jGnCPejIetjiy2gqaJ5V0NLwTpF4wbQ6cZIItJCSHno= -k8s.io/utils v0.0.0-20241104163129-6fe5fd82f078/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.19.2 h1:3sPrF58XQEPzbE8T81TN6selQIMGbtYwuaJ6eDssDF8= -sigs.k8s.io/controller-runtime v0.19.2/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= +k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 h1:hcha5B1kVACrLujCKLbr8XWMxCxzQx42DY8QKYJrDLg= +k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7/go.mod h1:GewRfANuJ70iYzvn+i4lezLDAFzvjxZYK1gn1lWcfas= +k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0= +k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.19.3 h1:XO2GvC9OPftRst6xWCpTgBZO04S2cbp0Qqkj8bX1sPw= +sigs.k8s.io/controller-runtime v0.19.3/go.mod h1:j4j87DqtsThvwTv5/Tc5NFRyyF/RF0ip4+62tbTSIUM= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= -sigs.k8s.io/structured-merge-diff/v4 v4.4.3 h1:sCP7Vv3xx/CWIuTPVN38lUPx0uw0lcLfzaiDa8Ja01A= -sigs.k8s.io/structured-merge-diff/v4 v4.4.3/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= +sigs.k8s.io/structured-merge-diff/v4 v4.5.0 h1:nbCitCK2hfnhyiKo6uf2HxUPTCodY6Qaf85SbDIaMBk= +sigs.k8s.io/structured-merge-diff/v4 v4.5.0/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/internal/controller/account_controller.go b/internal/controller/account_controller.go index 72418667..0be62eeb 100644 --- a/internal/controller/account_controller.go +++ b/internal/controller/account_controller.go @@ -18,6 +18,7 @@ package controller import ( "context" + "k8s.io/klog/v2" jetstreamnatsiov1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" diff --git a/internal/controller/client.go b/internal/controller/client.go index c20144b3..5eb9b8d6 100644 --- a/internal/controller/client.go +++ b/internal/controller/client.go @@ -2,6 +2,7 @@ package controller import ( "fmt" + "github.com/nats-io/nats.go" "github.com/nats-io/nats.go/jetstream" ) @@ -46,7 +47,7 @@ func (o *NatsConfig) buildOptions() ([]nats.Option, error) { opts = append(opts, nats.ClientCert(o.Certificate, o.Key)) } - if o.CAs != nil && len(o.CAs) > 0 { + if len(o.CAs) > 0 { opts = append(opts, nats.RootCAs(o.CAs...)) } } @@ -62,7 +63,6 @@ type Closable interface { // Returns a jetstream.Jetstream client and the Closable of the underlying connection. // Close should be called when the client is no longer used. func CreateJetStreamClient(cfg *NatsConfig, pedantic bool) (jetstream.JetStream, Closable, error) { - opts, err := cfg.buildOptions() if err != nil { return nil, nil, fmt.Errorf("nats options: %w", err) diff --git a/internal/controller/consumer_controller.go b/internal/controller/consumer_controller.go index ba7ebb0d..9010509f 100644 --- a/internal/controller/consumer_controller.go +++ b/internal/controller/consumer_controller.go @@ -20,6 +20,8 @@ import ( "context" "errors" "fmt" + "time" + "github.com/go-logr/logr" "github.com/nats-io/nats.go/jetstream" v1 "k8s.io/api/core/v1" @@ -27,7 +29,6 @@ import ( "k8s.io/klog/v2" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/predicate" - "time" api "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" ctrl "sigs.k8s.io/controller-runtime" @@ -67,7 +68,7 @@ func (r *ConsumerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c ) // Update ready status to unknown when no status is set - if consumer.Status.Conditions == nil || len(consumer.Status.Conditions) == 0 { + if len(consumer.Status.Conditions) == 0 { log.Info("Setting initial ready condition to unknown.") consumer.Status.Conditions = updateReadyCondition(consumer.Status.Conditions, v1.ConditionUnknown, "Reconciling", "Starting reconciliation") err := r.Status().Update(ctx, consumer) @@ -113,7 +114,6 @@ func (r *ConsumerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c } func (r *ConsumerReconciler) deleteConsumer(ctx context.Context, log logr.Logger, consumer *api.Consumer) error { - // Set status to not false consumer.Status.Conditions = updateReadyCondition(consumer.Status.Conditions, v1.ConditionFalse, "Finalizing", "Performing finalizer operations.") if err := r.Status().Update(ctx, consumer); err != nil { @@ -154,11 +154,9 @@ func (r *ConsumerReconciler) deleteConsumer(ctx context.Context, log logr.Logger } func (r *ConsumerReconciler) createOrUpdate(ctx context.Context, log klog.Logger, consumer *api.Consumer) error { - // Create or Update the stream based on the spec - if consumer.Spec.PreventUpdate || r.ReadOnly() { + if r.ReadOnly() { log.Info("Skipping consumer creation or update.", - "preventDelete", consumer.Spec.PreventDelete, "read-only", r.ReadOnly(), ) return nil @@ -171,9 +169,36 @@ func (r *ConsumerReconciler) createOrUpdate(ctx context.Context, log klog.Logger } err = r.WithJetStreamClient(consumerConnOpts(consumer.Spec), func(js jetstream.JetStream) error { - log.Info("Consumer created or updated.") - _, err := js.CreateOrUpdateConsumer(ctx, consumer.Spec.StreamName, *targetConfig) - return err + consumerName := targetConfig.Name + if consumerName == "" { + consumerName = targetConfig.Durable + } + + exists := false + _, err := js.Consumer(ctx, consumer.Spec.StreamName, consumerName) + if err == nil { + exists = true + } else if !errors.Is(err, jetstream.ErrConsumerNotFound) { + return err + } + + if !exists { + log.Info("Creating Consumer.") + _, err := js.CreateConsumer(ctx, consumer.Spec.StreamName, *targetConfig) + return err + } + + if !consumer.Spec.PreventUpdate { + log.Info("Updating Consumer.") + _, err := js.UpdateConsumer(ctx, consumer.Spec.StreamName, *targetConfig) + return err + } else { + log.Info("Skipping Consumer update.", + "preventUpdate", consumer.Spec.PreventUpdate, + ) + } + + return nil }) if err != nil { err = fmt.Errorf("create or update consumer: %w", err) @@ -211,7 +236,6 @@ func consumerConnOpts(spec api.ConsumerSpec) *connectionOptions { } func consumerSpecToConfig(spec *api.ConsumerSpec) (*jetstream.ConsumerConfig, error) { - config := &jetstream.ConsumerConfig{ Durable: spec.DurableName, Description: spec.Description, @@ -269,7 +293,7 @@ func consumerSpecToConfig(spec *api.ConsumerSpec) (*jetstream.ConsumerConfig, er config.AckWait = d } - //BackOff + // BackOff for _, bo := range spec.BackOff { d, err := time.ParseDuration(bo) if err != nil { diff --git a/internal/controller/consumer_controller_test.go b/internal/controller/consumer_controller_test.go index 62fd2d22..bf5410a1 100644 --- a/internal/controller/consumer_controller_test.go +++ b/internal/controller/consumer_controller_test.go @@ -17,19 +17,19 @@ limitations under the License. package controller import ( + "testing" + "time" + "github.com/nats-io/nats.go/jetstream" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/stretchr/testify/assert" v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" k8serrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "testing" - "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -67,7 +67,7 @@ var _ = Describe("Consumer Controller", func() { BeforeEach(func(ctx SpecContext) { By("creating the custom resource for the Kind Consumer") err := k8sClient.Get(ctx, typeNamespacedName, consumer) - if err != nil && errors.IsNotFound(err) { + if err != nil && k8serrors.IsNotFound(err) { resource := &api.Consumer{ ObjectMeta: metav1.ObjectMeta{ Name: resourceName, @@ -149,9 +149,7 @@ var _ = Describe("Consumer Controller", func() { }) When("reconciling a not initialized resource", func() { - It("should initialize a new resource", func(ctx SpecContext) { - By("re-queueing until it is initialized") // Initialization can require multiple reconciliation loops Eventually(func(ctx SpecContext) *api.Consumer { @@ -177,7 +175,6 @@ var _ = Describe("Consumer Controller", func() { }) When("reconciling an initialized resource", func() { - BeforeEach(func(ctx SpecContext) { By("initializing the stream resource") @@ -222,7 +219,6 @@ var _ = Describe("Consumer Controller", func() { }) It("should create a new consumer", func(ctx SpecContext) { - By("running Reconcile") result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) Expect(err).NotTo(HaveOccurred()) @@ -249,7 +245,6 @@ var _ = Describe("Consumer Controller", func() { }) It("should update an existing consumer", func(ctx SpecContext) { - By("reconciling once to create the consumer") result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) Expect(err).NotTo(HaveOccurred()) @@ -290,21 +285,20 @@ var _ = Describe("Consumer Controller", func() { }) When("PreventUpdate is set", func() { - BeforeEach(func(ctx SpecContext) { By("setting preventUpdate on the resource") consumer.Spec.PreventUpdate = true Expect(k8sClient.Update(ctx, consumer)).To(Succeed()) }) - It("should not create the consumer", func(ctx SpecContext) { + It("should create the consumer", func(ctx SpecContext) { By("running Reconcile") result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) Expect(err).NotTo(HaveOccurred()) Expect(result.IsZero()).To(BeTrue()) - By("checking that no consumer was created") + By("checking that consumer was created") _, err = jsClient.Consumer(ctx, streamName, consumerName) - Expect(err).To(MatchError(jetstream.ErrConsumerNotFound)) + Expect(err).ToNot(HaveOccurred()) }) It("should not update the consumer", func(ctx SpecContext) { By("creating the consumer") @@ -318,12 +312,12 @@ var _ = Describe("Consumer Controller", func() { By("checking that consumer was not updated") c, err := jsClient.Consumer(ctx, streamName, consumerName) + Expect(err).NotTo(HaveOccurred()) Expect(c.CachedInfo().Config.Description).To(BeEmpty()) }) }) When("read-only mode is enabled", func() { - BeforeEach(func(ctx SpecContext) { By("setting read only on the controller") readOnly, err := NewJSController(k8sClient, &NatsConfig{ServerURL: testServer.ClientURL()}, &Config{ReadOnly: true}) @@ -355,12 +349,12 @@ var _ = Describe("Consumer Controller", func() { By("checking that consumer was not updated") s, err := jsClient.Consumer(ctx, streamName, consumerName) + Expect(err).NotTo(HaveOccurred()) Expect(s.CachedInfo().Config.Description).To(BeEmpty()) }) }) When("namespace restriction is enabled", func() { - BeforeEach(func(ctx SpecContext) { By("setting a namespace on the resource") namespaced, err := NewJSController(k8sClient, &NatsConfig{ServerURL: testServer.ClientURL()}, &Config{Namespace: "other-namespace"}) @@ -392,12 +386,12 @@ var _ = Describe("Consumer Controller", func() { By("checking that consumer was not updated") s, err := jsClient.Consumer(ctx, streamName, consumerName) + Expect(err).NotTo(HaveOccurred()) Expect(s.CachedInfo().Config.Description).To(BeEmpty()) }) }) When("the resource is marked for deletion", func() { - BeforeEach(func(ctx SpecContext) { By("marking the resource for deletion") Expect(k8sClient.Delete(ctx, consumer)).To(Succeed()) @@ -495,7 +489,6 @@ var _ = Describe("Consumer Controller", func() { } }) It("should delete the resource and not delete the consumer", func(ctx SpecContext) { - By("reconciling") result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) Expect(err).NotTo(HaveOccurred()) @@ -521,7 +514,6 @@ var _ = Describe("Consumer Controller", func() { } }) It("should not delete the resource and consumer", func(ctx SpecContext) { - By("reconciling") result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) Expect(err).NotTo(HaveOccurred()) @@ -540,7 +532,6 @@ var _ = Describe("Consumer Controller", func() { }) It("should create consumer on different server as specified in spec", func(ctx SpecContext) { - By("setting up the alternative server") altServer := CreateTestServer() defer altServer.Shutdown() @@ -558,7 +549,7 @@ var _ = Describe("Consumer Controller", func() { Expect(k8sClient.Update(ctx, consumer)).To(Succeed()) By("checking precondition, that the consumer does not yet exist") - got, err := jsClient.Consumer(ctx, streamName, consumerName) + _, err = jsClient.Consumer(ctx, streamName, consumerName) Expect(err).To(MatchError(jetstream.ErrConsumerNotFound)) By("reconciling the resource") @@ -569,7 +560,7 @@ var _ = Describe("Consumer Controller", func() { Expect(result.IsZero()).To(BeTrue()) By("checking if the consumer was created on the alternative server") - got, err = altClient.Consumer(ctx, streamName, consumerName) + got, err := altClient.Consumer(ctx, streamName, consumerName) Expect(err).NotTo(HaveOccurred()) Expect(got.CachedInfo().Created).To(BeTemporally("~", time.Now(), time.Second)) @@ -582,8 +573,7 @@ var _ = Describe("Consumer Controller", func() { }) func Test_consumerSpecToConfig(t *testing.T) { - - date := time.Date(2024, 12, 03, 16, 55, 5, 0, time.UTC) + date := time.Date(2024, 12, 3, 16, 55, 5, 0, time.UTC) dateString := date.Format(time.RFC3339) tests := []struct { diff --git a/internal/controller/helpers_test.go b/internal/controller/helpers_test.go index 8235f11c..58f176c8 100644 --- a/internal/controller/helpers_test.go +++ b/internal/controller/helpers_test.go @@ -1,15 +1,15 @@ package controller import ( + "os" + "time" + api "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" "github.com/nats-io/nats-server/v2/server" natsserver "github.com/nats-io/nats-server/v2/test" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" v1 "k8s.io/api/core/v1" - - "os" - "time" ) func assertReadyStateMatches(condition api.Condition, status v1.ConditionStatus, reason string, message string, transitionTime time.Time) { diff --git a/internal/controller/jetstream_controller.go b/internal/controller/jetstream_controller.go index 3796fc47..63e8f720 100644 --- a/internal/controller/jetstream_controller.go +++ b/internal/controller/jetstream_controller.go @@ -2,14 +2,15 @@ package controller import ( "fmt" + "strings" + "time" + js "github.com/nats-io/nack/controllers/jetstream" api "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" "github.com/nats-io/nats.go/jetstream" v1 "k8s.io/api/core/v1" - "strings" "sigs.k8s.io/controller-runtime/pkg/client" - "time" ) type connectionOptions struct { @@ -39,7 +40,6 @@ type JetStreamController interface { } func NewJSController(k8sClient client.Client, natsConfig *NatsConfig, controllerConfig *Config) (JetStreamController, error) { - return &jsController{ Client: k8sClient, config: natsConfig, @@ -63,7 +63,6 @@ func (c *jsController) ValidNamespace(namespace string) bool { } func (c *jsController) WithJetStreamClient(opts *connectionOptions, op func(js jetstream.JetStream) error) error { - // Build single use client // TODO(future-feature): Use client-pool instead of single use client cfg := c.buildNatsConfig(opts) @@ -79,7 +78,6 @@ func (c *jsController) WithJetStreamClient(opts *connectionOptions, op func(js j // buildNatsConfig uses given opts to override the base NatsConfig. func (c *jsController) buildNatsConfig(opts *connectionOptions) *NatsConfig { - serverUrls := strings.Join(opts.Servers, ",") // Takes opts values if present @@ -132,7 +130,6 @@ func or[T comparable](v T, fallback T) T { // updateReadyCondition returns the given conditions with an added or updated ready condition. func updateReadyCondition(conditions []api.Condition, status v1.ConditionStatus, reason string, message string) []api.Condition { - var currentStatus v1.ConditionStatus var lastTransitionTime string for _, condition := range conditions { diff --git a/internal/controller/jetstream_controller_test.go b/internal/controller/jetstream_controller_test.go index d7176d04..83b75ee8 100644 --- a/internal/controller/jetstream_controller_test.go +++ b/internal/controller/jetstream_controller_test.go @@ -1,15 +1,15 @@ package controller import ( + "testing" + "time" + api "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" "github.com/stretchr/testify/assert" v1 "k8s.io/api/core/v1" - "testing" - "time" ) func Test_updateReadyCondition(t *testing.T) { - pastTransition := time.Now().UTC().Add(-time.Hour).Format(time.RFC3339Nano) updatedTransition := "now" diff --git a/internal/controller/keyvalue_controller.go b/internal/controller/keyvalue_controller.go new file mode 100644 index 00000000..d76220c1 --- /dev/null +++ b/internal/controller/keyvalue_controller.go @@ -0,0 +1,312 @@ +/* +Copyright 2025. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/go-logr/logr" + api "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" + "github.com/nats-io/nats.go/jetstream" + v1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/klog/v2" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/predicate" +) + +// KeyValueReconciler reconciles a KeyValue object +type KeyValueReconciler struct { + JetStreamController +} + +// Reconcile is part of the main kubernetes reconciliation loop which aims to +// move the current state of the cluster closer to the desired state. +// +// It performs three main operations: +// - Initialize finalizer and ready condition if not present +// - Delete KeyValue if it is marked for deletion. +// - Create or Update the KeyValue +// +// A call to reconcile may perform only one action, expecting the reconciliation to be triggered again by an update. +// For example: Setting the finalizer triggers a second reconciliation. Reconcile returns after setting the finalizer, +// to prevent parallel reconciliations performing the same steps. +func (r *KeyValueReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + log := klog.FromContext(ctx) + + if ok := r.ValidNamespace(req.Namespace); !ok { + log.Info("Controller restricted to namespace, skipping reconciliation.") + return ctrl.Result{}, nil + } + + // Fetch KeyValue resource + keyValue := &api.KeyValue{} + if err := r.Get(ctx, req.NamespacedName, keyValue); err != nil { + if apierrors.IsNotFound(err) { + log.Info("KeyValue resource not found. Ignoring since object must be deleted.") + return ctrl.Result{}, nil + } + return ctrl.Result{}, fmt.Errorf("get keyvalue resource '%s': %w", req.NamespacedName.String(), err) + } + + log = log.WithValues("keyValueName", keyValue.Spec.Name) + + // Update ready status to unknown when no status is set + if len(keyValue.Status.Conditions) == 0 { + log.Info("Setting initial ready condition to unknown.") + keyValue.Status.Conditions = updateReadyCondition(keyValue.Status.Conditions, v1.ConditionUnknown, "Reconciling", "Starting reconciliation") + err := r.Status().Update(ctx, keyValue) + if err != nil { + return ctrl.Result{}, fmt.Errorf("set condition unknown: %w", err) + } + return ctrl.Result{Requeue: true}, nil + } + + // Add finalizer + if !controllerutil.ContainsFinalizer(keyValue, keyValueFinalizer) { + log.Info("Adding KeyValue finalizer.") + if ok := controllerutil.AddFinalizer(keyValue, keyValueFinalizer); !ok { + return ctrl.Result{}, errors.New("failed to add finalizer to keyvalue resource") + } + + if err := r.Update(ctx, keyValue); err != nil { + return ctrl.Result{}, fmt.Errorf("update keyvalue resource to add finalizer: %w", err) + } + return ctrl.Result{}, nil + } + + // Check Deletion + markedForDeletion := keyValue.GetDeletionTimestamp() != nil + if markedForDeletion { + if controllerutil.ContainsFinalizer(keyValue, keyValueFinalizer) { + err := r.deleteKeyValue(ctx, log, keyValue) + if err != nil { + return ctrl.Result{}, fmt.Errorf("delete keyvalue: %w", err) + } + } else { + log.Info("KeyValue marked for deletion and already finalized. Ignoring.") + } + + return ctrl.Result{}, nil + } + + // Create or update KeyValue + if err := r.createOrUpdate(ctx, log, keyValue); err != nil { + return ctrl.Result{}, fmt.Errorf("create or update: %s", err) + } + return ctrl.Result{}, nil +} + +func (r *KeyValueReconciler) deleteKeyValue(ctx context.Context, log logr.Logger, keyValue *api.KeyValue) error { + // Set status to not false + keyValue.Status.Conditions = updateReadyCondition(keyValue.Status.Conditions, v1.ConditionFalse, "Finalizing", "Performing finalizer operations.") + if err := r.Status().Update(ctx, keyValue); err != nil { + return fmt.Errorf("update ready condition: %w", err) + } + + if !keyValue.Spec.PreventDelete && !r.ReadOnly() { + log.Info("Deleting KeyValue.") + err := r.WithJetStreamClient(keyValueConnOpts(keyValue.Spec), func(js jetstream.JetStream) error { + return js.DeleteKeyValue(ctx, keyValue.Spec.Name) + }) + if errors.Is(err, jetstream.ErrBucketNotFound) { + log.Info("KeyValue does not exist, unable to delete.", "keyValueName", keyValue.Spec.Name) + } else if err != nil { + return fmt.Errorf("delete keyvalue during finalization: %w", err) + } + } else { + log.Info("Skipping KeyValue deletion.", + "preventDelete", keyValue.Spec.PreventDelete, + "read-only", r.ReadOnly(), + ) + } + + log.Info("Removing KeyValue finalizer.") + if ok := controllerutil.RemoveFinalizer(keyValue, keyValueFinalizer); !ok { + return errors.New("failed to remove keyvalue finalizer") + } + if err := r.Update(ctx, keyValue); err != nil { + return fmt.Errorf("remove finalizer: %w", err) + } + + return nil +} + +func (r *KeyValueReconciler) createOrUpdate(ctx context.Context, log logr.Logger, keyValue *api.KeyValue) error { + // Create or Update the KeyValue based on the spec + if r.ReadOnly() { + log.Info("Skipping KeyValue creation or update.", + "read-only", r.ReadOnly(), + ) + return nil + } + + // Map spec to KeyValue targetConfig + targetConfig, err := keyValueSpecToConfig(&keyValue.Spec) + if err != nil { + return fmt.Errorf("map spec to keyvalue targetConfig: %w", err) + } + + // UpdateKeyValue is called on every reconciliation when the stream is not to be deleted. + // TODO(future-feature): Do we need to check if config differs? + err = r.WithJetStreamClient(keyValueConnOpts(keyValue.Spec), func(js jetstream.JetStream) error { + exists := false + _, err := js.KeyValue(ctx, targetConfig.Bucket) + if err == nil { + exists = true + } else if !errors.Is(err, jetstream.ErrBucketNotFound) { + return err + } + + if !exists { + log.Info("Creating KeyValue.") + _, err = js.CreateKeyValue(ctx, targetConfig) + return err + } + + if !keyValue.Spec.PreventUpdate { + log.Info("Updating KeyValue.") + _, err = js.UpdateKeyValue(ctx, targetConfig) + return err + } else { + log.Info("Skipping KeyValue update.", + "preventUpdate", keyValue.Spec.PreventUpdate, + ) + } + + return nil + }) + if err != nil { + err = fmt.Errorf("create or update keyvalue: %w", err) + keyValue.Status.Conditions = updateReadyCondition(keyValue.Status.Conditions, v1.ConditionFalse, "Errored", err.Error()) + if err := r.Status().Update(ctx, keyValue); err != nil { + log.Error(err, "Failed to update ready condition to Errored.") + } + return err + } + + // update the observed generation and ready status + keyValue.Status.ObservedGeneration = keyValue.Generation + keyValue.Status.Conditions = updateReadyCondition( + keyValue.Status.Conditions, + v1.ConditionTrue, + "Reconciling", + "KeyValue successfully created or updated.", + ) + err = r.Status().Update(ctx, keyValue) + if err != nil { + return fmt.Errorf("update ready condition: %w", err) + } + + return nil +} + +// keyValueConnOpts extracts nats connection relevant fields from the given KeyValue spec as connectionOptions. +func keyValueConnOpts(spec api.KeyValueSpec) *connectionOptions { + return &connectionOptions{ + Account: spec.Account, + Creds: spec.Creds, + Nkey: spec.Nkey, + Servers: spec.Servers, + TLS: spec.TLS, + } +} + +// keyValueSpecToConfig creates a jetstream.KeyValueConfig matching the given KeyValue resource spec +func keyValueSpecToConfig(spec *api.KeyValueSpec) (jetstream.KeyValueConfig, error) { + // Set directly mapped fields + config := jetstream.KeyValueConfig{ + Bucket: spec.Name, + Compression: spec.Compression, + Description: spec.Description, + History: uint8(spec.History), + MaxBytes: int64(spec.MaxBytes), + MaxValueSize: int32(spec.MaxValueSize), + Replicas: spec.Replicas, + } + + // TTL + if spec.TTL != "" { + t, err := time.ParseDuration(spec.TTL) + if err != nil { + return jetstream.KeyValueConfig{}, fmt.Errorf("invalid ttl: %w", err) + } + config.TTL = t + } + + // storage + if spec.Storage != "" { + err := config.Storage.UnmarshalJSON(asJsonString(spec.Storage)) + if err != nil { + return jetstream.KeyValueConfig{}, fmt.Errorf("invalid storage: %w", err) + } + } + + // placement + if spec.Placement != nil { + config.Placement = &jetstream.Placement{ + Cluster: spec.Placement.Cluster, + Tags: spec.Placement.Tags, + } + } + + // mirror + if spec.Mirror != nil { + ss, err := mapStreamSource(spec.Mirror) + if err != nil { + return jetstream.KeyValueConfig{}, fmt.Errorf("map mirror keyvalue source: %w", err) + } + config.Mirror = ss + } + + // sources + if spec.Sources != nil { + config.Sources = []*jetstream.StreamSource{} + for _, source := range spec.Sources { + s, err := mapStreamSource(source) + if err != nil { + return jetstream.KeyValueConfig{}, fmt.Errorf("map keyvalue source: %w", err) + } + config.Sources = append(config.Sources, s) + } + } + + // RePublish + if spec.Republish != nil { + config.RePublish = &jetstream.RePublish{ + Source: spec.Republish.Source, + Destination: spec.Republish.Destination, + HeadersOnly: spec.Republish.HeadersOnly, + } + } + + return config, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *KeyValueReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&api.KeyValue{}). + Owns(&api.KeyValue{}). + // Only trigger on generation changes + WithEventFilter(predicate.GenerationChangedPredicate{}). + Complete(r) +} diff --git a/internal/controller/keyvalue_controller_test.go b/internal/controller/keyvalue_controller_test.go new file mode 100644 index 00000000..26b06688 --- /dev/null +++ b/internal/controller/keyvalue_controller_test.go @@ -0,0 +1,699 @@ +/* +Copyright 2024. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "testing" + "time" + + "github.com/nats-io/nats.go/jetstream" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + api "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" +) + +var _ = Describe("KeyValue Controller", func() { + // The test keyValue resource + const resourceName = "test-kv" + const keyValueName = "orders" + typeNamespacedName := types.NamespacedName{ + Name: resourceName, + Namespace: "default", + } + keyValue := &api.KeyValue{} + + // The tested controller + var controller *KeyValueReconciler + + // Config to create minimal nats KeyValue store + emptyKeyValueConfig := jetstream.KeyValueConfig{ + Bucket: keyValueName, + Replicas: 1, + Storage: jetstream.FileStorage, + } + + BeforeEach(func(ctx SpecContext) { + By("creating a test keyvalue resource") + err := k8sClient.Get(ctx, typeNamespacedName, keyValue) + if err != nil && k8serrors.IsNotFound(err) { + resource := &api.KeyValue{ + ObjectMeta: metav1.ObjectMeta{ + Name: resourceName, + Namespace: "default", + }, + Spec: api.KeyValueSpec{ + Name: keyValueName, + Replicas: 1, + History: 10, + TTL: "5m", + Compression: true, + Description: "test keyvalue", + Storage: "file", + }, + } + Expect(k8sClient.Create(ctx, resource)).To(Succeed()) + // Re-fetch KeyValue + Expect(k8sClient.Get(ctx, typeNamespacedName, keyValue)).To(Succeed()) + } + + By("checking precondition: nats keyvalue does not exist") + _, err = jsClient.KeyValue(ctx, keyValueName) + Expect(err).To(MatchError(jetstream.ErrBucketNotFound)) + + By("setting up the tested controller") + controller = &KeyValueReconciler{ + baseController, + } + }) + + AfterEach(func(ctx SpecContext) { + By("removing the test keyvalue resource") + resource := &api.KeyValue{} + err := k8sClient.Get(ctx, typeNamespacedName, resource) + if err != nil { + Expect(err).To(MatchError(k8serrors.IsNotFound, "Is not found")) + } else { + if controllerutil.ContainsFinalizer(resource, keyValueFinalizer) { + By("removing the finalizer") + controllerutil.RemoveFinalizer(resource, keyValueFinalizer) + Expect(k8sClient.Update(ctx, resource)).To(Succeed()) + } + + By("removing the keyvalue resource") + Expect(k8sClient.Delete(ctx, resource)). + To(SatisfyAny( + Succeed(), + MatchError(k8serrors.IsNotFound, "is not found"), + )) + } + + By("deleting the nats keyvalue store") + Expect(jsClient.DeleteKeyValue(ctx, keyValueName)). + To(SatisfyAny( + Succeed(), + MatchError(jetstream.ErrBucketNotFound), + )) + }) + + When("reconciling a not existing resource", func() { + It("should stop reconciliation without error", func(ctx SpecContext) { + By("reconciling the created resource") + result, err := controller.Reconcile(ctx, reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: "fake", + Name: "not-existing", + }, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(result).To(Equal(ctrl.Result{})) + }) + }) + + When("reconciling a not initialized resource", func() { + It("should initialize a new resource", func(ctx SpecContext) { + By("re-queueing until it is initialized") + // Initialization can require multiple reconciliation loops + Eventually(func(ctx SpecContext) *api.KeyValue { + _, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) + Expect(err).NotTo(HaveOccurred()) + got := &api.KeyValue{} + Expect(k8sClient.Get(ctx, typeNamespacedName, got)).To(Succeed()) + return got + }).WithContext(ctx). + Should(SatisfyAll( + HaveField("Finalizers", HaveExactElements(keyValueFinalizer)), + HaveField("Status.Conditions", Not(BeEmpty())), + )) + + By("validating the ready condition") + // Fetch KeyValue + Expect(k8sClient.Get(ctx, typeNamespacedName, keyValue)).To(Succeed()) + Expect(keyValue.Status.Conditions).To(HaveLen(1)) + + assertReadyStateMatches(keyValue.Status.Conditions[0], v1.ConditionUnknown, "Reconciling", "Starting reconciliation", time.Now()) + }) + }) + + When("reconciling an initialized resource", func() { + BeforeEach(func(ctx SpecContext) { + By("initializing the keyvalue resource") + + By("setting the finalizer") + Expect(controllerutil.AddFinalizer(keyValue, keyValueFinalizer)).To(BeTrue()) + Expect(k8sClient.Update(ctx, keyValue)).To(Succeed()) + + By("setting an unknown ready state") + keyValue.Status.Conditions = []api.Condition{{ + Type: readyCondType, + Status: v1.ConditionUnknown, + Reason: "Test", + Message: "start condition", + LastTransitionTime: time.Now().Format(time.RFC3339Nano), + }} + Expect(k8sClient.Status().Update(ctx, keyValue)).To(Succeed()) + }) + + It("should create a new keyvalue store", func(ctx SpecContext) { + By("running Reconcile") + result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) + Expect(err).NotTo(HaveOccurred()) + Expect(result.IsZero()).To(BeTrue()) + + // Fetch resource + Expect(k8sClient.Get(ctx, typeNamespacedName, keyValue)).To(Succeed()) + + By("checking if the ready state was updated") + Expect(keyValue.Status.Conditions).To(HaveLen(1)) + assertReadyStateMatches(keyValue.Status.Conditions[0], v1.ConditionTrue, "Reconciling", "created or updated", time.Now()) + + By("checking if the observed generation matches") + Expect(keyValue.Status.ObservedGeneration).To(Equal(keyValue.Generation)) + + By("checking if the keyvalue store was created") + natsKeyValue, err := jsClient.KeyValue(ctx, keyValueName) + Expect(err).NotTo(HaveOccurred()) + kvStatus, err := natsKeyValue.Status(ctx) + Expect(err).NotTo(HaveOccurred()) + Expect(kvStatus.Bucket()).To(Equal(keyValueName)) + Expect(kvStatus.History()).To(Equal(int64(10))) + Expect(kvStatus.TTL()).To(Equal(5 * time.Minute)) + Expect(kvStatus.IsCompressed()).To(BeTrue()) + }) + + When("PreventUpdate is set", func() { + BeforeEach(func(ctx SpecContext) { + By("setting preventDelete on the resource") + keyValue.Spec.PreventUpdate = true + Expect(k8sClient.Update(ctx, keyValue)).To(Succeed()) + }) + It("should create the keyvalue", func(ctx SpecContext) { + By("running Reconcile") + result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) + Expect(err).NotTo(HaveOccurred()) + Expect(result.IsZero()).To(BeTrue()) + + By("checking that keyvalue was created") + _, err = jsClient.KeyValue(ctx, keyValueName) + Expect(err).NotTo(HaveOccurred()) + }) + It("should not update the keyvalue", func(ctx SpecContext) { + By("creating the keyvalue") + _, err := jsClient.CreateKeyValue(ctx, emptyKeyValueConfig) + Expect(err).NotTo(HaveOccurred()) + + By("running Reconcile") + result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) + Expect(err).NotTo(HaveOccurred()) + Expect(result.IsZero()).To(BeTrue()) + + By("checking that keyvalue was not updated") + natsKeyValue, err := jsClient.KeyValue(ctx, keyValueName) + Expect(err).NotTo(HaveOccurred()) + s, err := natsKeyValue.Status(ctx) + Expect(err).NotTo(HaveOccurred()) + Expect(s.IsCompressed()).To(BeFalse()) + Expect(s.History()).To(BeEquivalentTo(int64(1))) + }) + }) + + When("read-only mode is enabled", func() { + BeforeEach(func(ctx SpecContext) { + By("setting read only on the controller") + readOnly, err := NewJSController(k8sClient, &NatsConfig{ServerURL: testServer.ClientURL()}, &Config{ReadOnly: true}) + Expect(err).NotTo(HaveOccurred()) + controller = &KeyValueReconciler{ + JetStreamController: readOnly, + } + }) + + It("should not create the keyvalue", func(ctx SpecContext) { + By("running Reconcile") + result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) + Expect(err).NotTo(HaveOccurred()) + Expect(result.IsZero()).To(BeTrue()) + + By("checking that no keyvalue was created") + _, err = jsClient.KeyValue(ctx, keyValueName) + Expect(err).To(MatchError(jetstream.ErrBucketNotFound)) + }) + It("should not update the keyvalue", func(ctx SpecContext) { + By("creating the keyvalue") + _, err := jsClient.CreateKeyValue(ctx, emptyKeyValueConfig) + Expect(err).NotTo(HaveOccurred()) + + By("running Reconcile") + result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) + Expect(err).NotTo(HaveOccurred()) + Expect(result.IsZero()).To(BeTrue()) + + By("checking that keyvalue was not updated") + natsKeyValue, err := jsClient.KeyValue(ctx, keyValueName) + Expect(err).NotTo(HaveOccurred()) + s, err := natsKeyValue.Status(ctx) + Expect(err).NotTo(HaveOccurred()) + Expect(s.IsCompressed()).To(BeFalse()) + Expect(s.History()).To(BeEquivalentTo(int64(1))) + }) + }) + + When("namespace restriction is enabled", func() { + BeforeEach(func(ctx SpecContext) { + By("setting a namespace on the resource") + namespaced, err := NewJSController(k8sClient, &NatsConfig{ServerURL: testServer.ClientURL()}, &Config{Namespace: "other-namespace"}) + Expect(err).NotTo(HaveOccurred()) + controller = &KeyValueReconciler{ + JetStreamController: namespaced, + } + }) + + It("should not create the keyvalue", func(ctx SpecContext) { + By("running Reconcile") + result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) + Expect(err).NotTo(HaveOccurred()) + Expect(result.IsZero()).To(BeTrue()) + + By("checking that no keyvalue was created") + _, err = jsClient.KeyValue(ctx, keyValueName) + Expect(err).To(MatchError(jetstream.ErrBucketNotFound)) + }) + It("should not update the keyvalue", func(ctx SpecContext) { + By("creating the keyvalue") + _, err := jsClient.CreateKeyValue(ctx, emptyKeyValueConfig) + Expect(err).NotTo(HaveOccurred()) + + By("running Reconcile") + result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) + Expect(err).NotTo(HaveOccurred()) + Expect(result.IsZero()).To(BeTrue()) + + By("checking that keyvalue was not updated") + natsKeyValue, err := jsClient.KeyValue(ctx, keyValueName) + Expect(err).NotTo(HaveOccurred()) + s, err := natsKeyValue.Status(ctx) + Expect(err).NotTo(HaveOccurred()) + Expect(s.IsCompressed()).To(BeFalse()) + Expect(s.History()).To(BeEquivalentTo(int64(1))) + }) + }) + + It("should update an existing keyvalue", func(ctx SpecContext) { + By("reconciling once to create the keyvalue") + result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) + Expect(err).NotTo(HaveOccurred()) + Expect(result.IsZero()).To(BeTrue()) + + // Fetch resource + Expect(k8sClient.Get(ctx, typeNamespacedName, keyValue)).To(Succeed()) + previousTransitionTime := keyValue.Status.Conditions[0].LastTransitionTime + + By("updating the resource") + keyValue.Spec.Description = "new description" + keyValue.Spec.History = 50 + keyValue.Spec.TTL = "1h" + Expect(k8sClient.Update(ctx, keyValue)).To(Succeed()) + + By("reconciling the updated resource") + result, err = controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) + Expect(err).NotTo(HaveOccurred()) + Expect(result.IsZero()).To(BeTrue()) + + // Fetch resource + Expect(k8sClient.Get(ctx, typeNamespacedName, keyValue)).To(Succeed()) + + By("checking if the state transition time was not updated") + Expect(keyValue.Status.Conditions).To(HaveLen(1)) + Expect(keyValue.Status.Conditions[0].LastTransitionTime).To(Equal(previousTransitionTime)) + + By("checking if the observed generation matches") + Expect(keyValue.Status.ObservedGeneration).To(Equal(keyValue.Generation)) + + By("checking if the keyvalue was updated") + natsKeyValue, err := jsClient.KeyValue(ctx, keyValueName) + Expect(err).NotTo(HaveOccurred()) + + keyValueStatus, err := natsKeyValue.Status(ctx) + Expect(err).NotTo(HaveOccurred()) + Expect(keyValueStatus.Bucket()).To(Equal(keyValueName)) + Expect(keyValueStatus.History()).To(Equal(int64(50))) + Expect(keyValueStatus.TTL()).To(Equal(1 * time.Hour)) + Expect(keyValueStatus.IsCompressed()).To(BeTrue()) + }) + + It("should set an error state when the nats server is not available", func(ctx SpecContext) { + By("setting up controller with unavailable nats server") + // Setup client for not running server + // Use actual test server to ensure port not used by other service on test instance + sv := CreateTestServer() + base, err := NewJSController(k8sClient, &NatsConfig{ServerURL: sv.ClientURL()}, &Config{}) + Expect(err).NotTo(HaveOccurred()) + sv.Shutdown() + + controller := &KeyValueReconciler{ + base, + } + + By("reconciling resource") + result, err := controller.Reconcile(ctx, reconcile.Request{ + NamespacedName: typeNamespacedName, + }) + Expect(result).To(Equal(ctrl.Result{})) + Expect(err).To(HaveOccurred()) // Will be re-queued with back-off + + // Fetch resource + err = k8sClient.Get(ctx, typeNamespacedName, keyValue) + Expect(err).NotTo(HaveOccurred()) + + By("checking if the status was updated") + Expect(keyValue.Status.Conditions).To(HaveLen(1)) + assertReadyStateMatches( + keyValue.Status.Conditions[0], + v1.ConditionFalse, + "Errored", + "create or update keyvalue:", + time.Now(), + ) + + By("checking if the observed generation does not match") + Expect(keyValue.Status.ObservedGeneration).ToNot(Equal(keyValue.Generation)) + }) + + When("the resource is marked for deletion", func() { + BeforeEach(func(ctx SpecContext) { + By("marking the resource for deletion") + Expect(k8sClient.Delete(ctx, keyValue)).To(Succeed()) + Expect(k8sClient.Get(ctx, typeNamespacedName, keyValue)).To(Succeed()) // re-fetch after update + }) + + It("should succeed deleting a not existing keyvalue", func(ctx SpecContext) { + By("reconciling") + result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) + Expect(err).NotTo(HaveOccurred()) + Expect(result.IsZero()).To(BeTrue()) + + By("checking that the resource is deleted") + Eventually(k8sClient.Get). + WithArguments(ctx, typeNamespacedName, keyValue). + ShouldNot(Succeed()) + }) + + When("the underlying keyvalue exists", func() { + BeforeEach(func(ctx SpecContext) { + By("creating the keyvalue on the nats server") + _, err := jsClient.CreateKeyValue(ctx, emptyKeyValueConfig) + Expect(err).NotTo(HaveOccurred()) + }) + + AfterEach(func(ctx SpecContext) { + err := jsClient.DeleteKeyValue(ctx, keyValueName) + if err != nil { + Expect(err).To(MatchError(jetstream.ErrBucketNotFound)) + } + }) + + It("should delete the keyvalue", func(ctx SpecContext) { + By("reconciling") + result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) + Expect(err).NotTo(HaveOccurred()) + Expect(result.IsZero()).To(BeTrue()) + + By("checking that the keyvalue is deleted") + _, err = jsClient.KeyValue(ctx, keyValueName) + Expect(err).To(MatchError(jetstream.ErrBucketNotFound)) + + By("checking that the resource is deleted") + Eventually(k8sClient.Get). + WithArguments(ctx, typeNamespacedName, keyValue). + ShouldNot(Succeed()) + }) + + When("PreventDelete is set", func() { + BeforeEach(func(ctx SpecContext) { + By("setting preventDelete on the resource") + keyValue.Spec.PreventDelete = true + Expect(k8sClient.Update(ctx, keyValue)).To(Succeed()) + }) + It("Should delete the resource and not delete the nats keyvalue", func(ctx SpecContext) { + By("reconciling") + result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) + Expect(err).NotTo(HaveOccurred()) + Expect(result.IsZero()).To(BeTrue()) + + By("checking that the keyvalue is not deleted") + _, err = jsClient.KeyValue(ctx, keyValueName) + Expect(err).NotTo(HaveOccurred()) + + By("checking that the resource is deleted") + Eventually(k8sClient.Get). + WithArguments(ctx, typeNamespacedName, keyValue). + ShouldNot(Succeed()) + }) + }) + + When("read only is set", func() { + BeforeEach(func(ctx SpecContext) { + By("setting read only on the controller") + readOnly, err := NewJSController(k8sClient, &NatsConfig{ServerURL: testServer.ClientURL()}, &Config{ReadOnly: true}) + Expect(err).NotTo(HaveOccurred()) + controller = &KeyValueReconciler{ + JetStreamController: readOnly, + } + }) + It("should delete the resource and not delete the keyvalue", func(ctx SpecContext) { + By("reconciling") + result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) + Expect(err).NotTo(HaveOccurred()) + Expect(result.IsZero()).To(BeTrue()) + + By("checking that the keyvalue is not deleted") + _, err = jsClient.KeyValue(ctx, keyValueName) + Expect(err).NotTo(HaveOccurred()) + + By("checking that the resource is deleted") + Eventually(k8sClient.Get). + WithArguments(ctx, typeNamespacedName, keyValue). + ShouldNot(Succeed()) + }) + }) + + When("controller is restricted to different namespace", func() { + BeforeEach(func(ctx SpecContext) { + namespaced, err := NewJSController(k8sClient, &NatsConfig{ServerURL: testServer.ClientURL()}, &Config{Namespace: "other-namespace"}) + Expect(err).NotTo(HaveOccurred()) + controller = &KeyValueReconciler{ + JetStreamController: namespaced, + } + }) + It("should not delete the resource and keyvalue", func(ctx SpecContext) { + By("reconciling") + result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) + Expect(err).NotTo(HaveOccurred()) + Expect(result.IsZero()).To(BeTrue()) + + By("checking that the keyvalue is not deleted") + _, err = jsClient.KeyValue(ctx, keyValueName) + Expect(err).NotTo(HaveOccurred()) + + By("checking that the finalizer is not removed") + Expect(k8sClient.Get(ctx, typeNamespacedName, keyValue)).To(Succeed()) + Expect(keyValue.Finalizers).To(ContainElement(keyValueFinalizer)) + }) + }) + }) + }) + + It("should update keyvalue on different server as specified in spec", func(ctx SpecContext) { + By("setting up the alternative server") + // Setup altClient for alternate server + altServer := CreateTestServer() + defer altServer.Shutdown() + + By("setting the server in the keyvalue spec") + keyValue.Spec.Servers = []string{altServer.ClientURL()} + Expect(k8sClient.Update(ctx, keyValue)).To(Succeed()) + + By("checking precondition, that the keyvalue does not yet exist") + _, err := jsClient.KeyValue(ctx, keyValueName) + Expect(err).To(MatchError(jetstream.ErrBucketNotFound)) + + By("reconciling the resource") + result, err := controller.Reconcile(ctx, reconcile.Request{ + NamespacedName: typeNamespacedName, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(result.IsZero()).To(BeTrue()) + + By("checking if the keyvalue was created on the alternative server") + altClient, closer, err := CreateJetStreamClient(&NatsConfig{ServerURL: altServer.ClientURL()}, true) + defer closer.Close() + Expect(err).NotTo(HaveOccurred()) + + _, err = altClient.KeyValue(ctx, keyValueName) + Expect(err).NotTo(HaveOccurred()) + + By("checking that the keyvalue was NOT created on the original server") + _, err = jsClient.KeyValue(ctx, keyValueName) + Expect(err).To(MatchError(jetstream.ErrBucketNotFound)) + }) + }) +}) + +func Test_mapKVSpecToConfig(t *testing.T) { + date := time.Date(2024, 12, 3, 16, 55, 5, 0, time.UTC) + dateString := date.Format(time.RFC3339) + + tests := []struct { + name string + spec *api.KeyValueSpec + want jetstream.KeyValueConfig + wantErr bool + }{ + { + name: "emtpy spec", + spec: &api.KeyValueSpec{}, + want: jetstream.KeyValueConfig{}, + wantErr: false, + }, + { + name: "full spec", + spec: &api.KeyValueSpec{ + Account: "", + Creds: "", + Description: "kv description", + PreventDelete: false, + PreventUpdate: false, + History: 20, + MaxValueSize: 1024, + MaxBytes: 1048576, + TTL: "1h", + Mirror: &api.StreamSource{ + Name: "mirror", + OptStartSeq: 5, + OptStartTime: dateString, + FilterSubject: "orders", + ExternalAPIPrefix: "api", + ExternalDeliverPrefix: "deliver", + SubjectTransforms: []*api.SubjectTransform{{ + Source: "transform-source", + Dest: "transform-dest", + }}, + }, + Name: "kv-name", + Nkey: "", + Placement: &api.StreamPlacement{ + Cluster: "test-cluster", + Tags: []string{"tag"}, + }, + Replicas: 3, + Republish: &api.RePublish{ + Source: "re-publish-source", + Destination: "re-publish-dest", + HeadersOnly: true, + }, + Compression: true, + Servers: nil, + Sources: []*api.StreamSource{{ + Name: "source", + OptStartSeq: 5, + OptStartTime: dateString, + FilterSubject: "orders", + ExternalAPIPrefix: "api", + ExternalDeliverPrefix: "deliver", + SubjectTransforms: []*api.SubjectTransform{{ + Source: "transform-source", + Dest: "transform-dest", + }}, + }}, + Storage: "memory", + TLS: api.TLS{}, + }, + want: jetstream.KeyValueConfig{ + Bucket: "kv-name", + Description: "kv description", + MaxBytes: 1048576, + TTL: time.Hour, + MaxValueSize: 1024, + History: 20, + Storage: jetstream.MemoryStorage, + Replicas: 3, + Placement: &jetstream.Placement{ + Cluster: "test-cluster", + Tags: []string{"tag"}, + }, + Mirror: &jetstream.StreamSource{ + Name: "mirror", + OptStartSeq: 5, + OptStartTime: &date, + FilterSubject: "orders", + SubjectTransforms: []jetstream.SubjectTransformConfig{{ + Source: "transform-source", + Destination: "transform-dest", + }}, + External: &jetstream.ExternalStream{ + APIPrefix: "api", + DeliverPrefix: "deliver", + }, + Domain: "", + }, + Sources: []*jetstream.StreamSource{{ + Name: "source", + OptStartSeq: 5, + OptStartTime: &date, + FilterSubject: "orders", + SubjectTransforms: []jetstream.SubjectTransformConfig{{ + Source: "transform-source", + Destination: "transform-dest", + }}, + External: &jetstream.ExternalStream{ + APIPrefix: "api", + DeliverPrefix: "deliver", + }, + Domain: "", + }}, + Compression: true, + RePublish: &jetstream.RePublish{ + Source: "re-publish-source", + Destination: "re-publish-dest", + HeadersOnly: true, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert := assert.New(t) + got, err := keyValueSpecToConfig(tt.spec) + if (err != nil) != tt.wantErr { + t.Errorf("keyValueSpecToConfig() error = %v, wantErr %v", err, tt.wantErr) + return + } + + // Compare nested structs + assert.EqualValues(tt.want, got) + }) + } +} diff --git a/internal/controller/register.go b/internal/controller/register.go index 5fa21b5a..8c5c8def 100644 --- a/internal/controller/register.go +++ b/internal/controller/register.go @@ -2,6 +2,7 @@ package controller import ( "fmt" + ctrl "sigs.k8s.io/controller-runtime" ) @@ -19,7 +20,6 @@ type Config struct { // natsCfg is specific to the nats server connection. // controllerCfg defines behaviour of the registered controllers. func RegisterAll(mgr ctrl.Manager, clientConfig *NatsConfig, config *Config) error { - baseController, err := NewJSController(mgr.GetClient(), clientConfig, config) if err != nil { return fmt.Errorf("create base jetstream controller: %w", err) diff --git a/internal/controller/stream_controller.go b/internal/controller/stream_controller.go index 1766c8ba..bd7ad3ad 100644 --- a/internal/controller/stream_controller.go +++ b/internal/controller/stream_controller.go @@ -20,6 +20,8 @@ import ( "context" "errors" "fmt" + "time" + "github.com/go-logr/logr" api "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" "github.com/nats-io/nats.go/jetstream" @@ -29,7 +31,6 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/predicate" - "time" ) // StreamReconciler reconciles a Stream object @@ -69,7 +70,7 @@ func (r *StreamReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr log = log.WithValues("streamName", stream.Spec.Name) // Update ready status to unknown when no status is set - if stream.Status.Conditions == nil || len(stream.Status.Conditions) == 0 { + if len(stream.Status.Conditions) == 0 { log.Info("Setting initial ready condition to unknown.") stream.Status.Conditions = updateReadyCondition(stream.Status.Conditions, v1.ConditionUnknown, "Reconciling", "Starting reconciliation") err := r.Status().Update(ctx, stream) @@ -115,7 +116,6 @@ func (r *StreamReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr } func (r *StreamReconciler) deleteStream(ctx context.Context, log logr.Logger, stream *api.Stream) error { - // Set status to not false stream.Status.Conditions = updateReadyCondition(stream.Status.Conditions, v1.ConditionFalse, "Finalizing", "Performing finalizer operations.") if err := r.Status().Update(ctx, stream); err != nil { @@ -151,11 +151,9 @@ func (r *StreamReconciler) deleteStream(ctx context.Context, log logr.Logger, st } func (r *StreamReconciler) createOrUpdate(ctx context.Context, log logr.Logger, stream *api.Stream) error { - // Create or Update the stream based on the spec - if stream.Spec.PreventUpdate || r.ReadOnly() { + if r.ReadOnly() { log.Info("Skipping stream creation or update.", - "preventDelete", stream.Spec.PreventDelete, "read-only", r.ReadOnly(), ) return nil @@ -170,9 +168,31 @@ func (r *StreamReconciler) createOrUpdate(ctx context.Context, log logr.Logger, // CreateOrUpdateStream is called on every reconciliation when the stream is not to be deleted. // TODO(future-feature): Do we need to check if config differs? err = r.WithJetStreamClient(streamConnOpts(stream.Spec), func(js jetstream.JetStream) error { - log.Info("Creating or updating stream.") - _, err = js.CreateOrUpdateStream(ctx, targetConfig) - return err + exists := false + _, err := js.Stream(ctx, targetConfig.Name) + if err == nil { + exists = true + } else if !errors.Is(err, jetstream.ErrStreamNotFound) { + return err + } + + if !exists { + log.Info("Creating Stream.") + _, err := js.CreateStream(ctx, targetConfig) + return err + } + + if !stream.Spec.PreventUpdate { + log.Info("Updating Stream.") + _, err := js.UpdateStream(ctx, targetConfig) + return err + } else { + log.Info("Skipping Stream update.", + "preventUpdate", stream.Spec.PreventUpdate, + ) + } + + return nil }) if err != nil { err = fmt.Errorf("create or update stream: %w", err) @@ -212,7 +232,6 @@ func streamConnOpts(spec api.StreamSpec) *connectionOptions { // streamSpecToConfig creates a jetstream.StreamConfig matching the given stream resource spec func streamSpecToConfig(spec *api.StreamSpec) (jetstream.StreamConfig, error) { - // Set directly mapped fields config := jetstream.StreamConfig{ Name: spec.Name, @@ -293,7 +312,7 @@ func streamSpecToConfig(spec *api.StreamSpec) (jetstream.StreamConfig, error) { if spec.Mirror != nil { ss, err := mapStreamSource(spec.Mirror) if err != nil { - return jetstream.StreamConfig{}, fmt.Errorf("map mirror stream soruce: %w", err) + return jetstream.StreamConfig{}, fmt.Errorf("map mirror stream source: %w", err) } config.Mirror = ss } @@ -304,7 +323,7 @@ func streamSpecToConfig(spec *api.StreamSpec) (jetstream.StreamConfig, error) { for _, source := range spec.Sources { s, err := mapStreamSource(source) if err != nil { - return jetstream.StreamConfig{}, fmt.Errorf("map stream soruce: %w", err) + return jetstream.StreamConfig{}, fmt.Errorf("map stream source: %w", err) } config.Sources = append(config.Sources, s) } diff --git a/internal/controller/stream_controller_test.go b/internal/controller/stream_controller_test.go index e80d327b..e2506a7f 100644 --- a/internal/controller/stream_controller_test.go +++ b/internal/controller/stream_controller_test.go @@ -17,6 +17,9 @@ limitations under the License. package controller import ( + "testing" + "time" + "github.com/nats-io/nats.go/jetstream" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -27,8 +30,6 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "testing" - "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -36,7 +37,6 @@ import ( ) var _ = Describe("Stream Controller", func() { - // The test stream resource const resourceName = "test-stream" const streamName = "orders" @@ -136,9 +136,7 @@ var _ = Describe("Stream Controller", func() { }) When("reconciling a not initialized resource", func() { - It("should initialize a new resource", func(ctx SpecContext) { - By("re-queueing until it is initialized") // Initialization can require multiple reconciliation loops Eventually(func(ctx SpecContext) *api.Stream { @@ -160,11 +158,9 @@ var _ = Describe("Stream Controller", func() { assertReadyStateMatches(stream.Status.Conditions[0], v1.ConditionUnknown, "Reconciling", "Starting reconciliation", time.Now()) }) - }) When("reconciling an initialized resource", func() { - BeforeEach(func(ctx SpecContext) { By("initializing the stream resource") @@ -181,11 +177,9 @@ var _ = Describe("Stream Controller", func() { LastTransitionTime: time.Now().Format(time.RFC3339Nano), }} Expect(k8sClient.Status().Update(ctx, stream)).To(Succeed()) - }) It("should create a new stream", func(ctx SpecContext) { - By("running Reconcile") result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) Expect(err).NotTo(HaveOccurred()) @@ -212,21 +206,20 @@ var _ = Describe("Stream Controller", func() { }) When("PreventUpdate is set", func() { - BeforeEach(func(ctx SpecContext) { By("setting preventDelete on the resource") stream.Spec.PreventUpdate = true Expect(k8sClient.Update(ctx, stream)).To(Succeed()) }) - It("should not create the stream", func(ctx SpecContext) { + It("should create the stream", func(ctx SpecContext) { By("running Reconcile") result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) Expect(err).NotTo(HaveOccurred()) Expect(result.IsZero()).To(BeTrue()) - By("checking that no stream was created") + By("checking that stream was created") _, err = jsClient.Stream(ctx, streamName) - Expect(err).To(MatchError(jetstream.ErrStreamNotFound)) + Expect(err).NotTo(HaveOccurred()) }) It("should not update the stream", func(ctx SpecContext) { By("creating the stream") @@ -240,12 +233,12 @@ var _ = Describe("Stream Controller", func() { By("checking that stream was not updated") s, err := jsClient.Stream(ctx, streamName) + Expect(err).NotTo(HaveOccurred()) Expect(s.CachedInfo().Config.Description).To(BeEmpty()) }) }) When("read-only mode is enabled", func() { - BeforeEach(func(ctx SpecContext) { By("setting read only on the controller") readOnly, err := NewJSController(k8sClient, &NatsConfig{ServerURL: testServer.ClientURL()}, &Config{ReadOnly: true}) @@ -277,12 +270,12 @@ var _ = Describe("Stream Controller", func() { By("checking that stream was not updated") s, err := jsClient.Stream(ctx, streamName) + Expect(err).NotTo(HaveOccurred()) Expect(s.CachedInfo().Config.Description).To(BeEmpty()) }) }) When("namespace restriction is enabled", func() { - BeforeEach(func(ctx SpecContext) { By("setting a namespace on the resource") namespaced, err := NewJSController(k8sClient, &NatsConfig{ServerURL: testServer.ClientURL()}, &Config{Namespace: "other-namespace"}) @@ -314,6 +307,7 @@ var _ = Describe("Stream Controller", func() { By("checking that stream was not updated") s, err := jsClient.Stream(ctx, streamName) + Expect(err).NotTo(HaveOccurred()) Expect(s.CachedInfo().Config.Description).To(BeEmpty()) }) }) @@ -359,7 +353,6 @@ var _ = Describe("Stream Controller", func() { }) It("should set an error state when the nats server is not available", func(ctx SpecContext) { - By("setting up controller with unavailable nats server") // Setup client for not running server // Use actual test server to ensure port not used by other service on test instance @@ -398,7 +391,6 @@ var _ = Describe("Stream Controller", func() { }) When("the resource is marked for deletion", func() { - BeforeEach(func(ctx SpecContext) { By("marking the resource for deletion") Expect(k8sClient.Delete(ctx, stream)).To(Succeed()) @@ -480,7 +472,6 @@ var _ = Describe("Stream Controller", func() { } }) It("should delete the resource and not delete the stream", func(ctx SpecContext) { - By("reconciling") result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) Expect(err).NotTo(HaveOccurred()) @@ -506,7 +497,6 @@ var _ = Describe("Stream Controller", func() { } }) It("should not delete the resource and stream", func(ctx SpecContext) { - By("reconciling") result, err := controller.Reconcile(ctx, ctrl.Request{NamespacedName: typeNamespacedName}) Expect(err).NotTo(HaveOccurred()) @@ -535,7 +525,7 @@ var _ = Describe("Stream Controller", func() { Expect(k8sClient.Update(ctx, stream)).To(Succeed()) By("checking precondition, that the stream does not yet exist") - got, err := jsClient.Stream(ctx, streamName) + _, err := jsClient.Stream(ctx, streamName) Expect(err).To(MatchError(jetstream.ErrStreamNotFound)) By("reconciling the resource") @@ -550,21 +540,19 @@ var _ = Describe("Stream Controller", func() { defer closer.Close() Expect(err).NotTo(HaveOccurred()) - got, err = altClient.Stream(ctx, streamName) + got, err := altClient.Stream(ctx, streamName) Expect(err).NotTo(HaveOccurred()) Expect(got.CachedInfo().Created).To(BeTemporally("~", time.Now(), time.Second)) By("checking that the stream was NOT created on the original server") _, err = jsClient.Stream(ctx, streamName) Expect(err).To(MatchError(jetstream.ErrStreamNotFound)) - }) }) }) func Test_mapSpecToConfig(t *testing.T) { - - date := time.Date(2024, 12, 03, 16, 55, 5, 0, time.UTC) + date := time.Date(2024, 12, 3, 16, 55, 5, 0, time.UTC) dateString := date.Format(time.RFC3339) tests := []struct { diff --git a/internal/controller/suite_test.go b/internal/controller/suite_test.go index dc7a59b9..75bf60f5 100644 --- a/internal/controller/suite_test.go +++ b/internal/controller/suite_test.go @@ -18,13 +18,14 @@ package controller import ( "fmt" - "github.com/nats-io/nats-server/v2/server" - "github.com/nats-io/nats.go/jetstream" "os" "path/filepath" "runtime" "testing" + "github.com/nats-io/nats-server/v2/server" + "github.com/nats-io/nats.go/jetstream" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -41,12 +42,14 @@ import ( // These tests use Ginkgo (BDD-style Go testing framework). Refer to // http://onsi.github.io/ginkgo/ to learn more about Ginkgo. -var cfg *rest.Config -var k8sClient client.Client -var testEnv *envtest.Environment -var testServer *server.Server -var jsClient jetstream.JetStream -var baseController JetStreamController +var ( + cfg *rest.Config + k8sClient client.Client + testEnv *envtest.Environment + testServer *server.Server + jsClient jetstream.JetStream + baseController JetStreamController +) func TestControllers(t *testing.T) { RegisterFailHandler(Fail) @@ -68,7 +71,7 @@ var _ = BeforeSuite(func() { // Note that you must have the required binaries setup under the bin directory to perform // the tests directly. When we run make test it will be setup and used automatically. BinaryAssetsDirectory: filepath.Join("..", "..", "bin", "k8s", - fmt.Sprintf("1.29.0-%s-%s", runtime.GOOS, runtime.GOARCH)), + fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), } var err error @@ -90,7 +93,9 @@ var _ = BeforeSuite(func() { testNatsConfig := &NatsConfig{ServerURL: testServer.ClientURL()} baseController, err = NewJSController(k8sClient, testNatsConfig, &Config{}) + Expect(err).NotTo(HaveOccurred()) jsClient, _, err = CreateJetStreamClient(testNatsConfig, true) + Expect(err).NotTo(HaveOccurred()) }) var _ = AfterSuite(func() { diff --git a/internal/controller/types.go b/internal/controller/types.go index de166267..bc3b20c3 100644 --- a/internal/controller/types.go +++ b/internal/controller/types.go @@ -3,5 +3,6 @@ package controller const ( readyCondType = "Ready" streamFinalizer = "stream.nats.io/finalizer" + keyValueFinalizer = "keyvalue.nats.io/finalizer" consumerFinalizer = "consumer.nats.io/finalizer" ) diff --git a/pkg/bootconfig/bootconfig.go b/pkg/bootconfig/bootconfig.go index d4dd50ca..ddbe8c1c 100644 --- a/pkg/bootconfig/bootconfig.go +++ b/pkg/bootconfig/bootconfig.go @@ -121,7 +121,7 @@ func (c *Controller) Run(ctx context.Context) error { clientAdvertiseConfig := fmt.Sprintf("\nclient_advertise = \"%s\"\n\n", externalAddress) - err = os.WriteFile(c.opts.ClientAdvertiseFileName, []byte(clientAdvertiseConfig), 0644) + err = os.WriteFile(c.opts.ClientAdvertiseFileName, []byte(clientAdvertiseConfig), 0o644) if err != nil { return fmt.Errorf("Could not write client advertise config: %s", err) } @@ -129,7 +129,7 @@ func (c *Controller) Run(ctx context.Context) error { gatewayAdvertiseConfig := fmt.Sprintf("\nadvertise = \"%s\"\n\n", externalAddress) - err = os.WriteFile(c.opts.GatewayAdvertiseFileName, []byte(gatewayAdvertiseConfig), 0644) + err = os.WriteFile(c.opts.GatewayAdvertiseFileName, []byte(gatewayAdvertiseConfig), 0o644) if err != nil { return fmt.Errorf("Could not write gateway advertise config: %s", err) } diff --git a/pkg/jetstream/apis/jetstream/v1beta1/zz_generated.deepcopy.go b/pkg/jetstream/apis/jetstream/v1beta1/zz_generated.deepcopy.go index ce7e3e7e..25749171 100644 --- a/pkg/jetstream/apis/jetstream/v1beta1/zz_generated.deepcopy.go +++ b/pkg/jetstream/apis/jetstream/v1beta1/zz_generated.deepcopy.go @@ -1,7 +1,7 @@ //go:build !ignore_autogenerated // +build !ignore_autogenerated -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/apis/jetstream/v1beta2/keyvaluetypes.go b/pkg/jetstream/apis/jetstream/v1beta2/keyvaluetypes.go new file mode 100644 index 00000000..03bc9dbe --- /dev/null +++ b/pkg/jetstream/apis/jetstream/v1beta2/keyvaluetypes.go @@ -0,0 +1,55 @@ +package v1beta2 + +import ( + k8smeta "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// Stream is a specification for a Stream resource +type KeyValue struct { + k8smeta.TypeMeta `json:",inline"` + k8smeta.ObjectMeta `json:"metadata,omitempty"` + + Spec KeyValueSpec `json:"spec"` + Status Status `json:"status"` +} + +func (s *KeyValue) GetSpec() interface{} { + return s.Spec +} + +// StreamSpec is the spec for a Stream resource +type KeyValueSpec struct { + Account string `json:"account"` + Compression bool `json:"compression"` + Creds string `json:"creds"` + Description string `json:"description"` + History int `json:"history"` + MaxBytes int `json:"maxBytes"` + MaxValueSize int `json:"maxValueSize"` + Mirror *StreamSource `json:"mirror"` + Name string `json:"name"` + Nkey string `json:"nkey"` + Placement *StreamPlacement `json:"placement"` + PreventDelete bool `json:"preventDelete"` + PreventUpdate bool `json:"preventUpdate"` + Replicas int `json:"replicas"` + Republish *RePublish `json:"republish"` + Servers []string `json:"servers"` + Sources []*StreamSource `json:"sources"` + Storage string `json:"storage"` + TLS TLS `json:"tls"` + TTL string `json:"ttl"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// KeyValueList is a list of Stream resources +type KeyValueList struct { + k8smeta.TypeMeta `json:",inline"` + k8smeta.ListMeta `json:"metadata"` + + Items []KeyValue `json:"items"` +} diff --git a/pkg/jetstream/apis/jetstream/v1beta2/register.go b/pkg/jetstream/apis/jetstream/v1beta2/register.go index a2f25342..881fe90a 100644 --- a/pkg/jetstream/apis/jetstream/v1beta2/register.go +++ b/pkg/jetstream/apis/jetstream/v1beta2/register.go @@ -33,6 +33,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &Stream{}, &StreamList{}, + &KeyValue{}, + &KeyValueList{}, &Consumer{}, &ConsumerList{}, &Account{}, diff --git a/pkg/jetstream/apis/jetstream/v1beta2/zz_generated.deepcopy.go b/pkg/jetstream/apis/jetstream/v1beta2/zz_generated.deepcopy.go index 20ec90b1..23e4a228 100644 --- a/pkg/jetstream/apis/jetstream/v1beta2/zz_generated.deepcopy.go +++ b/pkg/jetstream/apis/jetstream/v1beta2/zz_generated.deepcopy.go @@ -1,7 +1,7 @@ //go:build !ignore_autogenerated // +build !ignore_autogenerated -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -263,6 +263,115 @@ func (in *CredsSecret) DeepCopy() *CredsSecret { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KeyValue) DeepCopyInto(out *KeyValue) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeyValue. +func (in *KeyValue) DeepCopy() *KeyValue { + if in == nil { + return nil + } + out := new(KeyValue) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *KeyValue) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KeyValueList) DeepCopyInto(out *KeyValueList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]KeyValue, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeyValueList. +func (in *KeyValueList) DeepCopy() *KeyValueList { + if in == nil { + return nil + } + out := new(KeyValueList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *KeyValueList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KeyValueSpec) DeepCopyInto(out *KeyValueSpec) { + *out = *in + if in.Mirror != nil { + in, out := &in.Mirror, &out.Mirror + *out = new(StreamSource) + (*in).DeepCopyInto(*out) + } + if in.Placement != nil { + in, out := &in.Placement, &out.Placement + *out = new(StreamPlacement) + (*in).DeepCopyInto(*out) + } + if in.Republish != nil { + in, out := &in.Republish, &out.Republish + *out = new(RePublish) + **out = **in + } + if in.Servers != nil { + in, out := &in.Servers, &out.Servers + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Sources != nil { + in, out := &in.Sources, &out.Sources + *out = make([]*StreamSource, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(StreamSource) + (*in).DeepCopyInto(*out) + } + } + } + in.TLS.DeepCopyInto(&out.TLS) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeyValueSpec. +func (in *KeyValueSpec) DeepCopy() *KeyValueSpec { + if in == nil { + return nil + } + out := new(KeyValueSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RePublish) DeepCopyInto(out *RePublish) { *out = *in diff --git a/pkg/jetstream/generated/applyconfiguration/internal/internal.go b/pkg/jetstream/generated/applyconfiguration/internal/internal.go index 63b69d16..083dbf96 100644 --- a/pkg/jetstream/generated/applyconfiguration/internal/internal.go +++ b/pkg/jetstream/generated/applyconfiguration/internal/internal.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,8 +16,8 @@ package internal import ( - "fmt" - "sync" + fmt "fmt" + sync "sync" typed "sigs.k8s.io/structured-merge-diff/v4/typed" ) diff --git a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/account.go b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/account.go index 42b91e90..3ff85c0f 100644 --- a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/account.go +++ b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/account.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -45,7 +45,7 @@ func Account(name, namespace string) *AccountApplyConfiguration { // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Kind field is set to the value of the last call. func (b *AccountApplyConfiguration) WithKind(value string) *AccountApplyConfiguration { - b.Kind = &value + b.TypeMetaApplyConfiguration.Kind = &value return b } @@ -53,7 +53,7 @@ func (b *AccountApplyConfiguration) WithKind(value string) *AccountApplyConfigur // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the APIVersion field is set to the value of the last call. func (b *AccountApplyConfiguration) WithAPIVersion(value string) *AccountApplyConfiguration { - b.APIVersion = &value + b.TypeMetaApplyConfiguration.APIVersion = &value return b } @@ -62,7 +62,7 @@ func (b *AccountApplyConfiguration) WithAPIVersion(value string) *AccountApplyCo // If called multiple times, the Name field is set to the value of the last call. func (b *AccountApplyConfiguration) WithName(value string) *AccountApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.Name = &value + b.ObjectMetaApplyConfiguration.Name = &value return b } @@ -71,7 +71,7 @@ func (b *AccountApplyConfiguration) WithName(value string) *AccountApplyConfigur // If called multiple times, the GenerateName field is set to the value of the last call. func (b *AccountApplyConfiguration) WithGenerateName(value string) *AccountApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.GenerateName = &value + b.ObjectMetaApplyConfiguration.GenerateName = &value return b } @@ -80,7 +80,7 @@ func (b *AccountApplyConfiguration) WithGenerateName(value string) *AccountApply // If called multiple times, the Namespace field is set to the value of the last call. func (b *AccountApplyConfiguration) WithNamespace(value string) *AccountApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.Namespace = &value + b.ObjectMetaApplyConfiguration.Namespace = &value return b } @@ -89,7 +89,7 @@ func (b *AccountApplyConfiguration) WithNamespace(value string) *AccountApplyCon // If called multiple times, the UID field is set to the value of the last call. func (b *AccountApplyConfiguration) WithUID(value types.UID) *AccountApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.UID = &value + b.ObjectMetaApplyConfiguration.UID = &value return b } @@ -98,7 +98,7 @@ func (b *AccountApplyConfiguration) WithUID(value types.UID) *AccountApplyConfig // If called multiple times, the ResourceVersion field is set to the value of the last call. func (b *AccountApplyConfiguration) WithResourceVersion(value string) *AccountApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.ResourceVersion = &value + b.ObjectMetaApplyConfiguration.ResourceVersion = &value return b } @@ -107,7 +107,7 @@ func (b *AccountApplyConfiguration) WithResourceVersion(value string) *AccountAp // If called multiple times, the Generation field is set to the value of the last call. func (b *AccountApplyConfiguration) WithGeneration(value int64) *AccountApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.Generation = &value + b.ObjectMetaApplyConfiguration.Generation = &value return b } @@ -116,7 +116,7 @@ func (b *AccountApplyConfiguration) WithGeneration(value int64) *AccountApplyCon // If called multiple times, the CreationTimestamp field is set to the value of the last call. func (b *AccountApplyConfiguration) WithCreationTimestamp(value metav1.Time) *AccountApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.CreationTimestamp = &value + b.ObjectMetaApplyConfiguration.CreationTimestamp = &value return b } @@ -125,7 +125,7 @@ func (b *AccountApplyConfiguration) WithCreationTimestamp(value metav1.Time) *Ac // If called multiple times, the DeletionTimestamp field is set to the value of the last call. func (b *AccountApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *AccountApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.DeletionTimestamp = &value + b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value return b } @@ -134,7 +134,7 @@ func (b *AccountApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *Ac // If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. func (b *AccountApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *AccountApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.DeletionGracePeriodSeconds = &value + b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value return b } @@ -144,11 +144,11 @@ func (b *AccountApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) // overwriting an existing map entries in Labels field with the same key. func (b *AccountApplyConfiguration) WithLabels(entries map[string]string) *AccountApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - if b.Labels == nil && len(entries) > 0 { - b.Labels = make(map[string]string, len(entries)) + if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries)) } for k, v := range entries { - b.Labels[k] = v + b.ObjectMetaApplyConfiguration.Labels[k] = v } return b } @@ -159,11 +159,11 @@ func (b *AccountApplyConfiguration) WithLabels(entries map[string]string) *Accou // overwriting an existing map entries in Annotations field with the same key. func (b *AccountApplyConfiguration) WithAnnotations(entries map[string]string) *AccountApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - if b.Annotations == nil && len(entries) > 0 { - b.Annotations = make(map[string]string, len(entries)) + if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries)) } for k, v := range entries { - b.Annotations[k] = v + b.ObjectMetaApplyConfiguration.Annotations[k] = v } return b } @@ -177,7 +177,7 @@ func (b *AccountApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerRefer if values[i] == nil { panic("nil value passed to WithOwnerReferences") } - b.OwnerReferences = append(b.OwnerReferences, *values[i]) + b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i]) } return b } @@ -188,7 +188,7 @@ func (b *AccountApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerRefer func (b *AccountApplyConfiguration) WithFinalizers(values ...string) *AccountApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() for i := range values { - b.Finalizers = append(b.Finalizers, values[i]) + b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i]) } return b } @@ -218,5 +218,5 @@ func (b *AccountApplyConfiguration) WithStatus(value *StatusApplyConfiguration) // GetName retrieves the value of the Name field in the declarative configuration. func (b *AccountApplyConfiguration) GetName() *string { b.ensureObjectMetaApplyConfigurationExists() - return b.Name + return b.ObjectMetaApplyConfiguration.Name } diff --git a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/accountspec.go b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/accountspec.go index 8f916234..cdfbcac8 100644 --- a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/accountspec.go +++ b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/accountspec.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/condition.go b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/condition.go index de299362..ec80bbe4 100644 --- a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/condition.go +++ b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/condition.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/consumer.go b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/consumer.go index e9cbc92f..731260f9 100644 --- a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/consumer.go +++ b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/consumer.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -45,7 +45,7 @@ func Consumer(name, namespace string) *ConsumerApplyConfiguration { // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Kind field is set to the value of the last call. func (b *ConsumerApplyConfiguration) WithKind(value string) *ConsumerApplyConfiguration { - b.Kind = &value + b.TypeMetaApplyConfiguration.Kind = &value return b } @@ -53,7 +53,7 @@ func (b *ConsumerApplyConfiguration) WithKind(value string) *ConsumerApplyConfig // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the APIVersion field is set to the value of the last call. func (b *ConsumerApplyConfiguration) WithAPIVersion(value string) *ConsumerApplyConfiguration { - b.APIVersion = &value + b.TypeMetaApplyConfiguration.APIVersion = &value return b } @@ -62,7 +62,7 @@ func (b *ConsumerApplyConfiguration) WithAPIVersion(value string) *ConsumerApply // If called multiple times, the Name field is set to the value of the last call. func (b *ConsumerApplyConfiguration) WithName(value string) *ConsumerApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.Name = &value + b.ObjectMetaApplyConfiguration.Name = &value return b } @@ -71,7 +71,7 @@ func (b *ConsumerApplyConfiguration) WithName(value string) *ConsumerApplyConfig // If called multiple times, the GenerateName field is set to the value of the last call. func (b *ConsumerApplyConfiguration) WithGenerateName(value string) *ConsumerApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.GenerateName = &value + b.ObjectMetaApplyConfiguration.GenerateName = &value return b } @@ -80,7 +80,7 @@ func (b *ConsumerApplyConfiguration) WithGenerateName(value string) *ConsumerApp // If called multiple times, the Namespace field is set to the value of the last call. func (b *ConsumerApplyConfiguration) WithNamespace(value string) *ConsumerApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.Namespace = &value + b.ObjectMetaApplyConfiguration.Namespace = &value return b } @@ -89,7 +89,7 @@ func (b *ConsumerApplyConfiguration) WithNamespace(value string) *ConsumerApplyC // If called multiple times, the UID field is set to the value of the last call. func (b *ConsumerApplyConfiguration) WithUID(value types.UID) *ConsumerApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.UID = &value + b.ObjectMetaApplyConfiguration.UID = &value return b } @@ -98,7 +98,7 @@ func (b *ConsumerApplyConfiguration) WithUID(value types.UID) *ConsumerApplyConf // If called multiple times, the ResourceVersion field is set to the value of the last call. func (b *ConsumerApplyConfiguration) WithResourceVersion(value string) *ConsumerApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.ResourceVersion = &value + b.ObjectMetaApplyConfiguration.ResourceVersion = &value return b } @@ -107,7 +107,7 @@ func (b *ConsumerApplyConfiguration) WithResourceVersion(value string) *Consumer // If called multiple times, the Generation field is set to the value of the last call. func (b *ConsumerApplyConfiguration) WithGeneration(value int64) *ConsumerApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.Generation = &value + b.ObjectMetaApplyConfiguration.Generation = &value return b } @@ -116,7 +116,7 @@ func (b *ConsumerApplyConfiguration) WithGeneration(value int64) *ConsumerApplyC // If called multiple times, the CreationTimestamp field is set to the value of the last call. func (b *ConsumerApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ConsumerApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.CreationTimestamp = &value + b.ObjectMetaApplyConfiguration.CreationTimestamp = &value return b } @@ -125,7 +125,7 @@ func (b *ConsumerApplyConfiguration) WithCreationTimestamp(value metav1.Time) *C // If called multiple times, the DeletionTimestamp field is set to the value of the last call. func (b *ConsumerApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ConsumerApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.DeletionTimestamp = &value + b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value return b } @@ -134,7 +134,7 @@ func (b *ConsumerApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *C // If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. func (b *ConsumerApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ConsumerApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.DeletionGracePeriodSeconds = &value + b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value return b } @@ -144,11 +144,11 @@ func (b *ConsumerApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) // overwriting an existing map entries in Labels field with the same key. func (b *ConsumerApplyConfiguration) WithLabels(entries map[string]string) *ConsumerApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - if b.Labels == nil && len(entries) > 0 { - b.Labels = make(map[string]string, len(entries)) + if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries)) } for k, v := range entries { - b.Labels[k] = v + b.ObjectMetaApplyConfiguration.Labels[k] = v } return b } @@ -159,11 +159,11 @@ func (b *ConsumerApplyConfiguration) WithLabels(entries map[string]string) *Cons // overwriting an existing map entries in Annotations field with the same key. func (b *ConsumerApplyConfiguration) WithAnnotations(entries map[string]string) *ConsumerApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - if b.Annotations == nil && len(entries) > 0 { - b.Annotations = make(map[string]string, len(entries)) + if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries)) } for k, v := range entries { - b.Annotations[k] = v + b.ObjectMetaApplyConfiguration.Annotations[k] = v } return b } @@ -177,7 +177,7 @@ func (b *ConsumerApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerRefe if values[i] == nil { panic("nil value passed to WithOwnerReferences") } - b.OwnerReferences = append(b.OwnerReferences, *values[i]) + b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i]) } return b } @@ -188,7 +188,7 @@ func (b *ConsumerApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerRefe func (b *ConsumerApplyConfiguration) WithFinalizers(values ...string) *ConsumerApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() for i := range values { - b.Finalizers = append(b.Finalizers, values[i]) + b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i]) } return b } @@ -218,5 +218,5 @@ func (b *ConsumerApplyConfiguration) WithStatus(value *StatusApplyConfiguration) // GetName retrieves the value of the Name field in the declarative configuration. func (b *ConsumerApplyConfiguration) GetName() *string { b.ensureObjectMetaApplyConfigurationExists() - return b.Name + return b.ObjectMetaApplyConfiguration.Name } diff --git a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/consumerspec.go b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/consumerspec.go index 8700fe3e..ca97ae62 100644 --- a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/consumerspec.go +++ b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/consumerspec.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/credssecret.go b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/credssecret.go index 467fb7a4..f7f3de8c 100644 --- a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/credssecret.go +++ b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/credssecret.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/keyvalue.go b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/keyvalue.go new file mode 100644 index 00000000..6b13dff1 --- /dev/null +++ b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/keyvalue.go @@ -0,0 +1,222 @@ +// Copyright 2025 The NATS Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta2 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// KeyValueApplyConfiguration represents a declarative configuration of the KeyValue type for use +// with apply. +type KeyValueApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + Spec *KeyValueSpecApplyConfiguration `json:"spec,omitempty"` + Status *StatusApplyConfiguration `json:"status,omitempty"` +} + +// KeyValue constructs a declarative configuration of the KeyValue type for use with +// apply. +func KeyValue(name, namespace string) *KeyValueApplyConfiguration { + b := &KeyValueApplyConfiguration{} + b.WithName(name) + b.WithNamespace(namespace) + b.WithKind("KeyValue") + b.WithAPIVersion("jetstream.nats.io/v1beta2") + return b +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *KeyValueApplyConfiguration) WithKind(value string) *KeyValueApplyConfiguration { + b.TypeMetaApplyConfiguration.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *KeyValueApplyConfiguration) WithAPIVersion(value string) *KeyValueApplyConfiguration { + b.TypeMetaApplyConfiguration.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *KeyValueApplyConfiguration) WithName(value string) *KeyValueApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *KeyValueApplyConfiguration) WithGenerateName(value string) *KeyValueApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *KeyValueApplyConfiguration) WithNamespace(value string) *KeyValueApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *KeyValueApplyConfiguration) WithUID(value types.UID) *KeyValueApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *KeyValueApplyConfiguration) WithResourceVersion(value string) *KeyValueApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *KeyValueApplyConfiguration) WithGeneration(value int64) *KeyValueApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *KeyValueApplyConfiguration) WithCreationTimestamp(value metav1.Time) *KeyValueApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *KeyValueApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *KeyValueApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *KeyValueApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *KeyValueApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *KeyValueApplyConfiguration) WithLabels(entries map[string]string) *KeyValueApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.ObjectMetaApplyConfiguration.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *KeyValueApplyConfiguration) WithAnnotations(entries map[string]string) *KeyValueApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.ObjectMetaApplyConfiguration.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *KeyValueApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *KeyValueApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *KeyValueApplyConfiguration) WithFinalizers(values ...string) *KeyValueApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i]) + } + return b +} + +func (b *KeyValueApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *KeyValueApplyConfiguration) WithSpec(value *KeyValueSpecApplyConfiguration) *KeyValueApplyConfiguration { + b.Spec = value + return b +} + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *KeyValueApplyConfiguration) WithStatus(value *StatusApplyConfiguration) *KeyValueApplyConfiguration { + b.Status = value + return b +} + +// GetName retrieves the value of the Name field in the declarative configuration. +func (b *KeyValueApplyConfiguration) GetName() *string { + b.ensureObjectMetaApplyConfigurationExists() + return b.ObjectMetaApplyConfiguration.Name +} diff --git a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/keyvaluespec.go b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/keyvaluespec.go new file mode 100644 index 00000000..a35967bf --- /dev/null +++ b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/keyvaluespec.go @@ -0,0 +1,218 @@ +// Copyright 2025 The NATS Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta2 + +import ( + jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" +) + +// KeyValueSpecApplyConfiguration represents a declarative configuration of the KeyValueSpec type for use +// with apply. +type KeyValueSpecApplyConfiguration struct { + Account *string `json:"account,omitempty"` + Compression *bool `json:"compression,omitempty"` + Creds *string `json:"creds,omitempty"` + Description *string `json:"description,omitempty"` + History *int `json:"history,omitempty"` + MaxBytes *int `json:"maxBytes,omitempty"` + MaxValueSize *int `json:"maxValueSize,omitempty"` + Mirror *StreamSourceApplyConfiguration `json:"mirror,omitempty"` + Name *string `json:"name,omitempty"` + Nkey *string `json:"nkey,omitempty"` + Placement *StreamPlacementApplyConfiguration `json:"placement,omitempty"` + PreventDelete *bool `json:"preventDelete,omitempty"` + PreventUpdate *bool `json:"preventUpdate,omitempty"` + Replicas *int `json:"replicas,omitempty"` + Republish *RePublishApplyConfiguration `json:"republish,omitempty"` + Servers []string `json:"servers,omitempty"` + Sources []*jetstreamv1beta2.StreamSource `json:"sources,omitempty"` + Storage *string `json:"storage,omitempty"` + TLS *TLSApplyConfiguration `json:"tls,omitempty"` + TTL *string `json:"ttl,omitempty"` +} + +// KeyValueSpecApplyConfiguration constructs a declarative configuration of the KeyValueSpec type for use with +// apply. +func KeyValueSpec() *KeyValueSpecApplyConfiguration { + return &KeyValueSpecApplyConfiguration{} +} + +// WithAccount sets the Account field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Account field is set to the value of the last call. +func (b *KeyValueSpecApplyConfiguration) WithAccount(value string) *KeyValueSpecApplyConfiguration { + b.Account = &value + return b +} + +// WithCompression sets the Compression field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Compression field is set to the value of the last call. +func (b *KeyValueSpecApplyConfiguration) WithCompression(value bool) *KeyValueSpecApplyConfiguration { + b.Compression = &value + return b +} + +// WithCreds sets the Creds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Creds field is set to the value of the last call. +func (b *KeyValueSpecApplyConfiguration) WithCreds(value string) *KeyValueSpecApplyConfiguration { + b.Creds = &value + return b +} + +// WithDescription sets the Description field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Description field is set to the value of the last call. +func (b *KeyValueSpecApplyConfiguration) WithDescription(value string) *KeyValueSpecApplyConfiguration { + b.Description = &value + return b +} + +// WithHistory sets the History field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the History field is set to the value of the last call. +func (b *KeyValueSpecApplyConfiguration) WithHistory(value int) *KeyValueSpecApplyConfiguration { + b.History = &value + return b +} + +// WithMaxBytes sets the MaxBytes field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the MaxBytes field is set to the value of the last call. +func (b *KeyValueSpecApplyConfiguration) WithMaxBytes(value int) *KeyValueSpecApplyConfiguration { + b.MaxBytes = &value + return b +} + +// WithMaxValueSize sets the MaxValueSize field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the MaxValueSize field is set to the value of the last call. +func (b *KeyValueSpecApplyConfiguration) WithMaxValueSize(value int) *KeyValueSpecApplyConfiguration { + b.MaxValueSize = &value + return b +} + +// WithMirror sets the Mirror field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Mirror field is set to the value of the last call. +func (b *KeyValueSpecApplyConfiguration) WithMirror(value *StreamSourceApplyConfiguration) *KeyValueSpecApplyConfiguration { + b.Mirror = value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *KeyValueSpecApplyConfiguration) WithName(value string) *KeyValueSpecApplyConfiguration { + b.Name = &value + return b +} + +// WithNkey sets the Nkey field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Nkey field is set to the value of the last call. +func (b *KeyValueSpecApplyConfiguration) WithNkey(value string) *KeyValueSpecApplyConfiguration { + b.Nkey = &value + return b +} + +// WithPlacement sets the Placement field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Placement field is set to the value of the last call. +func (b *KeyValueSpecApplyConfiguration) WithPlacement(value *StreamPlacementApplyConfiguration) *KeyValueSpecApplyConfiguration { + b.Placement = value + return b +} + +// WithPreventDelete sets the PreventDelete field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PreventDelete field is set to the value of the last call. +func (b *KeyValueSpecApplyConfiguration) WithPreventDelete(value bool) *KeyValueSpecApplyConfiguration { + b.PreventDelete = &value + return b +} + +// WithPreventUpdate sets the PreventUpdate field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PreventUpdate field is set to the value of the last call. +func (b *KeyValueSpecApplyConfiguration) WithPreventUpdate(value bool) *KeyValueSpecApplyConfiguration { + b.PreventUpdate = &value + return b +} + +// WithReplicas sets the Replicas field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Replicas field is set to the value of the last call. +func (b *KeyValueSpecApplyConfiguration) WithReplicas(value int) *KeyValueSpecApplyConfiguration { + b.Replicas = &value + return b +} + +// WithRepublish sets the Republish field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Republish field is set to the value of the last call. +func (b *KeyValueSpecApplyConfiguration) WithRepublish(value *RePublishApplyConfiguration) *KeyValueSpecApplyConfiguration { + b.Republish = value + return b +} + +// WithServers adds the given value to the Servers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Servers field. +func (b *KeyValueSpecApplyConfiguration) WithServers(values ...string) *KeyValueSpecApplyConfiguration { + for i := range values { + b.Servers = append(b.Servers, values[i]) + } + return b +} + +// WithSources adds the given value to the Sources field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Sources field. +func (b *KeyValueSpecApplyConfiguration) WithSources(values ...**jetstreamv1beta2.StreamSource) *KeyValueSpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithSources") + } + b.Sources = append(b.Sources, *values[i]) + } + return b +} + +// WithStorage sets the Storage field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Storage field is set to the value of the last call. +func (b *KeyValueSpecApplyConfiguration) WithStorage(value string) *KeyValueSpecApplyConfiguration { + b.Storage = &value + return b +} + +// WithTLS sets the TLS field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the TLS field is set to the value of the last call. +func (b *KeyValueSpecApplyConfiguration) WithTLS(value *TLSApplyConfiguration) *KeyValueSpecApplyConfiguration { + b.TLS = value + return b +} + +// WithTTL sets the TTL field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the TTL field is set to the value of the last call. +func (b *KeyValueSpecApplyConfiguration) WithTTL(value string) *KeyValueSpecApplyConfiguration { + b.TTL = &value + return b +} diff --git a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/republish.go b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/republish.go index 45873e7e..6a57feb2 100644 --- a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/republish.go +++ b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/republish.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/secretref.go b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/secretref.go index 57754747..e1ce93bd 100644 --- a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/secretref.go +++ b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/secretref.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/status.go b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/status.go index cebedf26..b7b8e484 100644 --- a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/status.go +++ b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/status.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/stream.go b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/stream.go index dc987f23..f363d091 100644 --- a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/stream.go +++ b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/stream.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -45,7 +45,7 @@ func Stream(name, namespace string) *StreamApplyConfiguration { // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Kind field is set to the value of the last call. func (b *StreamApplyConfiguration) WithKind(value string) *StreamApplyConfiguration { - b.Kind = &value + b.TypeMetaApplyConfiguration.Kind = &value return b } @@ -53,7 +53,7 @@ func (b *StreamApplyConfiguration) WithKind(value string) *StreamApplyConfigurat // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the APIVersion field is set to the value of the last call. func (b *StreamApplyConfiguration) WithAPIVersion(value string) *StreamApplyConfiguration { - b.APIVersion = &value + b.TypeMetaApplyConfiguration.APIVersion = &value return b } @@ -62,7 +62,7 @@ func (b *StreamApplyConfiguration) WithAPIVersion(value string) *StreamApplyConf // If called multiple times, the Name field is set to the value of the last call. func (b *StreamApplyConfiguration) WithName(value string) *StreamApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.Name = &value + b.ObjectMetaApplyConfiguration.Name = &value return b } @@ -71,7 +71,7 @@ func (b *StreamApplyConfiguration) WithName(value string) *StreamApplyConfigurat // If called multiple times, the GenerateName field is set to the value of the last call. func (b *StreamApplyConfiguration) WithGenerateName(value string) *StreamApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.GenerateName = &value + b.ObjectMetaApplyConfiguration.GenerateName = &value return b } @@ -80,7 +80,7 @@ func (b *StreamApplyConfiguration) WithGenerateName(value string) *StreamApplyCo // If called multiple times, the Namespace field is set to the value of the last call. func (b *StreamApplyConfiguration) WithNamespace(value string) *StreamApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.Namespace = &value + b.ObjectMetaApplyConfiguration.Namespace = &value return b } @@ -89,7 +89,7 @@ func (b *StreamApplyConfiguration) WithNamespace(value string) *StreamApplyConfi // If called multiple times, the UID field is set to the value of the last call. func (b *StreamApplyConfiguration) WithUID(value types.UID) *StreamApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.UID = &value + b.ObjectMetaApplyConfiguration.UID = &value return b } @@ -98,7 +98,7 @@ func (b *StreamApplyConfiguration) WithUID(value types.UID) *StreamApplyConfigur // If called multiple times, the ResourceVersion field is set to the value of the last call. func (b *StreamApplyConfiguration) WithResourceVersion(value string) *StreamApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.ResourceVersion = &value + b.ObjectMetaApplyConfiguration.ResourceVersion = &value return b } @@ -107,7 +107,7 @@ func (b *StreamApplyConfiguration) WithResourceVersion(value string) *StreamAppl // If called multiple times, the Generation field is set to the value of the last call. func (b *StreamApplyConfiguration) WithGeneration(value int64) *StreamApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.Generation = &value + b.ObjectMetaApplyConfiguration.Generation = &value return b } @@ -116,7 +116,7 @@ func (b *StreamApplyConfiguration) WithGeneration(value int64) *StreamApplyConfi // If called multiple times, the CreationTimestamp field is set to the value of the last call. func (b *StreamApplyConfiguration) WithCreationTimestamp(value metav1.Time) *StreamApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.CreationTimestamp = &value + b.ObjectMetaApplyConfiguration.CreationTimestamp = &value return b } @@ -125,7 +125,7 @@ func (b *StreamApplyConfiguration) WithCreationTimestamp(value metav1.Time) *Str // If called multiple times, the DeletionTimestamp field is set to the value of the last call. func (b *StreamApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *StreamApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.DeletionTimestamp = &value + b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value return b } @@ -134,7 +134,7 @@ func (b *StreamApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *Str // If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. func (b *StreamApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *StreamApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - b.DeletionGracePeriodSeconds = &value + b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value return b } @@ -144,11 +144,11 @@ func (b *StreamApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) * // overwriting an existing map entries in Labels field with the same key. func (b *StreamApplyConfiguration) WithLabels(entries map[string]string) *StreamApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - if b.Labels == nil && len(entries) > 0 { - b.Labels = make(map[string]string, len(entries)) + if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries)) } for k, v := range entries { - b.Labels[k] = v + b.ObjectMetaApplyConfiguration.Labels[k] = v } return b } @@ -159,11 +159,11 @@ func (b *StreamApplyConfiguration) WithLabels(entries map[string]string) *Stream // overwriting an existing map entries in Annotations field with the same key. func (b *StreamApplyConfiguration) WithAnnotations(entries map[string]string) *StreamApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() - if b.Annotations == nil && len(entries) > 0 { - b.Annotations = make(map[string]string, len(entries)) + if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries)) } for k, v := range entries { - b.Annotations[k] = v + b.ObjectMetaApplyConfiguration.Annotations[k] = v } return b } @@ -177,7 +177,7 @@ func (b *StreamApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerRefere if values[i] == nil { panic("nil value passed to WithOwnerReferences") } - b.OwnerReferences = append(b.OwnerReferences, *values[i]) + b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i]) } return b } @@ -188,7 +188,7 @@ func (b *StreamApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerRefere func (b *StreamApplyConfiguration) WithFinalizers(values ...string) *StreamApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() for i := range values { - b.Finalizers = append(b.Finalizers, values[i]) + b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i]) } return b } @@ -218,5 +218,5 @@ func (b *StreamApplyConfiguration) WithStatus(value *StatusApplyConfiguration) * // GetName retrieves the value of the Name field in the declarative configuration. func (b *StreamApplyConfiguration) GetName() *string { b.ensureObjectMetaApplyConfigurationExists() - return b.Name + return b.ObjectMetaApplyConfiguration.Name } diff --git a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/streamplacement.go b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/streamplacement.go index 4063166e..b6834dd5 100644 --- a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/streamplacement.go +++ b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/streamplacement.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/streamsource.go b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/streamsource.go index 0d5e63f0..7fccc24f 100644 --- a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/streamsource.go +++ b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/streamsource.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,19 +16,19 @@ package v1beta2 import ( - v1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" + jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" ) // StreamSourceApplyConfiguration represents a declarative configuration of the StreamSource type for use // with apply. type StreamSourceApplyConfiguration struct { - Name *string `json:"name,omitempty"` - OptStartSeq *int `json:"optStartSeq,omitempty"` - OptStartTime *string `json:"optStartTime,omitempty"` - FilterSubject *string `json:"filterSubject,omitempty"` - ExternalAPIPrefix *string `json:"externalApiPrefix,omitempty"` - ExternalDeliverPrefix *string `json:"externalDeliverPrefix,omitempty"` - SubjectTransforms []*v1beta2.SubjectTransform `json:"subjectTransforms,omitempty"` + Name *string `json:"name,omitempty"` + OptStartSeq *int `json:"optStartSeq,omitempty"` + OptStartTime *string `json:"optStartTime,omitempty"` + FilterSubject *string `json:"filterSubject,omitempty"` + ExternalAPIPrefix *string `json:"externalApiPrefix,omitempty"` + ExternalDeliverPrefix *string `json:"externalDeliverPrefix,omitempty"` + SubjectTransforms []*jetstreamv1beta2.SubjectTransform `json:"subjectTransforms,omitempty"` } // StreamSourceApplyConfiguration constructs a declarative configuration of the StreamSource type for use with @@ -88,7 +88,7 @@ func (b *StreamSourceApplyConfiguration) WithExternalDeliverPrefix(value string) // WithSubjectTransforms adds the given value to the SubjectTransforms field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the SubjectTransforms field. -func (b *StreamSourceApplyConfiguration) WithSubjectTransforms(values ...**v1beta2.SubjectTransform) *StreamSourceApplyConfiguration { +func (b *StreamSourceApplyConfiguration) WithSubjectTransforms(values ...**jetstreamv1beta2.SubjectTransform) *StreamSourceApplyConfiguration { for i := range values { if values[i] == nil { panic("nil value passed to WithSubjectTransforms") diff --git a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/streamspec.go b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/streamspec.go index 7be89f6a..608a118d 100644 --- a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/streamspec.go +++ b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/streamspec.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/subjecttransform.go b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/subjecttransform.go index 98fc658b..ec7283fd 100644 --- a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/subjecttransform.go +++ b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/subjecttransform.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/tls.go b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/tls.go index 806a9ee5..0eb0ec56 100644 --- a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/tls.go +++ b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/tls.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/tlssecret.go b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/tlssecret.go index c593036f..530a415c 100644 --- a/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/tlssecret.go +++ b/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2/tlssecret.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/applyconfiguration/utils.go b/pkg/jetstream/generated/applyconfiguration/utils.go index 70bd2a00..f641a5b4 100644 --- a/pkg/jetstream/generated/applyconfiguration/utils.go +++ b/pkg/jetstream/generated/applyconfiguration/utils.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -41,6 +41,10 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &jetstreamv1beta2.ConsumerSpecApplyConfiguration{} case v1beta2.SchemeGroupVersion.WithKind("CredsSecret"): return &jetstreamv1beta2.CredsSecretApplyConfiguration{} + case v1beta2.SchemeGroupVersion.WithKind("KeyValue"): + return &jetstreamv1beta2.KeyValueApplyConfiguration{} + case v1beta2.SchemeGroupVersion.WithKind("KeyValueSpec"): + return &jetstreamv1beta2.KeyValueSpecApplyConfiguration{} case v1beta2.SchemeGroupVersion.WithKind("RePublish"): return &jetstreamv1beta2.RePublishApplyConfiguration{} case v1beta2.SchemeGroupVersion.WithKind("SecretRef"): diff --git a/pkg/jetstream/generated/clientset/versioned/clientset.go b/pkg/jetstream/generated/clientset/versioned/clientset.go index 79f86ce7..6ef82837 100644 --- a/pkg/jetstream/generated/clientset/versioned/clientset.go +++ b/pkg/jetstream/generated/clientset/versioned/clientset.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,8 +16,8 @@ package versioned import ( - "fmt" - "net/http" + fmt "fmt" + http "net/http" jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2" discovery "k8s.io/client-go/discovery" diff --git a/pkg/jetstream/generated/clientset/versioned/fake/clientset_generated.go b/pkg/jetstream/generated/clientset/versioned/fake/clientset_generated.go index 642b047b..ceb891d7 100644 --- a/pkg/jetstream/generated/clientset/versioned/fake/clientset_generated.go +++ b/pkg/jetstream/generated/clientset/versioned/fake/clientset_generated.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/clientset/versioned/fake/doc.go b/pkg/jetstream/generated/clientset/versioned/fake/doc.go index fc05515c..f3f6430c 100644 --- a/pkg/jetstream/generated/clientset/versioned/fake/doc.go +++ b/pkg/jetstream/generated/clientset/versioned/fake/doc.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/clientset/versioned/fake/register.go b/pkg/jetstream/generated/clientset/versioned/fake/register.go index c64246e0..aa9df72f 100644 --- a/pkg/jetstream/generated/clientset/versioned/fake/register.go +++ b/pkg/jetstream/generated/clientset/versioned/fake/register.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/clientset/versioned/scheme/doc.go b/pkg/jetstream/generated/clientset/versioned/scheme/doc.go index 31cfa974..2d5c26bc 100644 --- a/pkg/jetstream/generated/clientset/versioned/scheme/doc.go +++ b/pkg/jetstream/generated/clientset/versioned/scheme/doc.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/clientset/versioned/scheme/register.go b/pkg/jetstream/generated/clientset/versioned/scheme/register.go index c900985f..bd153a8c 100644 --- a/pkg/jetstream/generated/clientset/versioned/scheme/register.go +++ b/pkg/jetstream/generated/clientset/versioned/scheme/register.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/account.go b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/account.go index b495a525..9b6541bf 100644 --- a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/account.go +++ b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/account.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,10 +16,10 @@ package v1beta2 import ( - "context" + context "context" - v1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" - jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2" + jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" + applyconfigurationjetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2" scheme "github.com/nats-io/nack/pkg/jetstream/generated/clientset/versioned/scheme" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" @@ -35,36 +35,37 @@ type AccountsGetter interface { // AccountInterface has methods to work with Account resources. type AccountInterface interface { - Create(ctx context.Context, account *v1beta2.Account, opts v1.CreateOptions) (*v1beta2.Account, error) - Update(ctx context.Context, account *v1beta2.Account, opts v1.UpdateOptions) (*v1beta2.Account, error) + Create(ctx context.Context, account *jetstreamv1beta2.Account, opts v1.CreateOptions) (*jetstreamv1beta2.Account, error) + Update(ctx context.Context, account *jetstreamv1beta2.Account, opts v1.UpdateOptions) (*jetstreamv1beta2.Account, error) // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). - UpdateStatus(ctx context.Context, account *v1beta2.Account, opts v1.UpdateOptions) (*v1beta2.Account, error) + UpdateStatus(ctx context.Context, account *jetstreamv1beta2.Account, opts v1.UpdateOptions) (*jetstreamv1beta2.Account, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta2.Account, error) - List(ctx context.Context, opts v1.ListOptions) (*v1beta2.AccountList, error) + Get(ctx context.Context, name string, opts v1.GetOptions) (*jetstreamv1beta2.Account, error) + List(ctx context.Context, opts v1.ListOptions) (*jetstreamv1beta2.AccountList, error) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta2.Account, err error) - Apply(ctx context.Context, account *jetstreamv1beta2.AccountApplyConfiguration, opts v1.ApplyOptions) (result *v1beta2.Account, err error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *jetstreamv1beta2.Account, err error) + Apply(ctx context.Context, account *applyconfigurationjetstreamv1beta2.AccountApplyConfiguration, opts v1.ApplyOptions) (result *jetstreamv1beta2.Account, err error) // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). - ApplyStatus(ctx context.Context, account *jetstreamv1beta2.AccountApplyConfiguration, opts v1.ApplyOptions) (result *v1beta2.Account, err error) + ApplyStatus(ctx context.Context, account *applyconfigurationjetstreamv1beta2.AccountApplyConfiguration, opts v1.ApplyOptions) (result *jetstreamv1beta2.Account, err error) AccountExpansion } // accounts implements AccountInterface type accounts struct { - *gentype.ClientWithListAndApply[*v1beta2.Account, *v1beta2.AccountList, *jetstreamv1beta2.AccountApplyConfiguration] + *gentype.ClientWithListAndApply[*jetstreamv1beta2.Account, *jetstreamv1beta2.AccountList, *applyconfigurationjetstreamv1beta2.AccountApplyConfiguration] } // newAccounts returns a Accounts func newAccounts(c *JetstreamV1beta2Client, namespace string) *accounts { return &accounts{ - gentype.NewClientWithListAndApply[*v1beta2.Account, *v1beta2.AccountList, *jetstreamv1beta2.AccountApplyConfiguration]( + gentype.NewClientWithListAndApply[*jetstreamv1beta2.Account, *jetstreamv1beta2.AccountList, *applyconfigurationjetstreamv1beta2.AccountApplyConfiguration]( "accounts", c.RESTClient(), scheme.ParameterCodec, namespace, - func() *v1beta2.Account { return &v1beta2.Account{} }, - func() *v1beta2.AccountList { return &v1beta2.AccountList{} }), + func() *jetstreamv1beta2.Account { return &jetstreamv1beta2.Account{} }, + func() *jetstreamv1beta2.AccountList { return &jetstreamv1beta2.AccountList{} }, + ), } } diff --git a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/consumer.go b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/consumer.go index de230925..3560df58 100644 --- a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/consumer.go +++ b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/consumer.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,10 +16,10 @@ package v1beta2 import ( - "context" + context "context" - v1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" - jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2" + jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" + applyconfigurationjetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2" scheme "github.com/nats-io/nack/pkg/jetstream/generated/clientset/versioned/scheme" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" @@ -35,36 +35,37 @@ type ConsumersGetter interface { // ConsumerInterface has methods to work with Consumer resources. type ConsumerInterface interface { - Create(ctx context.Context, consumer *v1beta2.Consumer, opts v1.CreateOptions) (*v1beta2.Consumer, error) - Update(ctx context.Context, consumer *v1beta2.Consumer, opts v1.UpdateOptions) (*v1beta2.Consumer, error) + Create(ctx context.Context, consumer *jetstreamv1beta2.Consumer, opts v1.CreateOptions) (*jetstreamv1beta2.Consumer, error) + Update(ctx context.Context, consumer *jetstreamv1beta2.Consumer, opts v1.UpdateOptions) (*jetstreamv1beta2.Consumer, error) // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). - UpdateStatus(ctx context.Context, consumer *v1beta2.Consumer, opts v1.UpdateOptions) (*v1beta2.Consumer, error) + UpdateStatus(ctx context.Context, consumer *jetstreamv1beta2.Consumer, opts v1.UpdateOptions) (*jetstreamv1beta2.Consumer, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta2.Consumer, error) - List(ctx context.Context, opts v1.ListOptions) (*v1beta2.ConsumerList, error) + Get(ctx context.Context, name string, opts v1.GetOptions) (*jetstreamv1beta2.Consumer, error) + List(ctx context.Context, opts v1.ListOptions) (*jetstreamv1beta2.ConsumerList, error) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta2.Consumer, err error) - Apply(ctx context.Context, consumer *jetstreamv1beta2.ConsumerApplyConfiguration, opts v1.ApplyOptions) (result *v1beta2.Consumer, err error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *jetstreamv1beta2.Consumer, err error) + Apply(ctx context.Context, consumer *applyconfigurationjetstreamv1beta2.ConsumerApplyConfiguration, opts v1.ApplyOptions) (result *jetstreamv1beta2.Consumer, err error) // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). - ApplyStatus(ctx context.Context, consumer *jetstreamv1beta2.ConsumerApplyConfiguration, opts v1.ApplyOptions) (result *v1beta2.Consumer, err error) + ApplyStatus(ctx context.Context, consumer *applyconfigurationjetstreamv1beta2.ConsumerApplyConfiguration, opts v1.ApplyOptions) (result *jetstreamv1beta2.Consumer, err error) ConsumerExpansion } // consumers implements ConsumerInterface type consumers struct { - *gentype.ClientWithListAndApply[*v1beta2.Consumer, *v1beta2.ConsumerList, *jetstreamv1beta2.ConsumerApplyConfiguration] + *gentype.ClientWithListAndApply[*jetstreamv1beta2.Consumer, *jetstreamv1beta2.ConsumerList, *applyconfigurationjetstreamv1beta2.ConsumerApplyConfiguration] } // newConsumers returns a Consumers func newConsumers(c *JetstreamV1beta2Client, namespace string) *consumers { return &consumers{ - gentype.NewClientWithListAndApply[*v1beta2.Consumer, *v1beta2.ConsumerList, *jetstreamv1beta2.ConsumerApplyConfiguration]( + gentype.NewClientWithListAndApply[*jetstreamv1beta2.Consumer, *jetstreamv1beta2.ConsumerList, *applyconfigurationjetstreamv1beta2.ConsumerApplyConfiguration]( "consumers", c.RESTClient(), scheme.ParameterCodec, namespace, - func() *v1beta2.Consumer { return &v1beta2.Consumer{} }, - func() *v1beta2.ConsumerList { return &v1beta2.ConsumerList{} }), + func() *jetstreamv1beta2.Consumer { return &jetstreamv1beta2.Consumer{} }, + func() *jetstreamv1beta2.ConsumerList { return &jetstreamv1beta2.ConsumerList{} }, + ), } } diff --git a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/doc.go b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/doc.go index f278ba06..7db3dc1e 100644 --- a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/doc.go +++ b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/doc.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/doc.go b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/doc.go index bd8826c0..ef446d4a 100644 --- a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/doc.go +++ b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/doc.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/fake_account.go b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/fake_account.go index fa2a89e2..1caa3b4d 100644 --- a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/fake_account.go +++ b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/fake_account.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,179 +16,33 @@ package fake import ( - "context" - json "encoding/json" - "fmt" - v1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - labels "k8s.io/apimachinery/pkg/labels" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - testing "k8s.io/client-go/testing" + typedjetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2" + gentype "k8s.io/client-go/gentype" ) -// FakeAccounts implements AccountInterface -type FakeAccounts struct { +// fakeAccounts implements AccountInterface +type fakeAccounts struct { + *gentype.FakeClientWithListAndApply[*v1beta2.Account, *v1beta2.AccountList, *jetstreamv1beta2.AccountApplyConfiguration] Fake *FakeJetstreamV1beta2 - ns string -} - -var accountsResource = v1beta2.SchemeGroupVersion.WithResource("accounts") - -var accountsKind = v1beta2.SchemeGroupVersion.WithKind("Account") - -// Get takes name of the account, and returns the corresponding account object, and an error if there is any. -func (c *FakeAccounts) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta2.Account, err error) { - emptyResult := &v1beta2.Account{} - obj, err := c.Fake. - Invokes(testing.NewGetActionWithOptions(accountsResource, c.ns, name, options), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1beta2.Account), err -} - -// List takes label and field selectors, and returns the list of Accounts that match those selectors. -func (c *FakeAccounts) List(ctx context.Context, opts v1.ListOptions) (result *v1beta2.AccountList, err error) { - emptyResult := &v1beta2.AccountList{} - obj, err := c.Fake. - Invokes(testing.NewListActionWithOptions(accountsResource, accountsKind, c.ns, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - - label, _, _ := testing.ExtractFromListOptions(opts) - if label == nil { - label = labels.Everything() - } - list := &v1beta2.AccountList{ListMeta: obj.(*v1beta2.AccountList).ListMeta} - for _, item := range obj.(*v1beta2.AccountList).Items { - if label.Matches(labels.Set(item.Labels)) { - list.Items = append(list.Items, item) - } - } - return list, err -} - -// Watch returns a watch.Interface that watches the requested accounts. -func (c *FakeAccounts) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - return c.Fake. - InvokesWatch(testing.NewWatchActionWithOptions(accountsResource, c.ns, opts)) - -} - -// Create takes the representation of a account and creates it. Returns the server's representation of the account, and an error, if there is any. -func (c *FakeAccounts) Create(ctx context.Context, account *v1beta2.Account, opts v1.CreateOptions) (result *v1beta2.Account, err error) { - emptyResult := &v1beta2.Account{} - obj, err := c.Fake. - Invokes(testing.NewCreateActionWithOptions(accountsResource, c.ns, account, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1beta2.Account), err -} - -// Update takes the representation of a account and updates it. Returns the server's representation of the account, and an error, if there is any. -func (c *FakeAccounts) Update(ctx context.Context, account *v1beta2.Account, opts v1.UpdateOptions) (result *v1beta2.Account, err error) { - emptyResult := &v1beta2.Account{} - obj, err := c.Fake. - Invokes(testing.NewUpdateActionWithOptions(accountsResource, c.ns, account, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1beta2.Account), err } -// UpdateStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *FakeAccounts) UpdateStatus(ctx context.Context, account *v1beta2.Account, opts v1.UpdateOptions) (result *v1beta2.Account, err error) { - emptyResult := &v1beta2.Account{} - obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceActionWithOptions(accountsResource, "status", c.ns, account, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1beta2.Account), err -} - -// Delete takes name of the account and deletes it. Returns an error if one occurs. -func (c *FakeAccounts) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(accountsResource, c.ns, name, opts), &v1beta2.Account{}) - - return err -} - -// DeleteCollection deletes a collection of objects. -func (c *FakeAccounts) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - action := testing.NewDeleteCollectionActionWithOptions(accountsResource, c.ns, opts, listOpts) - - _, err := c.Fake.Invokes(action, &v1beta2.AccountList{}) - return err -} - -// Patch applies the patch and returns the patched account. -func (c *FakeAccounts) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta2.Account, err error) { - emptyResult := &v1beta2.Account{} - obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceActionWithOptions(accountsResource, c.ns, name, pt, data, opts, subresources...), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1beta2.Account), err -} - -// Apply takes the given apply declarative configuration, applies it and returns the applied account. -func (c *FakeAccounts) Apply(ctx context.Context, account *jetstreamv1beta2.AccountApplyConfiguration, opts v1.ApplyOptions) (result *v1beta2.Account, err error) { - if account == nil { - return nil, fmt.Errorf("account provided to Apply must not be nil") - } - data, err := json.Marshal(account) - if err != nil { - return nil, err - } - name := account.Name - if name == nil { - return nil, fmt.Errorf("account.Name must be provided to Apply") - } - emptyResult := &v1beta2.Account{} - obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceActionWithOptions(accountsResource, c.ns, *name, types.ApplyPatchType, data, opts.ToPatchOptions()), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1beta2.Account), err -} - -// ApplyStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeAccounts) ApplyStatus(ctx context.Context, account *jetstreamv1beta2.AccountApplyConfiguration, opts v1.ApplyOptions) (result *v1beta2.Account, err error) { - if account == nil { - return nil, fmt.Errorf("account provided to Apply must not be nil") - } - data, err := json.Marshal(account) - if err != nil { - return nil, err - } - name := account.Name - if name == nil { - return nil, fmt.Errorf("account.Name must be provided to Apply") - } - emptyResult := &v1beta2.Account{} - obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceActionWithOptions(accountsResource, c.ns, *name, types.ApplyPatchType, data, opts.ToPatchOptions(), "status"), emptyResult) - - if obj == nil { - return emptyResult, err +func newFakeAccounts(fake *FakeJetstreamV1beta2, namespace string) typedjetstreamv1beta2.AccountInterface { + return &fakeAccounts{ + gentype.NewFakeClientWithListAndApply[*v1beta2.Account, *v1beta2.AccountList, *jetstreamv1beta2.AccountApplyConfiguration]( + fake.Fake, + namespace, + v1beta2.SchemeGroupVersion.WithResource("accounts"), + v1beta2.SchemeGroupVersion.WithKind("Account"), + func() *v1beta2.Account { return &v1beta2.Account{} }, + func() *v1beta2.AccountList { return &v1beta2.AccountList{} }, + func(dst, src *v1beta2.AccountList) { dst.ListMeta = src.ListMeta }, + func(list *v1beta2.AccountList) []*v1beta2.Account { return gentype.ToPointerSlice(list.Items) }, + func(list *v1beta2.AccountList, items []*v1beta2.Account) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, } - return obj.(*v1beta2.Account), err } diff --git a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/fake_consumer.go b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/fake_consumer.go index 72e4d444..33ed318f 100644 --- a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/fake_consumer.go +++ b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/fake_consumer.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,179 +16,33 @@ package fake import ( - "context" - json "encoding/json" - "fmt" - v1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - labels "k8s.io/apimachinery/pkg/labels" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - testing "k8s.io/client-go/testing" + typedjetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2" + gentype "k8s.io/client-go/gentype" ) -// FakeConsumers implements ConsumerInterface -type FakeConsumers struct { +// fakeConsumers implements ConsumerInterface +type fakeConsumers struct { + *gentype.FakeClientWithListAndApply[*v1beta2.Consumer, *v1beta2.ConsumerList, *jetstreamv1beta2.ConsumerApplyConfiguration] Fake *FakeJetstreamV1beta2 - ns string -} - -var consumersResource = v1beta2.SchemeGroupVersion.WithResource("consumers") - -var consumersKind = v1beta2.SchemeGroupVersion.WithKind("Consumer") - -// Get takes name of the consumer, and returns the corresponding consumer object, and an error if there is any. -func (c *FakeConsumers) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta2.Consumer, err error) { - emptyResult := &v1beta2.Consumer{} - obj, err := c.Fake. - Invokes(testing.NewGetActionWithOptions(consumersResource, c.ns, name, options), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1beta2.Consumer), err -} - -// List takes label and field selectors, and returns the list of Consumers that match those selectors. -func (c *FakeConsumers) List(ctx context.Context, opts v1.ListOptions) (result *v1beta2.ConsumerList, err error) { - emptyResult := &v1beta2.ConsumerList{} - obj, err := c.Fake. - Invokes(testing.NewListActionWithOptions(consumersResource, consumersKind, c.ns, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - - label, _, _ := testing.ExtractFromListOptions(opts) - if label == nil { - label = labels.Everything() - } - list := &v1beta2.ConsumerList{ListMeta: obj.(*v1beta2.ConsumerList).ListMeta} - for _, item := range obj.(*v1beta2.ConsumerList).Items { - if label.Matches(labels.Set(item.Labels)) { - list.Items = append(list.Items, item) - } - } - return list, err -} - -// Watch returns a watch.Interface that watches the requested consumers. -func (c *FakeConsumers) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - return c.Fake. - InvokesWatch(testing.NewWatchActionWithOptions(consumersResource, c.ns, opts)) - -} - -// Create takes the representation of a consumer and creates it. Returns the server's representation of the consumer, and an error, if there is any. -func (c *FakeConsumers) Create(ctx context.Context, consumer *v1beta2.Consumer, opts v1.CreateOptions) (result *v1beta2.Consumer, err error) { - emptyResult := &v1beta2.Consumer{} - obj, err := c.Fake. - Invokes(testing.NewCreateActionWithOptions(consumersResource, c.ns, consumer, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1beta2.Consumer), err -} - -// Update takes the representation of a consumer and updates it. Returns the server's representation of the consumer, and an error, if there is any. -func (c *FakeConsumers) Update(ctx context.Context, consumer *v1beta2.Consumer, opts v1.UpdateOptions) (result *v1beta2.Consumer, err error) { - emptyResult := &v1beta2.Consumer{} - obj, err := c.Fake. - Invokes(testing.NewUpdateActionWithOptions(consumersResource, c.ns, consumer, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1beta2.Consumer), err } -// UpdateStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *FakeConsumers) UpdateStatus(ctx context.Context, consumer *v1beta2.Consumer, opts v1.UpdateOptions) (result *v1beta2.Consumer, err error) { - emptyResult := &v1beta2.Consumer{} - obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceActionWithOptions(consumersResource, "status", c.ns, consumer, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1beta2.Consumer), err -} - -// Delete takes name of the consumer and deletes it. Returns an error if one occurs. -func (c *FakeConsumers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(consumersResource, c.ns, name, opts), &v1beta2.Consumer{}) - - return err -} - -// DeleteCollection deletes a collection of objects. -func (c *FakeConsumers) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - action := testing.NewDeleteCollectionActionWithOptions(consumersResource, c.ns, opts, listOpts) - - _, err := c.Fake.Invokes(action, &v1beta2.ConsumerList{}) - return err -} - -// Patch applies the patch and returns the patched consumer. -func (c *FakeConsumers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta2.Consumer, err error) { - emptyResult := &v1beta2.Consumer{} - obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceActionWithOptions(consumersResource, c.ns, name, pt, data, opts, subresources...), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1beta2.Consumer), err -} - -// Apply takes the given apply declarative configuration, applies it and returns the applied consumer. -func (c *FakeConsumers) Apply(ctx context.Context, consumer *jetstreamv1beta2.ConsumerApplyConfiguration, opts v1.ApplyOptions) (result *v1beta2.Consumer, err error) { - if consumer == nil { - return nil, fmt.Errorf("consumer provided to Apply must not be nil") - } - data, err := json.Marshal(consumer) - if err != nil { - return nil, err - } - name := consumer.Name - if name == nil { - return nil, fmt.Errorf("consumer.Name must be provided to Apply") - } - emptyResult := &v1beta2.Consumer{} - obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceActionWithOptions(consumersResource, c.ns, *name, types.ApplyPatchType, data, opts.ToPatchOptions()), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1beta2.Consumer), err -} - -// ApplyStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeConsumers) ApplyStatus(ctx context.Context, consumer *jetstreamv1beta2.ConsumerApplyConfiguration, opts v1.ApplyOptions) (result *v1beta2.Consumer, err error) { - if consumer == nil { - return nil, fmt.Errorf("consumer provided to Apply must not be nil") - } - data, err := json.Marshal(consumer) - if err != nil { - return nil, err - } - name := consumer.Name - if name == nil { - return nil, fmt.Errorf("consumer.Name must be provided to Apply") - } - emptyResult := &v1beta2.Consumer{} - obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceActionWithOptions(consumersResource, c.ns, *name, types.ApplyPatchType, data, opts.ToPatchOptions(), "status"), emptyResult) - - if obj == nil { - return emptyResult, err +func newFakeConsumers(fake *FakeJetstreamV1beta2, namespace string) typedjetstreamv1beta2.ConsumerInterface { + return &fakeConsumers{ + gentype.NewFakeClientWithListAndApply[*v1beta2.Consumer, *v1beta2.ConsumerList, *jetstreamv1beta2.ConsumerApplyConfiguration]( + fake.Fake, + namespace, + v1beta2.SchemeGroupVersion.WithResource("consumers"), + v1beta2.SchemeGroupVersion.WithKind("Consumer"), + func() *v1beta2.Consumer { return &v1beta2.Consumer{} }, + func() *v1beta2.ConsumerList { return &v1beta2.ConsumerList{} }, + func(dst, src *v1beta2.ConsumerList) { dst.ListMeta = src.ListMeta }, + func(list *v1beta2.ConsumerList) []*v1beta2.Consumer { return gentype.ToPointerSlice(list.Items) }, + func(list *v1beta2.ConsumerList, items []*v1beta2.Consumer) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, } - return obj.(*v1beta2.Consumer), err } diff --git a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/fake_jetstream_client.go b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/fake_jetstream_client.go index 31d69c86..7eec1be1 100644 --- a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/fake_jetstream_client.go +++ b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/fake_jetstream_client.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -26,15 +26,19 @@ type FakeJetstreamV1beta2 struct { } func (c *FakeJetstreamV1beta2) Accounts(namespace string) v1beta2.AccountInterface { - return &FakeAccounts{c, namespace} + return newFakeAccounts(c, namespace) } func (c *FakeJetstreamV1beta2) Consumers(namespace string) v1beta2.ConsumerInterface { - return &FakeConsumers{c, namespace} + return newFakeConsumers(c, namespace) +} + +func (c *FakeJetstreamV1beta2) KeyValues(namespace string) v1beta2.KeyValueInterface { + return newFakeKeyValues(c, namespace) } func (c *FakeJetstreamV1beta2) Streams(namespace string) v1beta2.StreamInterface { - return &FakeStreams{c, namespace} + return newFakeStreams(c, namespace) } // RESTClient returns a RESTClient that is used to communicate diff --git a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/fake_keyvalue.go b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/fake_keyvalue.go new file mode 100644 index 00000000..1fbf269a --- /dev/null +++ b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/fake_keyvalue.go @@ -0,0 +1,48 @@ +// Copyright 2025 The NATS Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" + jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2" + typedjetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2" + gentype "k8s.io/client-go/gentype" +) + +// fakeKeyValues implements KeyValueInterface +type fakeKeyValues struct { + *gentype.FakeClientWithListAndApply[*v1beta2.KeyValue, *v1beta2.KeyValueList, *jetstreamv1beta2.KeyValueApplyConfiguration] + Fake *FakeJetstreamV1beta2 +} + +func newFakeKeyValues(fake *FakeJetstreamV1beta2, namespace string) typedjetstreamv1beta2.KeyValueInterface { + return &fakeKeyValues{ + gentype.NewFakeClientWithListAndApply[*v1beta2.KeyValue, *v1beta2.KeyValueList, *jetstreamv1beta2.KeyValueApplyConfiguration]( + fake.Fake, + namespace, + v1beta2.SchemeGroupVersion.WithResource("keyvalues"), + v1beta2.SchemeGroupVersion.WithKind("KeyValue"), + func() *v1beta2.KeyValue { return &v1beta2.KeyValue{} }, + func() *v1beta2.KeyValueList { return &v1beta2.KeyValueList{} }, + func(dst, src *v1beta2.KeyValueList) { dst.ListMeta = src.ListMeta }, + func(list *v1beta2.KeyValueList) []*v1beta2.KeyValue { return gentype.ToPointerSlice(list.Items) }, + func(list *v1beta2.KeyValueList, items []*v1beta2.KeyValue) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, + } +} diff --git a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/fake_stream.go b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/fake_stream.go index da603cc1..f7f36cce 100644 --- a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/fake_stream.go +++ b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/fake/fake_stream.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,179 +16,31 @@ package fake import ( - "context" - json "encoding/json" - "fmt" - v1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - labels "k8s.io/apimachinery/pkg/labels" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - testing "k8s.io/client-go/testing" + typedjetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2" + gentype "k8s.io/client-go/gentype" ) -// FakeStreams implements StreamInterface -type FakeStreams struct { +// fakeStreams implements StreamInterface +type fakeStreams struct { + *gentype.FakeClientWithListAndApply[*v1beta2.Stream, *v1beta2.StreamList, *jetstreamv1beta2.StreamApplyConfiguration] Fake *FakeJetstreamV1beta2 - ns string -} - -var streamsResource = v1beta2.SchemeGroupVersion.WithResource("streams") - -var streamsKind = v1beta2.SchemeGroupVersion.WithKind("Stream") - -// Get takes name of the stream, and returns the corresponding stream object, and an error if there is any. -func (c *FakeStreams) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta2.Stream, err error) { - emptyResult := &v1beta2.Stream{} - obj, err := c.Fake. - Invokes(testing.NewGetActionWithOptions(streamsResource, c.ns, name, options), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1beta2.Stream), err -} - -// List takes label and field selectors, and returns the list of Streams that match those selectors. -func (c *FakeStreams) List(ctx context.Context, opts v1.ListOptions) (result *v1beta2.StreamList, err error) { - emptyResult := &v1beta2.StreamList{} - obj, err := c.Fake. - Invokes(testing.NewListActionWithOptions(streamsResource, streamsKind, c.ns, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - - label, _, _ := testing.ExtractFromListOptions(opts) - if label == nil { - label = labels.Everything() - } - list := &v1beta2.StreamList{ListMeta: obj.(*v1beta2.StreamList).ListMeta} - for _, item := range obj.(*v1beta2.StreamList).Items { - if label.Matches(labels.Set(item.Labels)) { - list.Items = append(list.Items, item) - } - } - return list, err -} - -// Watch returns a watch.Interface that watches the requested streams. -func (c *FakeStreams) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - return c.Fake. - InvokesWatch(testing.NewWatchActionWithOptions(streamsResource, c.ns, opts)) - -} - -// Create takes the representation of a stream and creates it. Returns the server's representation of the stream, and an error, if there is any. -func (c *FakeStreams) Create(ctx context.Context, stream *v1beta2.Stream, opts v1.CreateOptions) (result *v1beta2.Stream, err error) { - emptyResult := &v1beta2.Stream{} - obj, err := c.Fake. - Invokes(testing.NewCreateActionWithOptions(streamsResource, c.ns, stream, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1beta2.Stream), err -} - -// Update takes the representation of a stream and updates it. Returns the server's representation of the stream, and an error, if there is any. -func (c *FakeStreams) Update(ctx context.Context, stream *v1beta2.Stream, opts v1.UpdateOptions) (result *v1beta2.Stream, err error) { - emptyResult := &v1beta2.Stream{} - obj, err := c.Fake. - Invokes(testing.NewUpdateActionWithOptions(streamsResource, c.ns, stream, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1beta2.Stream), err } -// UpdateStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *FakeStreams) UpdateStatus(ctx context.Context, stream *v1beta2.Stream, opts v1.UpdateOptions) (result *v1beta2.Stream, err error) { - emptyResult := &v1beta2.Stream{} - obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceActionWithOptions(streamsResource, "status", c.ns, stream, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1beta2.Stream), err -} - -// Delete takes name of the stream and deletes it. Returns an error if one occurs. -func (c *FakeStreams) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(streamsResource, c.ns, name, opts), &v1beta2.Stream{}) - - return err -} - -// DeleteCollection deletes a collection of objects. -func (c *FakeStreams) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - action := testing.NewDeleteCollectionActionWithOptions(streamsResource, c.ns, opts, listOpts) - - _, err := c.Fake.Invokes(action, &v1beta2.StreamList{}) - return err -} - -// Patch applies the patch and returns the patched stream. -func (c *FakeStreams) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta2.Stream, err error) { - emptyResult := &v1beta2.Stream{} - obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceActionWithOptions(streamsResource, c.ns, name, pt, data, opts, subresources...), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1beta2.Stream), err -} - -// Apply takes the given apply declarative configuration, applies it and returns the applied stream. -func (c *FakeStreams) Apply(ctx context.Context, stream *jetstreamv1beta2.StreamApplyConfiguration, opts v1.ApplyOptions) (result *v1beta2.Stream, err error) { - if stream == nil { - return nil, fmt.Errorf("stream provided to Apply must not be nil") - } - data, err := json.Marshal(stream) - if err != nil { - return nil, err - } - name := stream.Name - if name == nil { - return nil, fmt.Errorf("stream.Name must be provided to Apply") - } - emptyResult := &v1beta2.Stream{} - obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceActionWithOptions(streamsResource, c.ns, *name, types.ApplyPatchType, data, opts.ToPatchOptions()), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1beta2.Stream), err -} - -// ApplyStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeStreams) ApplyStatus(ctx context.Context, stream *jetstreamv1beta2.StreamApplyConfiguration, opts v1.ApplyOptions) (result *v1beta2.Stream, err error) { - if stream == nil { - return nil, fmt.Errorf("stream provided to Apply must not be nil") - } - data, err := json.Marshal(stream) - if err != nil { - return nil, err - } - name := stream.Name - if name == nil { - return nil, fmt.Errorf("stream.Name must be provided to Apply") - } - emptyResult := &v1beta2.Stream{} - obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceActionWithOptions(streamsResource, c.ns, *name, types.ApplyPatchType, data, opts.ToPatchOptions(), "status"), emptyResult) - - if obj == nil { - return emptyResult, err +func newFakeStreams(fake *FakeJetstreamV1beta2, namespace string) typedjetstreamv1beta2.StreamInterface { + return &fakeStreams{ + gentype.NewFakeClientWithListAndApply[*v1beta2.Stream, *v1beta2.StreamList, *jetstreamv1beta2.StreamApplyConfiguration]( + fake.Fake, + namespace, + v1beta2.SchemeGroupVersion.WithResource("streams"), + v1beta2.SchemeGroupVersion.WithKind("Stream"), + func() *v1beta2.Stream { return &v1beta2.Stream{} }, + func() *v1beta2.StreamList { return &v1beta2.StreamList{} }, + func(dst, src *v1beta2.StreamList) { dst.ListMeta = src.ListMeta }, + func(list *v1beta2.StreamList) []*v1beta2.Stream { return gentype.ToPointerSlice(list.Items) }, + func(list *v1beta2.StreamList, items []*v1beta2.Stream) { list.Items = gentype.FromPointerSlice(items) }, + ), + fake, } - return obj.(*v1beta2.Stream), err } diff --git a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/generated_expansion.go b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/generated_expansion.go index f3410b9a..97b76f2e 100644 --- a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/generated_expansion.go +++ b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/generated_expansion.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -19,4 +19,6 @@ type AccountExpansion interface{} type ConsumerExpansion interface{} +type KeyValueExpansion interface{} + type StreamExpansion interface{} diff --git a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/jetstream_client.go b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/jetstream_client.go index b6115fcc..c18538bb 100644 --- a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/jetstream_client.go +++ b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/jetstream_client.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,10 +16,10 @@ package v1beta2 import ( - "net/http" + http "net/http" - v1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" - "github.com/nats-io/nack/pkg/jetstream/generated/clientset/versioned/scheme" + jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" + scheme "github.com/nats-io/nack/pkg/jetstream/generated/clientset/versioned/scheme" rest "k8s.io/client-go/rest" ) @@ -27,6 +27,7 @@ type JetstreamV1beta2Interface interface { RESTClient() rest.Interface AccountsGetter ConsumersGetter + KeyValuesGetter StreamsGetter } @@ -43,6 +44,10 @@ func (c *JetstreamV1beta2Client) Consumers(namespace string) ConsumerInterface { return newConsumers(c, namespace) } +func (c *JetstreamV1beta2Client) KeyValues(namespace string) KeyValueInterface { + return newKeyValues(c, namespace) +} + func (c *JetstreamV1beta2Client) Streams(namespace string) StreamInterface { return newStreams(c, namespace) } @@ -92,10 +97,10 @@ func New(c rest.Interface) *JetstreamV1beta2Client { } func setConfigDefaults(config *rest.Config) error { - gv := v1beta2.SchemeGroupVersion + gv := jetstreamv1beta2.SchemeGroupVersion config.GroupVersion = &gv config.APIPath = "/apis" - config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + config.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(scheme.Scheme, scheme.Codecs).WithoutConversion() if config.UserAgent == "" { config.UserAgent = rest.DefaultKubernetesUserAgent() diff --git a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/keyvalue.go b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/keyvalue.go new file mode 100644 index 00000000..c649bd05 --- /dev/null +++ b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/keyvalue.go @@ -0,0 +1,71 @@ +// Copyright 2025 The NATS Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta2 + +import ( + context "context" + + jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" + applyconfigurationjetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2" + scheme "github.com/nats-io/nack/pkg/jetstream/generated/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + gentype "k8s.io/client-go/gentype" +) + +// KeyValuesGetter has a method to return a KeyValueInterface. +// A group's client should implement this interface. +type KeyValuesGetter interface { + KeyValues(namespace string) KeyValueInterface +} + +// KeyValueInterface has methods to work with KeyValue resources. +type KeyValueInterface interface { + Create(ctx context.Context, keyValue *jetstreamv1beta2.KeyValue, opts v1.CreateOptions) (*jetstreamv1beta2.KeyValue, error) + Update(ctx context.Context, keyValue *jetstreamv1beta2.KeyValue, opts v1.UpdateOptions) (*jetstreamv1beta2.KeyValue, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, keyValue *jetstreamv1beta2.KeyValue, opts v1.UpdateOptions) (*jetstreamv1beta2.KeyValue, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*jetstreamv1beta2.KeyValue, error) + List(ctx context.Context, opts v1.ListOptions) (*jetstreamv1beta2.KeyValueList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *jetstreamv1beta2.KeyValue, err error) + Apply(ctx context.Context, keyValue *applyconfigurationjetstreamv1beta2.KeyValueApplyConfiguration, opts v1.ApplyOptions) (result *jetstreamv1beta2.KeyValue, err error) + // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). + ApplyStatus(ctx context.Context, keyValue *applyconfigurationjetstreamv1beta2.KeyValueApplyConfiguration, opts v1.ApplyOptions) (result *jetstreamv1beta2.KeyValue, err error) + KeyValueExpansion +} + +// keyValues implements KeyValueInterface +type keyValues struct { + *gentype.ClientWithListAndApply[*jetstreamv1beta2.KeyValue, *jetstreamv1beta2.KeyValueList, *applyconfigurationjetstreamv1beta2.KeyValueApplyConfiguration] +} + +// newKeyValues returns a KeyValues +func newKeyValues(c *JetstreamV1beta2Client, namespace string) *keyValues { + return &keyValues{ + gentype.NewClientWithListAndApply[*jetstreamv1beta2.KeyValue, *jetstreamv1beta2.KeyValueList, *applyconfigurationjetstreamv1beta2.KeyValueApplyConfiguration]( + "keyvalues", + c.RESTClient(), + scheme.ParameterCodec, + namespace, + func() *jetstreamv1beta2.KeyValue { return &jetstreamv1beta2.KeyValue{} }, + func() *jetstreamv1beta2.KeyValueList { return &jetstreamv1beta2.KeyValueList{} }, + ), + } +} diff --git a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/stream.go b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/stream.go index 44008042..644d63f6 100644 --- a/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/stream.go +++ b/pkg/jetstream/generated/clientset/versioned/typed/jetstream/v1beta2/stream.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,10 +16,10 @@ package v1beta2 import ( - "context" + context "context" - v1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" - jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2" + jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" + applyconfigurationjetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/applyconfiguration/jetstream/v1beta2" scheme "github.com/nats-io/nack/pkg/jetstream/generated/clientset/versioned/scheme" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" @@ -35,36 +35,37 @@ type StreamsGetter interface { // StreamInterface has methods to work with Stream resources. type StreamInterface interface { - Create(ctx context.Context, stream *v1beta2.Stream, opts v1.CreateOptions) (*v1beta2.Stream, error) - Update(ctx context.Context, stream *v1beta2.Stream, opts v1.UpdateOptions) (*v1beta2.Stream, error) + Create(ctx context.Context, stream *jetstreamv1beta2.Stream, opts v1.CreateOptions) (*jetstreamv1beta2.Stream, error) + Update(ctx context.Context, stream *jetstreamv1beta2.Stream, opts v1.UpdateOptions) (*jetstreamv1beta2.Stream, error) // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). - UpdateStatus(ctx context.Context, stream *v1beta2.Stream, opts v1.UpdateOptions) (*v1beta2.Stream, error) + UpdateStatus(ctx context.Context, stream *jetstreamv1beta2.Stream, opts v1.UpdateOptions) (*jetstreamv1beta2.Stream, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta2.Stream, error) - List(ctx context.Context, opts v1.ListOptions) (*v1beta2.StreamList, error) + Get(ctx context.Context, name string, opts v1.GetOptions) (*jetstreamv1beta2.Stream, error) + List(ctx context.Context, opts v1.ListOptions) (*jetstreamv1beta2.StreamList, error) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta2.Stream, err error) - Apply(ctx context.Context, stream *jetstreamv1beta2.StreamApplyConfiguration, opts v1.ApplyOptions) (result *v1beta2.Stream, err error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *jetstreamv1beta2.Stream, err error) + Apply(ctx context.Context, stream *applyconfigurationjetstreamv1beta2.StreamApplyConfiguration, opts v1.ApplyOptions) (result *jetstreamv1beta2.Stream, err error) // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). - ApplyStatus(ctx context.Context, stream *jetstreamv1beta2.StreamApplyConfiguration, opts v1.ApplyOptions) (result *v1beta2.Stream, err error) + ApplyStatus(ctx context.Context, stream *applyconfigurationjetstreamv1beta2.StreamApplyConfiguration, opts v1.ApplyOptions) (result *jetstreamv1beta2.Stream, err error) StreamExpansion } // streams implements StreamInterface type streams struct { - *gentype.ClientWithListAndApply[*v1beta2.Stream, *v1beta2.StreamList, *jetstreamv1beta2.StreamApplyConfiguration] + *gentype.ClientWithListAndApply[*jetstreamv1beta2.Stream, *jetstreamv1beta2.StreamList, *applyconfigurationjetstreamv1beta2.StreamApplyConfiguration] } // newStreams returns a Streams func newStreams(c *JetstreamV1beta2Client, namespace string) *streams { return &streams{ - gentype.NewClientWithListAndApply[*v1beta2.Stream, *v1beta2.StreamList, *jetstreamv1beta2.StreamApplyConfiguration]( + gentype.NewClientWithListAndApply[*jetstreamv1beta2.Stream, *jetstreamv1beta2.StreamList, *applyconfigurationjetstreamv1beta2.StreamApplyConfiguration]( "streams", c.RESTClient(), scheme.ParameterCodec, namespace, - func() *v1beta2.Stream { return &v1beta2.Stream{} }, - func() *v1beta2.StreamList { return &v1beta2.StreamList{} }), + func() *jetstreamv1beta2.Stream { return &jetstreamv1beta2.Stream{} }, + func() *jetstreamv1beta2.StreamList { return &jetstreamv1beta2.StreamList{} }, + ), } } diff --git a/pkg/jetstream/generated/informers/externalversions/factory.go b/pkg/jetstream/generated/informers/externalversions/factory.go index 8e6d034f..1f01ea2e 100644 --- a/pkg/jetstream/generated/informers/externalversions/factory.go +++ b/pkg/jetstream/generated/informers/externalversions/factory.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/informers/externalversions/generic.go b/pkg/jetstream/generated/informers/externalversions/generic.go index e5ba543b..b03765d4 100644 --- a/pkg/jetstream/generated/informers/externalversions/generic.go +++ b/pkg/jetstream/generated/informers/externalversions/generic.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,7 +16,7 @@ package externalversions import ( - "fmt" + fmt "fmt" v1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -54,6 +54,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource return &genericInformer{resource: resource.GroupResource(), informer: f.Jetstream().V1beta2().Accounts().Informer()}, nil case v1beta2.SchemeGroupVersion.WithResource("consumers"): return &genericInformer{resource: resource.GroupResource(), informer: f.Jetstream().V1beta2().Consumers().Informer()}, nil + case v1beta2.SchemeGroupVersion.WithResource("keyvalues"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Jetstream().V1beta2().KeyValues().Informer()}, nil case v1beta2.SchemeGroupVersion.WithResource("streams"): return &genericInformer{resource: resource.GroupResource(), informer: f.Jetstream().V1beta2().Streams().Informer()}, nil diff --git a/pkg/jetstream/generated/informers/externalversions/internalinterfaces/factory_interfaces.go b/pkg/jetstream/generated/informers/externalversions/internalinterfaces/factory_interfaces.go index 5156b38f..bec8fb37 100644 --- a/pkg/jetstream/generated/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/pkg/jetstream/generated/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/informers/externalversions/jetstream/interface.go b/pkg/jetstream/generated/informers/externalversions/jetstream/interface.go index ba66ab00..6101526b 100644 --- a/pkg/jetstream/generated/informers/externalversions/jetstream/interface.go +++ b/pkg/jetstream/generated/informers/externalversions/jetstream/interface.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/jetstream/generated/informers/externalversions/jetstream/v1beta2/account.go b/pkg/jetstream/generated/informers/externalversions/jetstream/v1beta2/account.go index da16b01b..2e9d5e47 100644 --- a/pkg/jetstream/generated/informers/externalversions/jetstream/v1beta2/account.go +++ b/pkg/jetstream/generated/informers/externalversions/jetstream/v1beta2/account.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,13 +16,13 @@ package v1beta2 import ( - "context" + context "context" time "time" - jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" + apisjetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" versioned "github.com/nats-io/nack/pkg/jetstream/generated/clientset/versioned" internalinterfaces "github.com/nats-io/nack/pkg/jetstream/generated/informers/externalversions/internalinterfaces" - v1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/listers/jetstream/v1beta2" + jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/listers/jetstream/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" @@ -33,7 +33,7 @@ import ( // Accounts. type AccountInformer interface { Informer() cache.SharedIndexInformer - Lister() v1beta2.AccountLister + Lister() jetstreamv1beta2.AccountLister } type accountInformer struct { @@ -68,7 +68,7 @@ func NewFilteredAccountInformer(client versioned.Interface, namespace string, re return client.JetstreamV1beta2().Accounts(namespace).Watch(context.TODO(), options) }, }, - &jetstreamv1beta2.Account{}, + &apisjetstreamv1beta2.Account{}, resyncPeriod, indexers, ) @@ -79,9 +79,9 @@ func (f *accountInformer) defaultInformer(client versioned.Interface, resyncPeri } func (f *accountInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&jetstreamv1beta2.Account{}, f.defaultInformer) + return f.factory.InformerFor(&apisjetstreamv1beta2.Account{}, f.defaultInformer) } -func (f *accountInformer) Lister() v1beta2.AccountLister { - return v1beta2.NewAccountLister(f.Informer().GetIndexer()) +func (f *accountInformer) Lister() jetstreamv1beta2.AccountLister { + return jetstreamv1beta2.NewAccountLister(f.Informer().GetIndexer()) } diff --git a/pkg/jetstream/generated/informers/externalversions/jetstream/v1beta2/consumer.go b/pkg/jetstream/generated/informers/externalversions/jetstream/v1beta2/consumer.go index ef400250..09aff42e 100644 --- a/pkg/jetstream/generated/informers/externalversions/jetstream/v1beta2/consumer.go +++ b/pkg/jetstream/generated/informers/externalversions/jetstream/v1beta2/consumer.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,13 +16,13 @@ package v1beta2 import ( - "context" + context "context" time "time" - jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" + apisjetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" versioned "github.com/nats-io/nack/pkg/jetstream/generated/clientset/versioned" internalinterfaces "github.com/nats-io/nack/pkg/jetstream/generated/informers/externalversions/internalinterfaces" - v1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/listers/jetstream/v1beta2" + jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/listers/jetstream/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" @@ -33,7 +33,7 @@ import ( // Consumers. type ConsumerInformer interface { Informer() cache.SharedIndexInformer - Lister() v1beta2.ConsumerLister + Lister() jetstreamv1beta2.ConsumerLister } type consumerInformer struct { @@ -68,7 +68,7 @@ func NewFilteredConsumerInformer(client versioned.Interface, namespace string, r return client.JetstreamV1beta2().Consumers(namespace).Watch(context.TODO(), options) }, }, - &jetstreamv1beta2.Consumer{}, + &apisjetstreamv1beta2.Consumer{}, resyncPeriod, indexers, ) @@ -79,9 +79,9 @@ func (f *consumerInformer) defaultInformer(client versioned.Interface, resyncPer } func (f *consumerInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&jetstreamv1beta2.Consumer{}, f.defaultInformer) + return f.factory.InformerFor(&apisjetstreamv1beta2.Consumer{}, f.defaultInformer) } -func (f *consumerInformer) Lister() v1beta2.ConsumerLister { - return v1beta2.NewConsumerLister(f.Informer().GetIndexer()) +func (f *consumerInformer) Lister() jetstreamv1beta2.ConsumerLister { + return jetstreamv1beta2.NewConsumerLister(f.Informer().GetIndexer()) } diff --git a/pkg/jetstream/generated/informers/externalversions/jetstream/v1beta2/interface.go b/pkg/jetstream/generated/informers/externalversions/jetstream/v1beta2/interface.go index 05bf3fdb..29a492fb 100644 --- a/pkg/jetstream/generated/informers/externalversions/jetstream/v1beta2/interface.go +++ b/pkg/jetstream/generated/informers/externalversions/jetstream/v1beta2/interface.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -25,6 +25,8 @@ type Interface interface { Accounts() AccountInformer // Consumers returns a ConsumerInformer. Consumers() ConsumerInformer + // KeyValues returns a KeyValueInformer. + KeyValues() KeyValueInformer // Streams returns a StreamInformer. Streams() StreamInformer } @@ -50,6 +52,11 @@ func (v *version) Consumers() ConsumerInformer { return &consumerInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} } +// KeyValues returns a KeyValueInformer. +func (v *version) KeyValues() KeyValueInformer { + return &keyValueInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + // Streams returns a StreamInformer. func (v *version) Streams() StreamInformer { return &streamInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} diff --git a/pkg/jetstream/generated/informers/externalversions/jetstream/v1beta2/keyvalue.go b/pkg/jetstream/generated/informers/externalversions/jetstream/v1beta2/keyvalue.go new file mode 100644 index 00000000..3f3c7489 --- /dev/null +++ b/pkg/jetstream/generated/informers/externalversions/jetstream/v1beta2/keyvalue.go @@ -0,0 +1,87 @@ +// Copyright 2025 The NATS Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta2 + +import ( + context "context" + time "time" + + apisjetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" + versioned "github.com/nats-io/nack/pkg/jetstream/generated/clientset/versioned" + internalinterfaces "github.com/nats-io/nack/pkg/jetstream/generated/informers/externalversions/internalinterfaces" + jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/listers/jetstream/v1beta2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// KeyValueInformer provides access to a shared informer and lister for +// KeyValues. +type KeyValueInformer interface { + Informer() cache.SharedIndexInformer + Lister() jetstreamv1beta2.KeyValueLister +} + +type keyValueInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewKeyValueInformer constructs a new informer for KeyValue type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewKeyValueInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredKeyValueInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredKeyValueInformer constructs a new informer for KeyValue type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredKeyValueInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.JetstreamV1beta2().KeyValues(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.JetstreamV1beta2().KeyValues(namespace).Watch(context.TODO(), options) + }, + }, + &apisjetstreamv1beta2.KeyValue{}, + resyncPeriod, + indexers, + ) +} + +func (f *keyValueInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredKeyValueInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *keyValueInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&apisjetstreamv1beta2.KeyValue{}, f.defaultInformer) +} + +func (f *keyValueInformer) Lister() jetstreamv1beta2.KeyValueLister { + return jetstreamv1beta2.NewKeyValueLister(f.Informer().GetIndexer()) +} diff --git a/pkg/jetstream/generated/informers/externalversions/jetstream/v1beta2/stream.go b/pkg/jetstream/generated/informers/externalversions/jetstream/v1beta2/stream.go index d8d7dbd4..b3af693c 100644 --- a/pkg/jetstream/generated/informers/externalversions/jetstream/v1beta2/stream.go +++ b/pkg/jetstream/generated/informers/externalversions/jetstream/v1beta2/stream.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,13 +16,13 @@ package v1beta2 import ( - "context" + context "context" time "time" - jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" + apisjetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" versioned "github.com/nats-io/nack/pkg/jetstream/generated/clientset/versioned" internalinterfaces "github.com/nats-io/nack/pkg/jetstream/generated/informers/externalversions/internalinterfaces" - v1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/listers/jetstream/v1beta2" + jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/generated/listers/jetstream/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" @@ -33,7 +33,7 @@ import ( // Streams. type StreamInformer interface { Informer() cache.SharedIndexInformer - Lister() v1beta2.StreamLister + Lister() jetstreamv1beta2.StreamLister } type streamInformer struct { @@ -68,7 +68,7 @@ func NewFilteredStreamInformer(client versioned.Interface, namespace string, res return client.JetstreamV1beta2().Streams(namespace).Watch(context.TODO(), options) }, }, - &jetstreamv1beta2.Stream{}, + &apisjetstreamv1beta2.Stream{}, resyncPeriod, indexers, ) @@ -79,9 +79,9 @@ func (f *streamInformer) defaultInformer(client versioned.Interface, resyncPerio } func (f *streamInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&jetstreamv1beta2.Stream{}, f.defaultInformer) + return f.factory.InformerFor(&apisjetstreamv1beta2.Stream{}, f.defaultInformer) } -func (f *streamInformer) Lister() v1beta2.StreamLister { - return v1beta2.NewStreamLister(f.Informer().GetIndexer()) +func (f *streamInformer) Lister() jetstreamv1beta2.StreamLister { + return jetstreamv1beta2.NewStreamLister(f.Informer().GetIndexer()) } diff --git a/pkg/jetstream/generated/listers/jetstream/v1beta2/account.go b/pkg/jetstream/generated/listers/jetstream/v1beta2/account.go index ef987a4e..019d7df5 100644 --- a/pkg/jetstream/generated/listers/jetstream/v1beta2/account.go +++ b/pkg/jetstream/generated/listers/jetstream/v1beta2/account.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,10 +16,10 @@ package v1beta2 import ( - v1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/listers" - "k8s.io/client-go/tools/cache" + jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" + labels "k8s.io/apimachinery/pkg/labels" + listers "k8s.io/client-go/listers" + cache "k8s.io/client-go/tools/cache" ) // AccountLister helps list Accounts. @@ -27,7 +27,7 @@ import ( type AccountLister interface { // List lists all Accounts in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1beta2.Account, err error) + List(selector labels.Selector) (ret []*jetstreamv1beta2.Account, err error) // Accounts returns an object that can list and get Accounts. Accounts(namespace string) AccountNamespaceLister AccountListerExpansion @@ -35,17 +35,17 @@ type AccountLister interface { // accountLister implements the AccountLister interface. type accountLister struct { - listers.ResourceIndexer[*v1beta2.Account] + listers.ResourceIndexer[*jetstreamv1beta2.Account] } // NewAccountLister returns a new AccountLister. func NewAccountLister(indexer cache.Indexer) AccountLister { - return &accountLister{listers.New[*v1beta2.Account](indexer, v1beta2.Resource("account"))} + return &accountLister{listers.New[*jetstreamv1beta2.Account](indexer, jetstreamv1beta2.Resource("account"))} } // Accounts returns an object that can list and get Accounts. func (s *accountLister) Accounts(namespace string) AccountNamespaceLister { - return accountNamespaceLister{listers.NewNamespaced[*v1beta2.Account](s.ResourceIndexer, namespace)} + return accountNamespaceLister{listers.NewNamespaced[*jetstreamv1beta2.Account](s.ResourceIndexer, namespace)} } // AccountNamespaceLister helps list and get Accounts. @@ -53,15 +53,15 @@ func (s *accountLister) Accounts(namespace string) AccountNamespaceLister { type AccountNamespaceLister interface { // List lists all Accounts in the indexer for a given namespace. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1beta2.Account, err error) + List(selector labels.Selector) (ret []*jetstreamv1beta2.Account, err error) // Get retrieves the Account from the indexer for a given namespace and name. // Objects returned here must be treated as read-only. - Get(name string) (*v1beta2.Account, error) + Get(name string) (*jetstreamv1beta2.Account, error) AccountNamespaceListerExpansion } // accountNamespaceLister implements the AccountNamespaceLister // interface. type accountNamespaceLister struct { - listers.ResourceIndexer[*v1beta2.Account] + listers.ResourceIndexer[*jetstreamv1beta2.Account] } diff --git a/pkg/jetstream/generated/listers/jetstream/v1beta2/consumer.go b/pkg/jetstream/generated/listers/jetstream/v1beta2/consumer.go index 1f46c5a0..651a55d8 100644 --- a/pkg/jetstream/generated/listers/jetstream/v1beta2/consumer.go +++ b/pkg/jetstream/generated/listers/jetstream/v1beta2/consumer.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,10 +16,10 @@ package v1beta2 import ( - v1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/listers" - "k8s.io/client-go/tools/cache" + jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" + labels "k8s.io/apimachinery/pkg/labels" + listers "k8s.io/client-go/listers" + cache "k8s.io/client-go/tools/cache" ) // ConsumerLister helps list Consumers. @@ -27,7 +27,7 @@ import ( type ConsumerLister interface { // List lists all Consumers in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1beta2.Consumer, err error) + List(selector labels.Selector) (ret []*jetstreamv1beta2.Consumer, err error) // Consumers returns an object that can list and get Consumers. Consumers(namespace string) ConsumerNamespaceLister ConsumerListerExpansion @@ -35,17 +35,17 @@ type ConsumerLister interface { // consumerLister implements the ConsumerLister interface. type consumerLister struct { - listers.ResourceIndexer[*v1beta2.Consumer] + listers.ResourceIndexer[*jetstreamv1beta2.Consumer] } // NewConsumerLister returns a new ConsumerLister. func NewConsumerLister(indexer cache.Indexer) ConsumerLister { - return &consumerLister{listers.New[*v1beta2.Consumer](indexer, v1beta2.Resource("consumer"))} + return &consumerLister{listers.New[*jetstreamv1beta2.Consumer](indexer, jetstreamv1beta2.Resource("consumer"))} } // Consumers returns an object that can list and get Consumers. func (s *consumerLister) Consumers(namespace string) ConsumerNamespaceLister { - return consumerNamespaceLister{listers.NewNamespaced[*v1beta2.Consumer](s.ResourceIndexer, namespace)} + return consumerNamespaceLister{listers.NewNamespaced[*jetstreamv1beta2.Consumer](s.ResourceIndexer, namespace)} } // ConsumerNamespaceLister helps list and get Consumers. @@ -53,15 +53,15 @@ func (s *consumerLister) Consumers(namespace string) ConsumerNamespaceLister { type ConsumerNamespaceLister interface { // List lists all Consumers in the indexer for a given namespace. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1beta2.Consumer, err error) + List(selector labels.Selector) (ret []*jetstreamv1beta2.Consumer, err error) // Get retrieves the Consumer from the indexer for a given namespace and name. // Objects returned here must be treated as read-only. - Get(name string) (*v1beta2.Consumer, error) + Get(name string) (*jetstreamv1beta2.Consumer, error) ConsumerNamespaceListerExpansion } // consumerNamespaceLister implements the ConsumerNamespaceLister // interface. type consumerNamespaceLister struct { - listers.ResourceIndexer[*v1beta2.Consumer] + listers.ResourceIndexer[*jetstreamv1beta2.Consumer] } diff --git a/pkg/jetstream/generated/listers/jetstream/v1beta2/expansion_generated.go b/pkg/jetstream/generated/listers/jetstream/v1beta2/expansion_generated.go index 5cacc517..b49efd09 100644 --- a/pkg/jetstream/generated/listers/jetstream/v1beta2/expansion_generated.go +++ b/pkg/jetstream/generated/listers/jetstream/v1beta2/expansion_generated.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -31,6 +31,14 @@ type ConsumerListerExpansion interface{} // ConsumerNamespaceLister. type ConsumerNamespaceListerExpansion interface{} +// KeyValueListerExpansion allows custom methods to be added to +// KeyValueLister. +type KeyValueListerExpansion interface{} + +// KeyValueNamespaceListerExpansion allows custom methods to be added to +// KeyValueNamespaceLister. +type KeyValueNamespaceListerExpansion interface{} + // StreamListerExpansion allows custom methods to be added to // StreamLister. type StreamListerExpansion interface{} diff --git a/pkg/jetstream/generated/listers/jetstream/v1beta2/keyvalue.go b/pkg/jetstream/generated/listers/jetstream/v1beta2/keyvalue.go new file mode 100644 index 00000000..e9a691a7 --- /dev/null +++ b/pkg/jetstream/generated/listers/jetstream/v1beta2/keyvalue.go @@ -0,0 +1,67 @@ +// Copyright 2025 The NATS Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta2 + +import ( + jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" + labels "k8s.io/apimachinery/pkg/labels" + listers "k8s.io/client-go/listers" + cache "k8s.io/client-go/tools/cache" +) + +// KeyValueLister helps list KeyValues. +// All objects returned here must be treated as read-only. +type KeyValueLister interface { + // List lists all KeyValues in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*jetstreamv1beta2.KeyValue, err error) + // KeyValues returns an object that can list and get KeyValues. + KeyValues(namespace string) KeyValueNamespaceLister + KeyValueListerExpansion +} + +// keyValueLister implements the KeyValueLister interface. +type keyValueLister struct { + listers.ResourceIndexer[*jetstreamv1beta2.KeyValue] +} + +// NewKeyValueLister returns a new KeyValueLister. +func NewKeyValueLister(indexer cache.Indexer) KeyValueLister { + return &keyValueLister{listers.New[*jetstreamv1beta2.KeyValue](indexer, jetstreamv1beta2.Resource("keyvalue"))} +} + +// KeyValues returns an object that can list and get KeyValues. +func (s *keyValueLister) KeyValues(namespace string) KeyValueNamespaceLister { + return keyValueNamespaceLister{listers.NewNamespaced[*jetstreamv1beta2.KeyValue](s.ResourceIndexer, namespace)} +} + +// KeyValueNamespaceLister helps list and get KeyValues. +// All objects returned here must be treated as read-only. +type KeyValueNamespaceLister interface { + // List lists all KeyValues in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*jetstreamv1beta2.KeyValue, err error) + // Get retrieves the KeyValue from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*jetstreamv1beta2.KeyValue, error) + KeyValueNamespaceListerExpansion +} + +// keyValueNamespaceLister implements the KeyValueNamespaceLister +// interface. +type keyValueNamespaceLister struct { + listers.ResourceIndexer[*jetstreamv1beta2.KeyValue] +} diff --git a/pkg/jetstream/generated/listers/jetstream/v1beta2/stream.go b/pkg/jetstream/generated/listers/jetstream/v1beta2/stream.go index 7151a170..19bcfecf 100644 --- a/pkg/jetstream/generated/listers/jetstream/v1beta2/stream.go +++ b/pkg/jetstream/generated/listers/jetstream/v1beta2/stream.go @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,10 +16,10 @@ package v1beta2 import ( - v1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/listers" - "k8s.io/client-go/tools/cache" + jetstreamv1beta2 "github.com/nats-io/nack/pkg/jetstream/apis/jetstream/v1beta2" + labels "k8s.io/apimachinery/pkg/labels" + listers "k8s.io/client-go/listers" + cache "k8s.io/client-go/tools/cache" ) // StreamLister helps list Streams. @@ -27,7 +27,7 @@ import ( type StreamLister interface { // List lists all Streams in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1beta2.Stream, err error) + List(selector labels.Selector) (ret []*jetstreamv1beta2.Stream, err error) // Streams returns an object that can list and get Streams. Streams(namespace string) StreamNamespaceLister StreamListerExpansion @@ -35,17 +35,17 @@ type StreamLister interface { // streamLister implements the StreamLister interface. type streamLister struct { - listers.ResourceIndexer[*v1beta2.Stream] + listers.ResourceIndexer[*jetstreamv1beta2.Stream] } // NewStreamLister returns a new StreamLister. func NewStreamLister(indexer cache.Indexer) StreamLister { - return &streamLister{listers.New[*v1beta2.Stream](indexer, v1beta2.Resource("stream"))} + return &streamLister{listers.New[*jetstreamv1beta2.Stream](indexer, jetstreamv1beta2.Resource("stream"))} } // Streams returns an object that can list and get Streams. func (s *streamLister) Streams(namespace string) StreamNamespaceLister { - return streamNamespaceLister{listers.NewNamespaced[*v1beta2.Stream](s.ResourceIndexer, namespace)} + return streamNamespaceLister{listers.NewNamespaced[*jetstreamv1beta2.Stream](s.ResourceIndexer, namespace)} } // StreamNamespaceLister helps list and get Streams. @@ -53,15 +53,15 @@ func (s *streamLister) Streams(namespace string) StreamNamespaceLister { type StreamNamespaceLister interface { // List lists all Streams in the indexer for a given namespace. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1beta2.Stream, err error) + List(selector labels.Selector) (ret []*jetstreamv1beta2.Stream, err error) // Get retrieves the Stream from the indexer for a given namespace and name. // Objects returned here must be treated as read-only. - Get(name string) (*v1beta2.Stream, error) + Get(name string) (*jetstreamv1beta2.Stream, error) StreamNamespaceListerExpansion } // streamNamespaceLister implements the StreamNamespaceLister // interface. type streamNamespaceLister struct { - listers.ResourceIndexer[*v1beta2.Stream] + listers.ResourceIndexer[*jetstreamv1beta2.Stream] } diff --git a/pkg/k8scodegen/file-header.txt b/pkg/k8scodegen/file-header.txt index 780fa5e9..a620c453 100644 --- a/pkg/k8scodegen/file-header.txt +++ b/pkg/k8scodegen/file-header.txt @@ -1,4 +1,4 @@ -// Copyright 2024 The NATS Authors +// Copyright 2025 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/pkg/natsreloader/natsreloader_test.go b/pkg/natsreloader/natsreloader_test.go index 1e05edee..2425e434 100644 --- a/pkg/natsreloader/natsreloader_test.go +++ b/pkg/natsreloader/natsreloader_test.go @@ -88,10 +88,12 @@ tls: { ` ) -var configContents = `port = 2222` -var newConfigContents = `port = 2222 +var ( + configContents = `port = 2222` + newConfigContents = `port = 2222 someOtherThing = "bar" ` +) func TestReloader(t *testing.T) { // Setup a pidfile that points to us @@ -261,7 +263,6 @@ func TestInclude(t *testing.T) { t.Fatal("Expected include paths do not match") } } - } func TestFileFinder(t *testing.T) {