-
Notifications
You must be signed in to change notification settings - Fork 118
Batch events #175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Batch events #175
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
4545876
Batch events
pleshakov e945ecf
Simplify the implementation
pleshakov ab9c45d
Improved logging
pleshakov eb86d34
Add FIXME
pleshakov 9501170
Update FIXME
pleshakov 9c2fd6a
Merge branch 'main' into feature/batch-events
pleshakov File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
package events | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/go-logr/logr" | ||
apiv1 "k8s.io/api/core/v1" | ||
"sigs.k8s.io/gateway-api/apis/v1beta1" | ||
|
||
"github.com/nginxinc/nginx-kubernetes-gateway/internal/nginx/config" | ||
"github.com/nginxinc/nginx-kubernetes-gateway/internal/nginx/file" | ||
"github.com/nginxinc/nginx-kubernetes-gateway/internal/nginx/runtime" | ||
"github.com/nginxinc/nginx-kubernetes-gateway/internal/state" | ||
"github.com/nginxinc/nginx-kubernetes-gateway/internal/status" | ||
) | ||
|
||
//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . EventHandler | ||
|
||
// EventHandler handle events. | ||
type EventHandler interface { | ||
// HandleEventBatch handles a batch of events. | ||
HandleEventBatch(ctx context.Context, batch EventBatch) | ||
} | ||
|
||
// EventHandlerConfig holds configuration parameters for EventHandlerImpl. | ||
type EventHandlerConfig struct { | ||
// Processor is the state ChangeProcessor. | ||
Processor state.ChangeProcessor | ||
// ServiceStore is the state ServiceStore. | ||
ServiceStore state.ServiceStore | ||
// SecretStore is the state SecretStore. | ||
SecretStore state.SecretStore | ||
// SecretMemoryManager is the state SecretMemoryManager. | ||
SecretMemoryManager state.SecretDiskMemoryManager | ||
// Generator is the nginx config Generator. | ||
Generator config.Generator | ||
// Logger is the logger to be used by the EventHandler. | ||
Logger logr.Logger | ||
// NginxFileMgr is the file Manager for nginx. | ||
NginxFileMgr file.Manager | ||
// NginxRuntimeMgr manages nginx runtime. | ||
NginxRuntimeMgr runtime.Manager | ||
// StatusUpdater updates statuses on Kubernetes resources. | ||
StatusUpdater status.Updater | ||
} | ||
|
||
// EventHandlerImpl implements EventHandler. | ||
// EventHandlerImpl is responsible for: | ||
// (1) Reconciling the Gateway API and Kubernetes built-in resources with the NGINX configuration. | ||
// (2) Keeping the statuses of the Gateway API resources updated. | ||
type EventHandlerImpl struct { | ||
cfg EventHandlerConfig | ||
} | ||
|
||
// NewEventHandlerImpl creates a new EventHandlerImpl. | ||
func NewEventHandlerImpl(cfg EventHandlerConfig) *EventHandlerImpl { | ||
return &EventHandlerImpl{ | ||
cfg: cfg, | ||
} | ||
} | ||
|
||
func (h *EventHandlerImpl) HandleEventBatch(ctx context.Context, batch EventBatch) { | ||
|
||
for _, event := range batch { | ||
switch e := event.(type) { | ||
case *UpsertEvent: | ||
h.propagateUpsert(e) | ||
case *DeleteEvent: | ||
h.propagateDelete(e) | ||
default: | ||
panic(fmt.Errorf("unknown event type %T", e)) | ||
} | ||
} | ||
|
||
changed, conf, statuses := h.cfg.Processor.Process() | ||
if !changed { | ||
h.cfg.Logger.Info("Handling events didn't result into NGINX configuration changes") | ||
return | ||
} | ||
|
||
err := h.updateNginx(ctx, conf) | ||
if err != nil { | ||
h.cfg.Logger.Error(err, "Failed to update NGINX configuration") | ||
} else { | ||
h.cfg.Logger.Info("NGINX configuration was successfully updated") | ||
} | ||
|
||
h.cfg.StatusUpdater.Update(ctx, statuses) | ||
} | ||
|
||
func (h *EventHandlerImpl) updateNginx(ctx context.Context, conf state.Configuration) error { | ||
// Write all secrets (nuke and pave). | ||
// This will remove all secrets in the secrets directory before writing the requested secrets. | ||
// FIXME(kate-osborn): We may want to rethink this approach in the future and write and remove secrets individually. | ||
err := h.cfg.SecretMemoryManager.WriteAllRequestedSecrets() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
cfg, warnings := h.cfg.Generator.Generate(conf) | ||
|
||
// For now, we keep all http servers in one config | ||
// We might rethink that. For example, we can write each server to its file | ||
// or group servers in some way. | ||
err = h.cfg.NginxFileMgr.WriteHTTPServersConfig("http-servers", cfg) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
for obj, objWarnings := range warnings { | ||
for _, w := range objWarnings { | ||
// FIXME(pleshakov): report warnings via Object status | ||
h.cfg.Logger.Info("Got warning while generating config", | ||
"kind", obj.GetObjectKind().GroupVersionKind().Kind, | ||
"namespace", obj.GetNamespace(), | ||
"name", obj.GetName(), | ||
"warning", w) | ||
} | ||
} | ||
|
||
return h.cfg.NginxRuntimeMgr.Reload(ctx) | ||
} | ||
|
||
func (h *EventHandlerImpl) propagateUpsert(e *UpsertEvent) { | ||
switch r := e.Resource.(type) { | ||
case *v1beta1.GatewayClass: | ||
h.cfg.Processor.CaptureUpsertChange(r) | ||
case *v1beta1.Gateway: | ||
h.cfg.Processor.CaptureUpsertChange(r) | ||
case *v1beta1.HTTPRoute: | ||
h.cfg.Processor.CaptureUpsertChange(r) | ||
case *apiv1.Service: | ||
// FIXME(pleshakov): make sure the affected hosts are updated | ||
h.cfg.ServiceStore.Upsert(r) | ||
case *apiv1.Secret: | ||
// FIXME(kate-osborn): need to handle certificate rotation | ||
h.cfg.SecretStore.Upsert(r) | ||
default: | ||
panic(fmt.Errorf("unknown resource type %T", e.Resource)) | ||
} | ||
} | ||
|
||
func (h *EventHandlerImpl) propagateDelete(e *DeleteEvent) { | ||
switch e.Type.(type) { | ||
case *v1beta1.GatewayClass: | ||
h.cfg.Processor.CaptureDeleteChange(e.Type, e.NamespacedName) | ||
case *v1beta1.Gateway: | ||
h.cfg.Processor.CaptureDeleteChange(e.Type, e.NamespacedName) | ||
case *v1beta1.HTTPRoute: | ||
h.cfg.Processor.CaptureDeleteChange(e.Type, e.NamespacedName) | ||
case *apiv1.Service: | ||
// FIXME(pleshakov): make sure the affected hosts are updated | ||
h.cfg.ServiceStore.Delete(e.NamespacedName) | ||
case *apiv1.Secret: | ||
// FIXME(kate-osborn): make sure that affected servers are updated | ||
h.cfg.SecretStore.Delete(e.NamespacedName) | ||
default: | ||
panic(fmt.Errorf("unknown resource type %T", e.Type)) | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.