diff --git a/cmd/anycastmonitor/main.go b/cmd/anycastmonitor/main.go index b668e4eba..a75b82d6e 100644 --- a/cmd/anycastmonitor/main.go +++ b/cmd/anycastmonitor/main.go @@ -113,7 +113,7 @@ func run(cmd *cobra.Command, args []string) { // expose metrics endpoint mux := http.NewServeMux() mux.Handle("/metrics", promhttp.Handler()) - ctx := httpext.ContextWithSIGINT(context.Background(), 1*time.Second) + ctx := httpext.ContextWithSIGINT(cmd.Context(), 1*time.Second) go func() { must.Succeed(httpext.ListenAndServeContext(ctx, listenAddress, mux)) }() diff --git a/cmd/api/main.go b/cmd/api/main.go index cec38f08b..38f37bef4 100644 --- a/cmd/api/main.go +++ b/cmd/api/main.go @@ -20,7 +20,6 @@ package apicmd import ( - "context" "fmt" "net/http" "os" @@ -64,8 +63,8 @@ func run(cmd *cobra.Command, args []string) { keppel.SetTaskName("api") cfg := keppel.ParseConfiguration() - ctx := httpext.ContextWithSIGINT(context.Background(), 10*time.Second) - auditor := keppel.InitAuditTrail() + ctx := httpext.ContextWithSIGINT(cmd.Context(), 10*time.Second) + auditor := keppel.InitAuditTrail(ctx) db := must.Return(keppel.InitDB(cfg.DatabaseURL)) must.Succeed(setupDBIfRequested(db)) diff --git a/cmd/healthmonitor/main.go b/cmd/healthmonitor/main.go index ec0631797..928fe4980 100644 --- a/cmd/healthmonitor/main.go +++ b/cmd/healthmonitor/main.go @@ -81,7 +81,7 @@ type healthMonitorJob struct { } func run(cmd *cobra.Command, args []string) { - ctx := httpext.ContextWithSIGINT(context.Background(), 1*time.Second) + ctx := httpext.ContextWithSIGINT(cmd.Context(), 1*time.Second) keppel.SetTaskName("health-monitor") prometheus.MustRegister(healthmonitorResultGauge) diff --git a/cmd/janitor/main.go b/cmd/janitor/main.go index 7a8878af9..5dc05cf40 100644 --- a/cmd/janitor/main.go +++ b/cmd/janitor/main.go @@ -19,7 +19,6 @@ package janitorcmd import ( - "context" "net/http" "time" @@ -54,8 +53,8 @@ func run(cmd *cobra.Command, args []string) { keppel.SetTaskName("janitor") cfg := keppel.ParseConfiguration() - ctx := httpext.ContextWithSIGINT(context.Background(), 10*time.Second) - auditor := keppel.InitAuditTrail() + ctx := httpext.ContextWithSIGINT(cmd.Context(), 10*time.Second) + auditor := keppel.InitAuditTrail(ctx) db := must.Return(keppel.InitDB(cfg.DatabaseURL)) ad := must.Return(keppel.NewAuthDriver(ctx, osext.MustGetenv("KEPPEL_DRIVER_AUTH"), nil)) diff --git a/cmd/trivyproxy/main.go b/cmd/trivyproxy/main.go index ca3523e25..fa1e51f65 100644 --- a/cmd/trivyproxy/main.go +++ b/cmd/trivyproxy/main.go @@ -58,7 +58,7 @@ The token is used to both authenticate API requests to the proxy, as well to aut func run(cmd *cobra.Command, args []string) { keppel.SetTaskName("trivy") - ctx := httpext.ContextWithSIGINT(context.Background(), 10*time.Second) + ctx := httpext.ContextWithSIGINT(cmd.Context(), 10*time.Second) token := osext.MustGetenv("KEPPEL_TRIVY_TOKEN") dbMirrorPrefix := osext.MustGetenv("KEPPEL_TRIVY_DB_MIRROR_PREFIX") diff --git a/go.mod b/go.mod index c2731d736..9b9455077 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/redis/go-redis/v9 v9.5.3 github.com/rs/cors v1.11.0 github.com/sapcc/go-api-declarations v1.11.3 - github.com/sapcc/go-bits v0.0.0-20240708133634-c3fa8372671d + github.com/sapcc/go-bits v0.0.0-20240709125621-b1e90ef040ad github.com/spf13/cobra v1.8.1 github.com/timewasted/go-accept-headers v0.0.0-20130320203746-c78f304b1b09 go.uber.org/automaxprocs v1.5.3 diff --git a/go.sum b/go.sum index 8b3b82bb3..ecc76be1f 100644 --- a/go.sum +++ b/go.sum @@ -185,8 +185,8 @@ github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= github.com/sapcc/go-api-declarations v1.11.3 h1:A8JgeSmOdziYXuiOes9Lp3LKZ0FsU2lc9FOxoM3kRR0= github.com/sapcc/go-api-declarations v1.11.3/go.mod h1:83R3hTANhuRXt/pXDby37IJetw8l7DG41s33Tp9NXxI= -github.com/sapcc/go-bits v0.0.0-20240708133634-c3fa8372671d h1:T2+b3BdnLVgagXxNgTyk/1MTSKDk1wAEmt6tFwrQo2U= -github.com/sapcc/go-bits v0.0.0-20240708133634-c3fa8372671d/go.mod h1:d9JN0Gm8lF5jUMQeH/3MS5iNhs6/AlR/wVQ8vxRAGmo= +github.com/sapcc/go-bits v0.0.0-20240709125621-b1e90ef040ad h1:e0kDKCEhohs+oKwYRRAibCJdqd2DvLwWrK17yELxUpY= +github.com/sapcc/go-bits v0.0.0-20240709125621-b1e90ef040ad/go.mod h1:d9JN0Gm8lF5jUMQeH/3MS5iNhs6/AlR/wVQ8vxRAGmo= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= diff --git a/internal/drivers/openstack/cache.go b/internal/drivers/openstack/cache.go index 567cd32a5..d5031ef74 100644 --- a/internal/drivers/openstack/cache.go +++ b/internal/drivers/openstack/cache.go @@ -40,15 +40,15 @@ func hashCacheKey(cacheKey string) string { return "keystone-" + hex.EncodeToString(sha256Hash[:]) } -func (c redisCacher) StoreTokenPayload(cacheKey string, payload []byte) { - err := c.Set(context.Background(), hashCacheKey(cacheKey), payload, 5*time.Minute).Err() +func (c redisCacher) StoreTokenPayload(ctx context.Context, cacheKey string, payload []byte) { + err := c.Set(ctx, hashCacheKey(cacheKey), payload, 5*time.Minute).Err() if err != nil { logg.Error("cannot cache token payload in Redis: %s", err.Error()) } } -func (c redisCacher) LoadTokenPayload(cacheKey string) []byte { - payload, err := c.Get(context.Background(), hashCacheKey(cacheKey)).Bytes() +func (c redisCacher) LoadTokenPayload(ctx context.Context, cacheKey string) []byte { + payload, err := c.Get(ctx, hashCacheKey(cacheKey)).Bytes() if errors.Is(err, redis.Nil) { return nil } diff --git a/internal/drivers/openstack/keystone.go b/internal/drivers/openstack/keystone.go index 50f0a57bf..ff8e3cb63 100644 --- a/internal/drivers/openstack/keystone.go +++ b/internal/drivers/openstack/keystone.go @@ -134,7 +134,7 @@ func (d *keystoneDriver) AuthenticateUser(ctx context.Context, userName, passwor throwAwayClient.SetTokenAndAuthResult(nil) //nolint:errcheck t := d.TokenValidator.CheckCredentials( - fmt.Sprintf("username=%s,password=%s", userName, password), + ctx, fmt.Sprintf("username=%s,password=%s", userName, password), func() gopherpolicy.TokenResult { return tokens.Create(ctx, &throwAwayClient, &authOpts) }, ) diff --git a/internal/keppel/auditor.go b/internal/keppel/auditor.go index 6abade9b2..0f7952fc3 100644 --- a/internal/keppel/auditor.go +++ b/internal/keppel/auditor.go @@ -19,6 +19,7 @@ package keppel import ( + "context" "encoding/json" "net" "net/http" @@ -76,7 +77,7 @@ type auditorImpl struct { // InitAuditTrail initializes a Auditor from the configuration variables // found in the environment. -func InitAuditTrail() Auditor { +func InitAuditTrail(ctx context.Context) Auditor { logg.Debug("initializing audit trail...") prometheus.MustRegister(auditEventPublishSuccessCounter) @@ -110,7 +111,7 @@ func InitAuditTrail() Auditor { EventSink: eventSink, OnSuccessfulPublish: func() { auditEventPublishSuccessCounter.Inc() }, OnFailedPublish: func() { auditEventPublishFailedCounter.Inc() }, - }.Commit(rabbitURI, rabbitQueueName) + }.Commit(ctx, rabbitURI, rabbitQueueName) } return auditorImpl{ diff --git a/internal/test/setup.go b/internal/test/setup.go index 242ec684d..2ce3b51ea 100644 --- a/internal/test/setup.go +++ b/internal/test/setup.go @@ -360,7 +360,7 @@ func NewSetup(t *testing.T, opts ...SetupOption) Setup { quotasSetFor := make(map[string]bool) for _, account := range params.Accounts { mustDo(t, s.DB.Insert(account)) - fd.RecordExistingAccount(context.Background(), *account, s.Clock.Now()) //nolint:errcheck + fd.RecordExistingAccount(s.Ctx, *account, s.Clock.Now()) //nolint:errcheck if params.WithQuotas && !quotasSetFor[account.AuthTenantID] { mustDo(t, s.DB.Insert(&models.Quotas{ AuthTenantID: account.AuthTenantID, diff --git a/vendor/github.com/sapcc/go-bits/audittools/rabbitmq.go b/vendor/github.com/sapcc/go-bits/audittools/rabbitmq.go index 21fc31ea0..ec430e9ef 100644 --- a/vendor/github.com/sapcc/go-bits/audittools/rabbitmq.go +++ b/vendor/github.com/sapcc/go-bits/audittools/rabbitmq.go @@ -91,7 +91,7 @@ func (c *RabbitConnection) IsNilOrClosed() bool { // PublishEvent publishes a cadf.Event to a specific RabbitMQ Connection. // A nil pointer for event parameter will return an error. -func (c *RabbitConnection) PublishEvent(event *cadf.Event) error { +func (c *RabbitConnection) PublishEvent(ctx context.Context, event *cadf.Event) error { if c.IsNilOrClosed() { return amqp.ErrClosed } @@ -106,7 +106,7 @@ func (c *RabbitConnection) PublishEvent(event *cadf.Event) error { } return c.Channel.PublishWithContext( - context.Background(), + ctx, "", // exchange: publish to default c.QueueName, // routing key: same as queue name false, // mandatory: don't publish if no queue is bound that matches the routing key diff --git a/vendor/github.com/sapcc/go-bits/audittools/trail.go b/vendor/github.com/sapcc/go-bits/audittools/trail.go index 4de436992..b46c9448f 100644 --- a/vendor/github.com/sapcc/go-bits/audittools/trail.go +++ b/vendor/github.com/sapcc/go-bits/audittools/trail.go @@ -20,6 +20,7 @@ package audittools import ( + "context" "net/url" "time" @@ -40,7 +41,7 @@ type AuditTrail struct { // a specific RabbitMQ Connection using the specified amqp URI and queue name. // The OnSuccessfulPublish and OnFailedPublish closures are executed as per // their respective case. -func (t AuditTrail) Commit(rabbitmqURI url.URL, rabbitmqQueueName string) { +func (t AuditTrail) Commit(ctx context.Context, rabbitmqURI url.URL, rabbitmqQueueName string) { rc, err := NewRabbitConnection(rabbitmqURI, rabbitmqQueueName) if err != nil { logg.Error(err.Error()) @@ -48,7 +49,7 @@ func (t AuditTrail) Commit(rabbitmqURI url.URL, rabbitmqQueueName string) { sendEvent := func(e *cadf.Event) bool { rc = refreshConnectionIfClosedOrOld(rc, rabbitmqURI, rabbitmqQueueName) - err := rc.PublishEvent(e) + err := rc.PublishEvent(ctx, e) if err != nil { t.OnFailedPublish() logg.Error("audittools: failed to publish audit event with ID %q: %s", e.ID, err.Error()) diff --git a/vendor/github.com/sapcc/go-bits/gopherpolicy/cache.go b/vendor/github.com/sapcc/go-bits/gopherpolicy/cache.go index 279eccf58..f84df8c8b 100644 --- a/vendor/github.com/sapcc/go-bits/gopherpolicy/cache.go +++ b/vendor/github.com/sapcc/go-bits/gopherpolicy/cache.go @@ -19,6 +19,7 @@ package gopherpolicy import ( + "context" "crypto/sha256" "encoding/hex" @@ -40,11 +41,11 @@ func InMemoryCacher() Cacher { return inMemoryCacher{c} } -func (c inMemoryCacher) StoreTokenPayload(token string, payload []byte) { +func (c inMemoryCacher) StoreTokenPayload(_ context.Context, token string, payload []byte) { c.Add(cacheKeyFor(token), payload) } -func (c inMemoryCacher) LoadTokenPayload(token string) []byte { +func (c inMemoryCacher) LoadTokenPayload(_ context.Context, token string) []byte { payload, ok := c.Get(cacheKeyFor(token)) if !ok { return nil diff --git a/vendor/github.com/sapcc/go-bits/gopherpolicy/pkg.go b/vendor/github.com/sapcc/go-bits/gopherpolicy/pkg.go index abe7929c9..be3126fd8 100644 --- a/vendor/github.com/sapcc/go-bits/gopherpolicy/pkg.go +++ b/vendor/github.com/sapcc/go-bits/gopherpolicy/pkg.go @@ -22,6 +22,7 @@ package gopherpolicy import ( + "context" "encoding/json" "errors" "fmt" @@ -53,11 +54,11 @@ type Cacher interface { // StoreTokenPayload attempts to store the token payload corresponding to the // given credentials in the cache. Implementations shall treat `credentials` // as an opaque string and only use it as a cache key. - StoreTokenPayload(credentials string, payload []byte) + StoreTokenPayload(ctx context.Context, credentials string, payload []byte) // LoadTokenPayload attempts to retrieve the payload for the given credentials // from the cache. If there nothing cached for these credentials, or if the // retrieval fails, nil shall be returned. - LoadTokenPayload(credentials string) []byte + LoadTokenPayload(ctx context.Context, credentials string) []byte } // TokenValidator combines an Identity v3 client to validate tokens (AuthN), and @@ -97,7 +98,7 @@ func (v *TokenValidator) CheckToken(r *http.Request) *Token { return &Token{Err: errors.New("X-Auth-Token header missing")} } - token := v.CheckCredentials(tokenStr, func() TokenResult { + token := v.CheckCredentials(r.Context(), tokenStr, func() TokenResult { return tokens.Get(r.Context(), v.IdentityV3, tokenStr) }) token.Context.Logger = logg.Debug @@ -116,11 +117,11 @@ func (v *TokenValidator) CheckToken(r *http.Request) *Token { // The `cacheKey` argument shall be a string that identifies the given // credentials. This key is used for caching the TokenResult in `v.Cacher` if // that is non-nil. -func (v *TokenValidator) CheckCredentials(cacheKey string, check func() TokenResult) *Token { +func (v *TokenValidator) CheckCredentials(ctx context.Context, cacheKey string, check func() TokenResult) *Token { // prefer cached token payload over actually talking to Keystone (but fallback // to Keystone if the token payload deserialization fails) if v.Cacher != nil { - payload := v.Cacher.LoadTokenPayload(cacheKey) + payload := v.Cacher.LoadTokenPayload(ctx, cacheKey) if payload != nil { var s serializableToken err := json.Unmarshal(payload, &s) @@ -139,7 +140,7 @@ func (v *TokenValidator) CheckCredentials(cacheKey string, check func() TokenRes if t.Err == nil && v.Cacher != nil { payload, err := json.Marshal(t.serializable) if err == nil { - v.Cacher.StoreTokenPayload(cacheKey, payload) + v.Cacher.StoreTokenPayload(ctx, cacheKey, payload) } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 6682dbf61..2095a4c2e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -180,7 +180,7 @@ github.com/samber/lo ## explicit; go 1.21 github.com/sapcc/go-api-declarations/bininfo github.com/sapcc/go-api-declarations/cadf -# github.com/sapcc/go-bits v0.0.0-20240708133634-c3fa8372671d +# github.com/sapcc/go-bits v0.0.0-20240709125621-b1e90ef040ad ## explicit; go 1.22 github.com/sapcc/go-bits/assert github.com/sapcc/go-bits/audittools