diff --git a/.config/api-rules/violation_exceptions.list b/.config/api-rules/violation_exceptions.list index 0ff8ac3866..30db9a4668 100644 --- a/.config/api-rules/violation_exceptions.list +++ b/.config/api-rules/violation_exceptions.list @@ -178,8 +178,32 @@ API rule violation: list_type_missing,kmodules.xyz/offshoot-api/api/v1,PodSpec,V API rule violation: list_type_missing,kmodules.xyz/offshoot-api/api/v1,ServiceSpec,ExternalIPs API rule violation: list_type_missing,kmodules.xyz/offshoot-api/api/v1,ServiceSpec,LoadBalancerSourceRanges API rule violation: list_type_missing,kmodules.xyz/offshoot-api/api/v1,ServiceSpec,Ports -API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/dashboard/v1alpha1,ElasticsearchDashboardSpec,ServiceTemplates -API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/dashboard/v1alpha1,ElasticsearchDashboardStatus,Conditions +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,ElasticsearchNodesStatSpec,Roles +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,ElasticsearchNodesStatsSpec,Nodes +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,ElasticsearchSchemaOverviewSpec,Indices +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,GenericSchemaOverviewSpec,Databases +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,MariaDBQueriesSpec,Queries +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,MongoDBCollectionSpec,TotalSize +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,MongoDBQueriesSpec,Queries +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,MongoDBSchemaOverviewSpec,Collections +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,MySQLQueriesSpec,Queries +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,PgBouncerInsightSpec,PodInsights +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,PgBouncerPoolOverviewSpec,Pools +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,PgBouncerServerOverviewSpec,Servers +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,PgBouncerSettingsSpec,Settings +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,PodInsight,QueryTypeInsight +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,PostgresInsightSpec,ReplicationStatus +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,PostgresQueriesSpec,Queries +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,PostgresSettingsSpec,Settings +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,ProxySQLInsightSpec,PodInsights +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,ProxySQLQueriesSpec,Queries +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,ProxySQLQuerySpec,SlowQueries +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,ProxySQLSettingsSpec,MySQLQueryRules +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,ProxySQLSettingsSpec,MySQLServers +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,ProxySQLSettingsSpec,ProxySQLServers +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,RedisQueriesSpec,Queries +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,RedisQuerySpec,Args +API rule violation: list_type_missing,kubedb.dev/apimachinery/apis/ui/v1alpha1,RedisSchemaOverviewSpec,Databases API rule violation: names_match,k8s.io/api/core/v1,AzureDiskVolumeSource,DataDiskURI API rule violation: names_match,k8s.io/api/core/v1,ContainerStatus,LastTerminationState API rule violation: names_match,k8s.io/api/core/v1,DaemonEndpoint,Port @@ -229,3 +253,121 @@ API rule violation: names_match,kmodules.xyz/client-go/api/v1,TimeOfDay,Time API rule violation: names_match,kmodules.xyz/offshoot-api/api/v1,ContainerRuntimeSettings,IONice API rule violation: names_match,kmodules.xyz/offshoot-api/api/v1,VolumeSource,CephFS API rule violation: names_match,kmodules.xyz/offshoot-api/api/v1,VolumeSource,StorageOS +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,MongoDBCollectionSpec,TotalSize +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsCompletionFields,SizeBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsCompletionFields,TotalSize +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsCompletionStats,SizeBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsCompletionStats,TotalSize +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsFieldDataFields,MemorySize +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsFieldDataFields,MemorySizeBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsFielddataStats,MemorySize +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsFielddataStats,MemorySizeBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsFlushStats,TotalTime +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsFlushStats,TotalTimeInMillis +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsGetStats,ExistsTime +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsGetStats,ExistsTimeInMillis +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsGetStats,MissingTime +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsGetStats,MissingTimeInMillis +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsGetStats,Time +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsGetStats,TimeInMillis +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsIndex,IndicesLevel +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsIndex,QueryCache +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsIndex,RequestCache +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsIndex,Shards +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsIndex,ShardsLevel +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsIndexingStats,DeleteCurrent +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsIndexingStats,DeleteTime +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsIndexingStats,DeleteTimeInMillis +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsIndexingStats,DeleteTotal +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsIndexingStats,IndexCurrent +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsIndexingStats,IndexFailed +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsIndexingStats,IndexTime +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsIndexingStats,IndexTimeInMillis +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsIndexingStats,IndexTotal +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsIndexingStats,IsThrottled +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsIndexingStats,NoopUpdateTotal +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsIndexingStats,ThrottledTime +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsIndexingStats,ThrottledTimeInMillis +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsMergeStats,CurrentDocs +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsMergeStats,CurrentSize +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsMergeStats,CurrentSizeBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsMergeStats,TotalDocs +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsMergeStats,TotalSize +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsMergeStats,TotalSizeBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsMergeStats,TotalStoppedTime +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsMergeStats,TotalStoppedTimeInMillis +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsMergeStats,TotalThrottleBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsMergeStats,TotalThrottleBytesBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsMergeStats,TotalThrottledTime +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsMergeStats,TotalThrottledTimeInMillis +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsMergeStats,TotalTime +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsMergeStats,TotalTimeInMillis +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsNodeOSCPU,LoadAverage +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsNodeOSMem,FreeBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsNodeOSMem,FreePercent +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsNodeOSMem,TotalBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsNodeOSMem,UsedBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsNodeOSMem,UsedPercent +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsNodeOSSwap,FreeBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsNodeOSSwap,TotalBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsNodeOSSwap,UsedBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsQueryCacheStats,CacheCount +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsQueryCacheStats,CacheSize +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsQueryCacheStats,HitCount +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsQueryCacheStats,MemorySize +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsQueryCacheStats,MemorySizeBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsQueryCacheStats,MissCount +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsQueryCacheStats,TotalCount +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsRecoveryStats,CurrentAsSource +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsRecoveryStats,CurrentAsTarget +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsRefreshStats,TotalTime +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsRefreshStats,TotalTimeInMillis +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsRequestCacheStats,HitCount +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsRequestCacheStats,MemorySize +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsRequestCacheStats,MemorySizeBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsRequestCacheStats,MissCount +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSearchStats,FetchCurrent +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSearchStats,FetchTime +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSearchStats,FetchTimeInMillis +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSearchStats,FetchTotal +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSearchStats,OpenContexts +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSearchStats,QueryCurrent +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSearchStats,QueryTime +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSearchStats,QueryTimeInMillis +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSearchStats,QueryTotal +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSearchStats,ScrollCurrent +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSearchStats,ScrollTime +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSearchStats,ScrollTimeInMillis +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSearchStats,ScrollTotal +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSegmentsStats,DocValuesMemory +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSegmentsStats,DocValuesMemoryBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSegmentsStats,FixedBitSetMemory +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSegmentsStats,FixedBitSetMemoryBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSegmentsStats,IndexWriterMaxMemory +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSegmentsStats,IndexWriterMaxMemoryBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSegmentsStats,IndexWriterMemory +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSegmentsStats,IndexWriterMemoryBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSegmentsStats,MemoryBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSegmentsStats,NormsMemory +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSegmentsStats,NormsMemoryBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSegmentsStats,StoredFieldsMemory +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSegmentsStats,StoredFieldsMemoryBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSegmentsStats,TermVectorsMemory +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSegmentsStats,TermVectorsMemoryBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSegmentsStats,TermsMemory +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSegmentsStats,TermsMemoryBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSegmentsStats,VersionMapMemory +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsSegmentsStats,VersionMapMemoryBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsShardCountStats,TotalCount +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsStoreStats,SizeBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsStoreStats,TotalSize +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsTranslogStats,SizeBytes +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsTranslogStats,TotalSize +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsWarmerStats,TotalTime +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,NodesStatsWarmerStats,TotalTimeInMillis +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,PodInsight,QueryTypeInsight +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,ProxySQLSettingsSpec,AdminVariables +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,ProxySQLSettingsSpec,MySQLQueryRules +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,ProxySQLSettingsSpec,MySQLServers +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,ProxySQLSettingsSpec,MySQLVariables +API rule violation: names_match,kubedb.dev/apimachinery/apis/ui/v1alpha1,ProxySQLSettingsSpec,ProxySQLServers diff --git a/apis/kubedb/v1alpha2/druid_helpers.go b/apis/kubedb/v1alpha2/druid_helpers.go index 296480ec07..4dd48f7147 100644 --- a/apis/kubedb/v1alpha2/druid_helpers.go +++ b/apis/kubedb/v1alpha2/druid_helpers.go @@ -1,3 +1,19 @@ +/* +Copyright AppsCode Inc. and Contributors + +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 v1alpha2 import ( diff --git a/go.mod b/go.mod index 9cb7876f4a..5f44c01b8b 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module kubedb.dev/apimachinery -go 1.21 +go 1.21.5 require ( github.com/Masterminds/semver/v3 v3.2.1 @@ -14,7 +14,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.70.0 github.com/prometheus-operator/prometheus-operator/pkg/client v0.70.0 - go.bytebuilders.dev/audit v0.0.29-0.20231225201242-3ff33160c6f0 + go.bytebuilders.dev/audit v0.0.32-0.20240105184043-9cf3195203b7 gomodules.xyz/encoding v0.0.7 gomodules.xyz/pointer v0.1.0 gomodules.xyz/runtime v0.3.0 @@ -103,6 +103,7 @@ require ( github.com/imdario/mergo v0.3.13 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/jonboulle/clockwork v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/compress v1.17.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect @@ -160,6 +161,7 @@ require ( golang.org/x/term v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect + gomodules.xyz/counter v0.0.1 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gomodules.xyz/mergo v0.3.13 // indirect gomodules.xyz/sets v0.2.1 // indirect diff --git a/go.sum b/go.sum index ec97fd36fa..d040f00ee8 100644 --- a/go.sum +++ b/go.sum @@ -460,8 +460,8 @@ github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHW github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= -github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= +github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= 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/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -731,8 +731,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.bytebuilders.dev/audit v0.0.29-0.20231225201242-3ff33160c6f0 h1:NOA3xOja8zVlnWcd+ap4PSHjH3IrCgXcQ8R1U6+ulr4= -go.bytebuilders.dev/audit v0.0.29-0.20231225201242-3ff33160c6f0/go.mod h1:VPU6L3GCSPEIEOOyH+gmwi6f8WpCkXsOCtqHggzJZzA= +go.bytebuilders.dev/audit v0.0.32-0.20240105184043-9cf3195203b7 h1:LaxhSR/p5uH9a7gPTGeAXJ58df9TxT4Hq9LjZAzmn0w= +go.bytebuilders.dev/audit v0.0.32-0.20240105184043-9cf3195203b7/go.mod h1:7B7cjCAoqAW+DghpBi6MzajKYxn4d+8dqx7iIAjMvu0= go.bytebuilders.dev/license-proxyserver v0.0.6 h1:9gstbQ/Ug8s6V1PzELbqLMIktXLn8NsnV7ZBtJg1f+w= go.bytebuilders.dev/license-proxyserver v0.0.6/go.mod h1:QmaFuBWQKFCgHp8UJVYGjWrJdoGB9Natw6qAFmElLp0= go.bytebuilders.dev/license-verifier v0.13.4 h1:K4qSsTWTZc7lyRvRHfI23XRrbVrQVJ8Ew5afvSiMdBE= @@ -1113,6 +1113,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T 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/counter v0.0.1 h1:ceHyWSJFgaMmUMmw5KLJSprxeqqEirAmltkZBhi/UOE= +gomodules.xyz/counter v0.0.1/go.mod h1:WlB0utIJzIaZgUs6sulne7DLzbEkAxvNGsMHkhjPaUY= gomodules.xyz/encoding v0.0.7 h1:Y4PaflVS+vkYgkw6FwyF1S0ab4Y1BAdOqB3Uwjcx8qI= gomodules.xyz/encoding v0.0.7/go.mod h1:blYJWy456Bzxj3L2G7G5WV1l5rFXl6uYXrmeFqxxqk8= gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= diff --git a/vendor/github.com/jonboulle/clockwork/.editorconfig b/vendor/github.com/jonboulle/clockwork/.editorconfig new file mode 100644 index 0000000000..4492e9f9fe --- /dev/null +++ b/vendor/github.com/jonboulle/clockwork/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.go] +indent_style = tab diff --git a/vendor/github.com/jonboulle/clockwork/.gitignore b/vendor/github.com/jonboulle/clockwork/.gitignore new file mode 100644 index 0000000000..00852bd942 --- /dev/null +++ b/vendor/github.com/jonboulle/clockwork/.gitignore @@ -0,0 +1,27 @@ +/.idea/ + +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test + +*.swp diff --git a/vendor/github.com/jonboulle/clockwork/LICENSE b/vendor/github.com/jonboulle/clockwork/LICENSE new file mode 100644 index 0000000000..5c304d1a4a --- /dev/null +++ b/vendor/github.com/jonboulle/clockwork/LICENSE @@ -0,0 +1,201 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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. diff --git a/vendor/github.com/jonboulle/clockwork/README.md b/vendor/github.com/jonboulle/clockwork/README.md new file mode 100644 index 0000000000..42970da802 --- /dev/null +++ b/vendor/github.com/jonboulle/clockwork/README.md @@ -0,0 +1,80 @@ +# clockwork + +[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge-flat.svg)](https://github.com/avelino/awesome-go#utilities) + +[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/jonboulle/clockwork/ci.yaml?style=flat-square)](https://github.com/jonboulle/clockwork/actions?query=workflow%3ACI) +[![Go Report Card](https://goreportcard.com/badge/github.com/jonboulle/clockwork?style=flat-square)](https://goreportcard.com/report/github.com/jonboulle/clockwork) +![Go Version](https://img.shields.io/badge/go%20version-%3E=1.15-61CFDD.svg?style=flat-square) +[![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/mod/github.com/jonboulle/clockwork) + +**A simple fake clock for Go.** + + +## Usage + +Replace uses of the `time` package with the `clockwork.Clock` interface instead. + +For example, instead of using `time.Sleep` directly: + +```go +func myFunc() { + time.Sleep(3 * time.Second) + doSomething() +} +``` + +Inject a clock and use its `Sleep` method instead: + +```go +func myFunc(clock clockwork.Clock) { + clock.Sleep(3 * time.Second) + doSomething() +} +``` + +Now you can easily test `myFunc` with a `FakeClock`: + +```go +func TestMyFunc(t *testing.T) { + c := clockwork.NewFakeClock() + + // Start our sleepy function + var wg sync.WaitGroup + wg.Add(1) + go func() { + myFunc(c) + wg.Done() + }() + + // Ensure we wait until myFunc is sleeping + c.BlockUntil(1) + + assertState() + + // Advance the FakeClock forward in time + c.Advance(3 * time.Second) + + // Wait until the function completes + wg.Wait() + + assertState() +} +``` + +and in production builds, simply inject the real clock instead: + +```go +myFunc(clockwork.NewRealClock()) +``` + +See [example_test.go](example_test.go) for a full example. + + +# Credits + +clockwork is inspired by @wickman's [threaded fake clock](https://gist.github.com/wickman/3840816), and the [Golang playground](https://blog.golang.org/playground#TOC_3.1.) + + +## License + +Apache License, Version 2.0. Please see [License File](LICENSE) for more information. diff --git a/vendor/github.com/jonboulle/clockwork/clockwork.go b/vendor/github.com/jonboulle/clockwork/clockwork.go new file mode 100644 index 0000000000..3206b36e4e --- /dev/null +++ b/vendor/github.com/jonboulle/clockwork/clockwork.go @@ -0,0 +1,349 @@ +package clockwork + +import ( + "context" + "sort" + "sync" + "time" +) + +// Clock provides an interface that packages can use instead of directly using +// the [time] module, so that chronology-related behavior can be tested. +type Clock interface { + After(d time.Duration) <-chan time.Time + Sleep(d time.Duration) + Now() time.Time + Since(t time.Time) time.Duration + NewTicker(d time.Duration) Ticker + NewTimer(d time.Duration) Timer + AfterFunc(d time.Duration, f func()) Timer +} + +// FakeClock provides an interface for a clock which can be manually advanced +// through time. +// +// FakeClock maintains a list of "waiters," which consists of all callers +// waiting on the underlying clock (i.e. Tickers and Timers including callers of +// Sleep or After). Users can call BlockUntil to block until the clock has an +// expected number of waiters. +type FakeClock interface { + Clock + // Advance advances the FakeClock to a new point in time, ensuring any existing + // waiters are notified appropriately before returning. + Advance(d time.Duration) + // BlockUntil blocks until the FakeClock has the given number of waiters. + BlockUntil(waiters int) +} + +// NewRealClock returns a Clock which simply delegates calls to the actual time +// package; it should be used by packages in production. +func NewRealClock() Clock { + return &realClock{} +} + +// NewFakeClock returns a FakeClock implementation which can be +// manually advanced through time for testing. The initial time of the +// FakeClock will be the current system time. +// +// Tests that require a deterministic time must use NewFakeClockAt. +func NewFakeClock() FakeClock { + return NewFakeClockAt(time.Now()) +} + +// NewFakeClockAt returns a FakeClock initialised at the given time.Time. +func NewFakeClockAt(t time.Time) FakeClock { + return &fakeClock{ + time: t, + } +} + +type realClock struct{} + +func (rc *realClock) After(d time.Duration) <-chan time.Time { + return time.After(d) +} + +func (rc *realClock) Sleep(d time.Duration) { + time.Sleep(d) +} + +func (rc *realClock) Now() time.Time { + return time.Now() +} + +func (rc *realClock) Since(t time.Time) time.Duration { + return rc.Now().Sub(t) +} + +func (rc *realClock) NewTicker(d time.Duration) Ticker { + return realTicker{time.NewTicker(d)} +} + +func (rc *realClock) NewTimer(d time.Duration) Timer { + return realTimer{time.NewTimer(d)} +} + +func (rc *realClock) AfterFunc(d time.Duration, f func()) Timer { + return realTimer{time.AfterFunc(d, f)} +} + +type fakeClock struct { + // l protects all attributes of the clock, including all attributes of all + // waiters and blockers. + l sync.RWMutex + waiters []expirer + blockers []*blocker + time time.Time +} + +// blocker is a caller of BlockUntil. +type blocker struct { + count int + + // ch is closed when the underlying clock has the specificed number of blockers. + ch chan struct{} +} + +// expirer is a timer or ticker that expires at some point in the future. +type expirer interface { + // expire the expirer at the given time, returning the desired duration until + // the next expiration, if any. + expire(now time.Time) (next *time.Duration) + + // Get and set the expiration time. + expiry() time.Time + setExpiry(time.Time) +} + +// After mimics [time.After]; it waits for the given duration to elapse on the +// fakeClock, then sends the current time on the returned channel. +func (fc *fakeClock) After(d time.Duration) <-chan time.Time { + return fc.NewTimer(d).Chan() +} + +// Sleep blocks until the given duration has passed on the fakeClock. +func (fc *fakeClock) Sleep(d time.Duration) { + <-fc.After(d) +} + +// Now returns the current time of the fakeClock +func (fc *fakeClock) Now() time.Time { + fc.l.RLock() + defer fc.l.RUnlock() + return fc.time +} + +// Since returns the duration that has passed since the given time on the +// fakeClock. +func (fc *fakeClock) Since(t time.Time) time.Duration { + return fc.Now().Sub(t) +} + +// NewTicker returns a Ticker that will expire only after calls to +// fakeClock.Advance() have moved the clock past the given duration. +func (fc *fakeClock) NewTicker(d time.Duration) Ticker { + var ft *fakeTicker + ft = &fakeTicker{ + firer: newFirer(), + d: d, + reset: func(d time.Duration) { fc.set(ft, d) }, + stop: func() { fc.stop(ft) }, + } + fc.set(ft, d) + return ft +} + +// NewTimer returns a Timer that will fire only after calls to +// fakeClock.Advance() have moved the clock past the given duration. +func (fc *fakeClock) NewTimer(d time.Duration) Timer { + return fc.newTimer(d, nil) +} + +// AfterFunc mimics [time.AfterFunc]; it returns a Timer that will invoke the +// given function only after calls to fakeClock.Advance() have moved the clock +// past the given duration. +func (fc *fakeClock) AfterFunc(d time.Duration, f func()) Timer { + return fc.newTimer(d, f) +} + +// newTimer returns a new timer, using an optional afterFunc. +func (fc *fakeClock) newTimer(d time.Duration, afterfunc func()) *fakeTimer { + var ft *fakeTimer + ft = &fakeTimer{ + firer: newFirer(), + reset: func(d time.Duration) bool { + fc.l.Lock() + defer fc.l.Unlock() + // fc.l must be held across the calls to stopExpirer & setExpirer. + stopped := fc.stopExpirer(ft) + fc.setExpirer(ft, d) + return stopped + }, + stop: func() bool { return fc.stop(ft) }, + + afterFunc: afterfunc, + } + fc.set(ft, d) + return ft +} + +// Advance advances fakeClock to a new point in time, ensuring waiters and +// blockers are notified appropriately before returning. +func (fc *fakeClock) Advance(d time.Duration) { + fc.l.Lock() + defer fc.l.Unlock() + end := fc.time.Add(d) + // Expire the earliest waiter until the earliest waiter's expiration is after + // end. + // + // We don't iterate because the callback of the waiter might register a new + // waiter, so the list of waiters might change as we execute this. + for len(fc.waiters) > 0 && !end.Before(fc.waiters[0].expiry()) { + w := fc.waiters[0] + fc.waiters = fc.waiters[1:] + + // Use the waiter's expriation as the current time for this expiration. + now := w.expiry() + fc.time = now + if d := w.expire(now); d != nil { + // Set the new exipration if needed. + fc.setExpirer(w, *d) + } + } + fc.time = end +} + +// BlockUntil blocks until the fakeClock has the given number of waiters. +// +// Prefer BlockUntilContext, which offers context cancellation to prevent +// deadlock. +// +// Deprecation warning: This function might be deprecated in later versions. +func (fc *fakeClock) BlockUntil(n int) { + b := fc.newBlocker(n) + if b == nil { + return + } + <-b.ch +} + +// BlockUntilContext blocks until the fakeClock has the given number of waiters +// or the context is cancelled. +func (fc *fakeClock) BlockUntilContext(ctx context.Context, n int) error { + b := fc.newBlocker(n) + if b == nil { + return nil + } + + select { + case <-b.ch: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +func (fc *fakeClock) newBlocker(n int) *blocker { + fc.l.Lock() + defer fc.l.Unlock() + // Fast path: we already have >= n waiters. + if len(fc.waiters) >= n { + return nil + } + // Set up a new blocker to wait for more waiters. + b := &blocker{ + count: n, + ch: make(chan struct{}), + } + fc.blockers = append(fc.blockers, b) + return b +} + +// stop stops an expirer, returning true if the expirer was stopped. +func (fc *fakeClock) stop(e expirer) bool { + fc.l.Lock() + defer fc.l.Unlock() + return fc.stopExpirer(e) +} + +// stopExpirer stops an expirer, returning true if the expirer was stopped. +// +// The caller must hold fc.l. +func (fc *fakeClock) stopExpirer(e expirer) bool { + for i, t := range fc.waiters { + if t == e { + // Remove element, maintaining order. + copy(fc.waiters[i:], fc.waiters[i+1:]) + fc.waiters[len(fc.waiters)-1] = nil + fc.waiters = fc.waiters[:len(fc.waiters)-1] + return true + } + } + return false +} + +// set sets an expirer to expire at a future point in time. +func (fc *fakeClock) set(e expirer, d time.Duration) { + fc.l.Lock() + defer fc.l.Unlock() + fc.setExpirer(e, d) +} + +// setExpirer sets an expirer to expire at a future point in time. +// +// The caller must hold fc.l. +func (fc *fakeClock) setExpirer(e expirer, d time.Duration) { + if d.Nanoseconds() <= 0 { + // special case - trigger immediately, never reset. + // + // TODO: Explain what cases this covers. + e.expire(fc.time) + return + } + // Add the expirer to the set of waiters and notify any blockers. + e.setExpiry(fc.time.Add(d)) + fc.waiters = append(fc.waiters, e) + sort.Slice(fc.waiters, func(i int, j int) bool { + return fc.waiters[i].expiry().Before(fc.waiters[j].expiry()) + }) + + // Notify blockers of our new waiter. + var blocked []*blocker + count := len(fc.waiters) + for _, b := range fc.blockers { + if b.count <= count { + close(b.ch) + continue + } + blocked = append(blocked, b) + } + fc.blockers = blocked +} + +// firer is used by fakeTimer and fakeTicker used to help implement expirer. +type firer struct { + // The channel associated with the firer, used to send expriation times. + c chan time.Time + + // The time when the firer expires. Only meaningful if the firer is currently + // one of a fakeClock's waiters. + exp time.Time +} + +func newFirer() firer { + return firer{c: make(chan time.Time, 1)} +} + +func (f *firer) Chan() <-chan time.Time { + return f.c +} + +// expiry implements expirer. +func (f *firer) expiry() time.Time { + return f.exp +} + +// setExpiry implements expirer. +func (f *firer) setExpiry(t time.Time) { + f.exp = t +} diff --git a/vendor/github.com/jonboulle/clockwork/context.go b/vendor/github.com/jonboulle/clockwork/context.go new file mode 100644 index 0000000000..edbb368f09 --- /dev/null +++ b/vendor/github.com/jonboulle/clockwork/context.go @@ -0,0 +1,25 @@ +package clockwork + +import ( + "context" +) + +// contextKey is private to this package so we can ensure uniqueness here. This +// type identifies context values provided by this package. +type contextKey string + +// keyClock provides a clock for injecting during tests. If absent, a real clock should be used. +var keyClock = contextKey("clock") // clockwork.Clock + +// AddToContext creates a derived context that references the specified clock. +func AddToContext(ctx context.Context, clock Clock) context.Context { + return context.WithValue(ctx, keyClock, clock) +} + +// FromContext extracts a clock from the context. If not present, a real clock is returned. +func FromContext(ctx context.Context) Clock { + if clock, ok := ctx.Value(keyClock).(Clock); ok { + return clock + } + return NewRealClock() +} diff --git a/vendor/github.com/jonboulle/clockwork/ticker.go b/vendor/github.com/jonboulle/clockwork/ticker.go new file mode 100644 index 0000000000..b68e4d7773 --- /dev/null +++ b/vendor/github.com/jonboulle/clockwork/ticker.go @@ -0,0 +1,48 @@ +package clockwork + +import "time" + +// Ticker provides an interface which can be used instead of directly using +// [time.Ticker]. The real-time ticker t provides ticks through t.C which +// becomes t.Chan() to make this channel requirement definable in this +// interface. +type Ticker interface { + Chan() <-chan time.Time + Reset(d time.Duration) + Stop() +} + +type realTicker struct{ *time.Ticker } + +func (r realTicker) Chan() <-chan time.Time { + return r.C +} + +type fakeTicker struct { + firer + + // reset and stop provide the implementation of the respective exported + // functions. + reset func(d time.Duration) + stop func() + + // The duration of the ticker. + d time.Duration +} + +func (f *fakeTicker) Reset(d time.Duration) { + f.reset(d) +} + +func (f *fakeTicker) Stop() { + f.stop() +} + +func (f *fakeTicker) expire(now time.Time) *time.Duration { + // Never block on expiration. + select { + case f.c <- now: + default: + } + return &f.d +} diff --git a/vendor/github.com/jonboulle/clockwork/timer.go b/vendor/github.com/jonboulle/clockwork/timer.go new file mode 100644 index 0000000000..6f928b3dde --- /dev/null +++ b/vendor/github.com/jonboulle/clockwork/timer.go @@ -0,0 +1,53 @@ +package clockwork + +import "time" + +// Timer provides an interface which can be used instead of directly using +// [time.Timer]. The real-time timer t provides events through t.C which becomes +// t.Chan() to make this channel requirement definable in this interface. +type Timer interface { + Chan() <-chan time.Time + Reset(d time.Duration) bool + Stop() bool +} + +type realTimer struct{ *time.Timer } + +func (r realTimer) Chan() <-chan time.Time { + return r.C +} + +type fakeTimer struct { + firer + + // reset and stop provide the implmenetation of the respective exported + // functions. + reset func(d time.Duration) bool + stop func() bool + + // If present when the timer fires, the timer calls afterFunc in its own + // goroutine rather than sending the time on Chan(). + afterFunc func() +} + +func (f *fakeTimer) Reset(d time.Duration) bool { + return f.reset(d) +} + +func (f *fakeTimer) Stop() bool { + return f.stop() +} + +func (f *fakeTimer) expire(now time.Time) *time.Duration { + if f.afterFunc != nil { + go f.afterFunc() + return nil + } + + // Never block on expiration. + select { + case f.c <- now: + default: + } + return nil +} diff --git a/vendor/go.bytebuilders.dev/audit/lib/node.go b/vendor/go.bytebuilders.dev/audit/lib/node.go new file mode 100644 index 0000000000..3870d32d17 --- /dev/null +++ b/vendor/go.bytebuilders.dev/audit/lib/node.go @@ -0,0 +1,127 @@ +/* +Copyright AppsCode Inc. and Contributors + +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 lib + +import ( + "fmt" + + api "go.bytebuilders.dev/audit/api/v1" + + "gomodules.xyz/counter/hourly" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/tools/cache" + "k8s.io/klog/v2" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var siteEventCounter hourly.Int32 + +type SiteInfoPublisher struct { + p *EventPublisher + createEvent EventCreator +} + +var _ cache.ResourceEventHandler = &SiteInfoPublisher{} + +func (p *SiteInfoPublisher) OnAdd(o interface{}, isInInitialList bool) { + obj, ok := o.(client.Object) + if !ok { + return + } + + ev, err := p.createEvent(obj) + if err != nil { + klog.V(5).InfoS("failed to create event data", "error", err) + return + } + + if err = p.p.Publish(ev, api.EventCreated); err != nil { + klog.V(5).InfoS("error while publishing event", "error", err) + return + } + + siteEventCounter.Inc() +} + +func (p *SiteInfoPublisher) OnUpdate(oldObj, newObj interface{}) { + uOld, ok := oldObj.(client.Object) + if !ok { + return + } + uNew, ok := newObj.(client.Object) + if !ok { + return + } + + alreadySentHourly := siteEventCounter.Get() > 0 + if alreadySentHourly && + uOld.GetUID() == uNew.GetUID() && uOld.GetGeneration() == uNew.GetGeneration() { + if klog.V(8).Enabled() { + klog.V(8).InfoS("skipping update event", + "gvk", uNew.GetObjectKind().GroupVersionKind(), + "namespace", uNew.GetNamespace(), + "name", uNew.GetName(), + ) + } + return + } + + ev, err := p.createEvent(uNew) + if err != nil { + klog.V(5).InfoS("failed to create event data", "error", err) + return + } + + if err = p.p.Publish(ev, api.EventUpdated); err != nil { + klog.V(5).InfoS("failed to publish event", "error", err) + return + } + + siteEventCounter.Inc() +} + +func (p *SiteInfoPublisher) OnDelete(obj interface{}) { + var object client.Object + var ok bool + if object, ok = obj.(client.Object); !ok { + tombstone, ok := obj.(cache.DeletedFinalStateUnknown) + if !ok { + klog.V(5).Info("error decoding object, invalid type") + return + } + object, ok = tombstone.Obj.(client.Object) + if !ok { + utilruntime.HandleError(fmt.Errorf("error decoding object tombstone, invalid type")) + return + } + klog.V(5).Infof("Recovered deleted object '%v' from tombstone", tombstone.Obj.(metav1.Object).GetName()) + } + + ev, err := p.createEvent(object) + if err != nil { + klog.V(5).InfoS("failed to create event data", "error", err) + return + } + + if err := p.p.Publish(ev, api.EventDeleted); err != nil { + klog.V(5).InfoS("failed to publish event", "error", err) + return + } + + siteEventCounter.Inc() +} diff --git a/vendor/go.bytebuilders.dev/audit/lib/publisher.go b/vendor/go.bytebuilders.dev/audit/lib/publisher.go index 440a790c0a..c5c3fce65a 100644 --- a/vendor/go.bytebuilders.dev/audit/lib/publisher.go +++ b/vendor/go.bytebuilders.dev/audit/lib/publisher.go @@ -31,10 +31,8 @@ import ( "go.bytebuilders.dev/license-verifier/info" "gomodules.xyz/sync" core "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime/schema" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" @@ -51,6 +49,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/manager" ) +const eventInterval = 1 * time.Hour + // Informer - informer allows you interact with the underlying informer. type Informer interface { // AddEventHandlerWithResyncPeriod adds an event handler to the shared informer using the @@ -171,7 +171,8 @@ func (p *EventPublisher) ForGVK(informer Informer, gvk schema.GroupVersionKind) } h := &ResourceEventPublisher{ - p: p, + p: p, + counters: map[kmapi.OID]int32{}, createEvent: func(obj client.Object) (*api.Event, error) { r := obj.DeepCopyObject().(client.Object) r.GetObjectKind().SetGroupVersionKind(gvk) @@ -191,7 +192,7 @@ func (p *EventPublisher) ForGVK(informer Informer, gvk schema.GroupVersionKind) return ev, nil }, } - _, _ = informer.AddEventHandlerWithResyncPeriod(h, 1*time.Hour) + _, _ = informer.AddEventHandlerWithResyncPeriod(h, eventInterval) } type funcNodeLister func() ([]*core.Node, error) @@ -238,7 +239,7 @@ func (p *EventPublisher) setupSiteInfoPublisher(cfg *rest.Config, kc kubernetes. p.si.Product = new(auditorapi.ProductInfo) } - _, err = nodeInformer.AddEventHandler(&ResourceEventPublisher{ + _, err = nodeInformer.AddEventHandlerWithResyncPeriod(&SiteInfoPublisher{ p: p, createEvent: func(_ client.Object) (*api.Event, error) { cmeta, err := clusterid.ClusterMetadata(kc.CoreV1().Namespaces()) @@ -275,7 +276,7 @@ func (p *EventPublisher) setupSiteInfoPublisher(cfg *rest.Config, kc kubernetes. } return ev, nil }, - }) + }, eventInterval) return err } @@ -298,72 +299,3 @@ func (p *EventPublisher) SetupWithManager(ctx context.Context, mgr manager.Manag } return p.SetupWithManagerForKind(ctx, mgr, gvk) } - -type ResourceEventPublisher struct { - p *EventPublisher - createEvent EventCreator -} - -var _ cache.ResourceEventHandler = &ResourceEventPublisher{} - -func (p *ResourceEventPublisher) OnAdd(o interface{}, isInInitialList bool) { - obj, ok := o.(client.Object) - if !ok { - return - } - - ev, err := p.createEvent(obj) - if err != nil { - klog.V(5).InfoS("failed to create event data", "error", err) - return - } - - if err = p.p.Publish(ev, api.EventCreated); err != nil { - klog.V(5).InfoS("error while publishing event", "error", err) - } -} - -func (p *ResourceEventPublisher) OnUpdate(_, newObj interface{}) { - uNew, ok := newObj.(client.Object) - if !ok { - return - } - - ev, err := p.createEvent(uNew) - if err != nil { - klog.V(5).InfoS("failed to create event data", "error", err) - return - } - - if err = p.p.Publish(ev, api.EventUpdated); err != nil { - klog.V(5).InfoS("failed to publish event", "error", err) - } -} - -func (p *ResourceEventPublisher) OnDelete(obj interface{}) { - var object client.Object - var ok bool - if object, ok = obj.(client.Object); !ok { - tombstone, ok := obj.(cache.DeletedFinalStateUnknown) - if !ok { - klog.V(5).Info("error decoding object, invalid type") - return - } - object, ok = tombstone.Obj.(client.Object) - if !ok { - utilruntime.HandleError(fmt.Errorf("error decoding object tombstone, invalid type")) - return - } - klog.V(5).Infof("Recovered deleted object '%v' from tombstone", tombstone.Obj.(metav1.Object).GetName()) - } - - ev, err := p.createEvent(object) - if err != nil { - klog.V(5).InfoS("failed to create event data", "error", err) - return - } - - if err := p.p.Publish(ev, api.EventDeleted); err != nil { - klog.V(5).InfoS("failed to publish event", "error", err) - } -} diff --git a/vendor/go.bytebuilders.dev/audit/lib/resource.go b/vendor/go.bytebuilders.dev/audit/lib/resource.go new file mode 100644 index 0000000000..7579369163 --- /dev/null +++ b/vendor/go.bytebuilders.dev/audit/lib/resource.go @@ -0,0 +1,150 @@ +/* +Copyright AppsCode Inc. and Contributors + +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 lib + +import ( + "fmt" + gosync "sync" + + api "go.bytebuilders.dev/audit/api/v1" + + "gomodules.xyz/counter/hourly" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/tools/cache" + "k8s.io/klog/v2" + kmapi "kmodules.xyz/client-go/api/v1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type ResourceEventPublisher struct { + p *EventPublisher + createEvent EventCreator + + counters map[kmapi.OID]int32 + mu gosync.Mutex +} + +var _ cache.ResourceEventHandler = &ResourceEventPublisher{} + +func (p *ResourceEventPublisher) OnAdd(o interface{}, isInInitialList bool) { + obj, ok := o.(client.Object) + if !ok { + return + } + + ev, err := p.createEvent(obj) + if err != nil { + klog.V(5).InfoS("failed to create event data", "error", err) + return + } + + if err = p.p.Publish(ev, api.EventCreated); err != nil { + klog.V(5).InfoS("error while publishing event", "error", err) + return + } + + p.mu.Lock() + oid := kmapi.NewObjectID(obj).OID() + c := p.counters[oid] + hourly.Inc32(&c) + p.counters[oid] = c + p.mu.Unlock() +} + +func (p *ResourceEventPublisher) OnUpdate(oldObj, newObj interface{}) { + uOld, ok := oldObj.(client.Object) + if !ok { + return + } + uNew, ok := newObj.(client.Object) + if !ok { + return + } + + alreadySentHourly := false + oid := kmapi.NewObjectID(uNew).OID() + p.mu.Lock() + c := p.counters[oid] + alreadySentHourly = hourly.Get32(&c) > 0 + p.mu.Unlock() + + if alreadySentHourly && + uOld.GetUID() == uNew.GetUID() && uOld.GetGeneration() == uNew.GetGeneration() { + if klog.V(8).Enabled() { + klog.V(8).InfoS("skipping update event", + "gvk", uNew.GetObjectKind().GroupVersionKind(), + "namespace", uNew.GetNamespace(), + "name", uNew.GetName(), + ) + } + return + } + + ev, err := p.createEvent(uNew) + if err != nil { + klog.V(5).InfoS("failed to create event data", "error", err) + return + } + + if err = p.p.Publish(ev, api.EventUpdated); err != nil { + klog.V(5).InfoS("failed to publish event", "error", err) + return + } + + p.mu.Lock() + c = p.counters[oid] + hourly.Inc32(&c) + p.counters[oid] = c + p.mu.Unlock() +} + +func (p *ResourceEventPublisher) OnDelete(obj interface{}) { + var object client.Object + var ok bool + if object, ok = obj.(client.Object); !ok { + tombstone, ok := obj.(cache.DeletedFinalStateUnknown) + if !ok { + klog.V(5).Info("error decoding object, invalid type") + return + } + object, ok = tombstone.Obj.(client.Object) + if !ok { + utilruntime.HandleError(fmt.Errorf("error decoding object tombstone, invalid type")) + return + } + klog.V(5).Infof("Recovered deleted object '%v' from tombstone", tombstone.Obj.(metav1.Object).GetName()) + } + + ev, err := p.createEvent(object) + if err != nil { + klog.V(5).InfoS("failed to create event data", "error", err) + return + } + + if err := p.p.Publish(ev, api.EventDeleted); err != nil { + klog.V(5).InfoS("failed to publish event", "error", err) + return + } + + p.mu.Lock() + oid := kmapi.NewObjectID(object).OID() + c := p.counters[oid] + hourly.Inc32(&c) + p.counters[oid] = c + p.mu.Unlock() +} diff --git a/vendor/gomodules.xyz/counter/LICENSE b/vendor/gomodules.xyz/counter/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/vendor/gomodules.xyz/counter/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/vendor/gomodules.xyz/counter/hourly/int.go b/vendor/gomodules.xyz/counter/hourly/int.go new file mode 100644 index 0000000000..f786afeedc --- /dev/null +++ b/vendor/gomodules.xyz/counter/hourly/int.go @@ -0,0 +1,20 @@ +package hourly + +import "sync" + +type Int struct { + c int + m sync.RWMutex +} + +func (i *Int) Inc() int { + i.m.Lock() + defer i.m.Unlock() + return Inc(&i.c) +} + +func (i *Int) Get() int { + i.m.RLock() + defer i.m.RUnlock() + return Get(&i.c) +} diff --git a/vendor/gomodules.xyz/counter/hourly/int32.go b/vendor/gomodules.xyz/counter/hourly/int32.go new file mode 100644 index 0000000000..225fd1b3dc --- /dev/null +++ b/vendor/gomodules.xyz/counter/hourly/int32.go @@ -0,0 +1,20 @@ +package hourly + +import "sync" + +type Int32 struct { + c int32 + m sync.RWMutex +} + +func (i *Int32) Inc() int32 { + i.m.Lock() + defer i.m.Unlock() + return Inc32(&i.c) +} + +func (i *Int32) Get() int32 { + i.m.RLock() + defer i.m.RUnlock() + return Get32(&i.c) +} diff --git a/vendor/gomodules.xyz/counter/hourly/int64.go b/vendor/gomodules.xyz/counter/hourly/int64.go new file mode 100644 index 0000000000..ee59dfa52d --- /dev/null +++ b/vendor/gomodules.xyz/counter/hourly/int64.go @@ -0,0 +1,20 @@ +package hourly + +import "sync" + +type Int64 struct { + c int64 + m sync.RWMutex +} + +func (i *Int64) Inc() int64 { + i.m.Lock() + defer i.m.Unlock() + return Inc64(&i.c) +} + +func (i *Int64) Get() int64 { + i.m.RLock() + defer i.m.RUnlock() + return Get64(&i.c) +} diff --git a/vendor/gomodules.xyz/counter/hourly/lib.go b/vendor/gomodules.xyz/counter/hourly/lib.go new file mode 100644 index 0000000000..a16d3f4c17 --- /dev/null +++ b/vendor/gomodules.xyz/counter/hourly/lib.go @@ -0,0 +1,78 @@ +package hourly + +import ( + "github.com/jonboulle/clockwork" +) + +var Clock = clockwork.NewRealClock() + +const ( + SuffixLen = 6 // bits.Len(23) + 1 + Suffix = 0b0111111 +) + +func Inc(addr *int) int { + stored := *addr + storedTime := int(stored & Suffix) + curTime := Clock.Now().Hour() + if storedTime == curTime { + *addr = ((stored>>SuffixLen)+1)<> SuffixLen + } + return 0 +} + +func Inc64(addr *int64) int64 { + stored := *addr + storedTime := int(stored & Suffix) + curTime := Clock.Now().Hour() + if storedTime == curTime { + *addr = ((stored>>SuffixLen)+1)<> SuffixLen + } + return 0 +} + +func Inc32(addr *int32) int32 { + stored := *addr + storedTime := int(stored & Suffix) + curTime := Clock.Now().Hour() + if storedTime == curTime { + *addr = ((stored>>SuffixLen)+1)<> SuffixLen + } + return 0 +} diff --git a/vendor/modules.txt b/vendor/modules.txt index d4c715b9ac..1bafe55e95 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -372,6 +372,9 @@ github.com/inconshreveable/mousetrap # github.com/jmespath/go-jmespath v0.4.0 ## explicit; go 1.14 github.com/jmespath/go-jmespath +# github.com/jonboulle/clockwork v0.4.0 +## explicit; go 1.15 +github.com/jonboulle/clockwork # github.com/josharian/intern v1.0.0 ## explicit; go 1.5 github.com/josharian/intern @@ -515,7 +518,7 @@ github.com/yudai/gojsondiff/formatter # github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 ## explicit github.com/yudai/golcs -# go.bytebuilders.dev/audit v0.0.29-0.20231225201242-3ff33160c6f0 +# go.bytebuilders.dev/audit v0.0.32-0.20240105184043-9cf3195203b7 ## explicit; go 1.21.5 go.bytebuilders.dev/audit/api/v1 go.bytebuilders.dev/audit/lib @@ -742,6 +745,9 @@ golang.org/x/text/width # golang.org/x/time v0.5.0 ## explicit; go 1.18 golang.org/x/time/rate +# gomodules.xyz/counter v0.0.1 +## explicit; go 1.21.5 +gomodules.xyz/counter/hourly # gomodules.xyz/encoding v0.0.7 ## explicit; go 1.17 gomodules.xyz/encoding/json