Skip to content
This repository has been archived by the owner on Mar 16, 2024. It is now read-only.

Commit

Permalink
Rename event source to "resource"
Browse files Browse the repository at this point in the history
Replace required event source field with a new optional "resource" field.

Signed-off-by: Nick Hale <4175918+njhale@users.noreply.github.com>
  • Loading branch information
njhale committed Jul 17, 2023
1 parent fe9549a commit 1c8849a
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 48 deletions.
2 changes: 1 addition & 1 deletion integration/events/events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func TestAppEvents(t *testing.T) {
// Ensure an event of each type has been recorded
var created, updated, deleted bool
helper.Wait(t, helper.Watcher(t, c), &apiv1.EventList{}, func(obj *apiv1.Event) bool {
if obj.Namespace != project.Name || obj.Source.Kind != "app" || obj.Source.Name != app.Name {
if obj.Namespace != project.Name || obj.Resource.Kind != "app" || obj.Resource.Name != app.Name {
// This event isn't for our app
return false
}
Expand Down
31 changes: 20 additions & 11 deletions pkg/apis/internal.acorn.io/v1/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package v1
import (
"encoding/json"
"errors"
"fmt"
"strings"
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -40,8 +40,9 @@ type EventInstance struct {
// +optional
AppName string `json:"appName,omitempty"`

// Source identifies the object the Event is regarding.
Source EventSource `json:"source"`
// Resource identifies the object the Event is regarding.
// +optional
Resource *EventResource `json:"resource,omitempty"`

// Description is a human-readable description of the Event.
// +optional
Expand Down Expand Up @@ -120,24 +121,32 @@ const (
// EventSeverity indicates the severity of an event.
type EventSeverity string

// EventSource identifies an object related to an Event.
// EventResource identifies a resource related to an Event.
//
// The referenced object may or may not exist.
// The referenced resource may or may not exist.
//
// Note: corev1.ObjectReference was explicitly avoided because its use in new schemas is discouraged.
// See https://github.com/kubernetes/api/blob/cdff1d4efea5d7ddc52c4085f82748c5f3e5cc8e/core/v1/types.go#L5919
// for more details.
type EventSource struct {
// Kind is the source object kind.
type EventResource struct {
// Kind is the resource kind.
Kind string `json:"kind"`

// Name is the name of the source object.
// Name is the name of the resource.
Name string `json:"name"`

// UID uniquely identifies the source object.
// UID uniquely identifies the resource.
UID types.UID `json:"uuid"`
}

func (e EventSource) String() string {
return fmt.Sprintf("%s/%s", e.Kind, e.Name)
func (e EventResource) String() string {
components := make([]string, 0, 2)
if e.Kind != "" {
components = append(components, e.Kind)
}
if e.Name != "" {
components = append(components, e.Name)
}

return strings.Join(components, "/")
}
18 changes: 13 additions & 5 deletions pkg/cli/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,13 +382,20 @@ func eventsCompletion(ctx context.Context, c client.Client, toComplete string) (

matched := make(map[string]struct{})
if err := channels.ForEach(ctx, events, func(e apiv1.Event) error {
for _, completion := range []string{
completions := []string{
// Name prefix completion
e.Name,
// Source prefix completion
e.Source.String(),
e.Source.Kind,
} {
}

if e.Resource != nil {
// Resource prefix completions
completions = append(completions,
e.Resource.String(),
e.Resource.Kind,
)
}

for _, completion := range completions {
if _, ok := matched[completion]; ok {
// Completion already added to results
return nil
Expand All @@ -399,6 +406,7 @@ func eventsCompletion(ctx context.Context, c client.Client, toComplete string) (
matched[completion] = struct{}{}
}
}

return nil
}); !channels.NilOrCanceled(err) {
return nil, err
Expand Down
8 changes: 4 additions & 4 deletions pkg/cli/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ func NewEvent(c CommandContext) *cobra.Command {
# List the last 5 events and follow the event log
acorn events --tail 5 -f
# Filter by Event Source
# Filter by Related Resource
# If a PREFIX is given in the form '<kind>/<name>', the results of this command are pruned to include
# only those events sourced by resources matching the given kind and name.
# List events sourced by the 'hello' app in the current project
# only those events related to resources matching the given kind and name.
# List events related to the 'hello' app in the current project
acorn events app/hello
# If the '/<name>' suffix is omitted, '<kind>' will match events sourced by any resource of the given kind.
# If the '/<name>' suffix is omitted, '<kind>' will match events related to any resource of the given kind.
# List events related to any app in the current project
acorn events app
Expand Down
2 changes: 1 addition & 1 deletion pkg/controller/appdefinition/pullappimage.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ func recordPullEvent(ctx context.Context, recorder event.Recorder, observed meta
Severity: v1.EventSeverityInfo,
Description: fmt.Sprintf("Pulled %s", target.Name),
AppName: obj.GetName(),
Source: event.ObjectSource(obj),
Resource: event.Resource(obj),
Observed: v1.MicroTime(observed),
}
e.SetNamespace(obj.GetNamespace())
Expand Down
10 changes: 5 additions & 5 deletions pkg/controller/appdefinition/pullappimage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func withMeta[T kclient.Object](name, uid, resourceVersion string, obj T) T {

func TestPullAppImageEvents(t *testing.T) {
// Test cases below this comment ensure the handler produces the correct events
now := v1.MicroTime(metav1.NowMicro())
now := v1.NowMicro()
// Manual upgrade should record an event
testRecordPullEvent(t,
"ImageChange",
Expand All @@ -108,7 +108,7 @@ func TestPullAppImageEvents(t *testing.T) {
Severity: v1.EventSeverityInfo,
Description: "Pulled acorn.io/img:1",
AppName: "foo",
Source: v1.EventSource{Kind: "app", Name: "foo", UID: types.UID("foo-uid")},
Resource: &v1.EventResource{Kind: "app", Name: "foo", UID: types.UID("foo-uid")},
Observed: now,
Details: mustMapify(t, AppImagePullEventDetails{
ResourceVersion: "1",
Expand All @@ -131,7 +131,7 @@ func TestPullAppImageEvents(t *testing.T) {
Severity: v1.EventSeverityInfo,
Description: "Pulled acorn.io/img:1",
AppName: "foo",
Source: v1.EventSource{Kind: "app", Name: "foo"},
Resource: &v1.EventResource{Kind: "app", Name: "foo"},
Observed: now,
Details: mustMapify(t, AppImagePullEventDetails{
AutoUpgrade: true,
Expand All @@ -152,7 +152,7 @@ func TestPullAppImageEvents(t *testing.T) {
Severity: v1.EventSeverityInfo,
Description: "Pulled acorn.io/img:1",
AppName: "foo",
Source: v1.EventSource{Kind: "app", Name: "foo"},
Resource: &v1.EventResource{Kind: "app", Name: "foo"},
Observed: now,
Details: mustMapify(t, AppImagePullEventDetails{
AutoUpgrade: true,
Expand All @@ -173,7 +173,7 @@ func TestPullAppImageEvents(t *testing.T) {
Severity: v1.EventSeverityError,
Description: "Failed to pull acorn.io/img:1",
AppName: "foo",
Source: v1.EventSource{Kind: "app", Name: "foo"},
Resource: &v1.EventResource{Kind: "app", Name: "foo"},
Observed: now,
Details: mustMapify(t, AppImagePullEventDetails{
Target: ImageSummary{Name: "acorn.io/img:1"},
Expand Down
19 changes: 9 additions & 10 deletions pkg/event/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import (
"fmt"

apiv1 "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1"
v1 "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1"
internalv1 "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1"
"github.com/acorn-io/z"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/endpoints/request"
kclient "sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -46,13 +47,10 @@ var (
)

func init() {
must := func(err error) {
if err != nil {
panic(fmt.Sprintf("failed to add to scheme: %s", err.Error()))
}
}
must(apiv1.AddToScheme(scheme))
must(v1.AddToScheme(scheme))
z.Must(
apiv1.AddToScheme(scheme),
internalv1.AddToScheme(scheme),
)
}

func publicKind(obj runtime.Object) string {
Expand All @@ -66,8 +64,9 @@ func publicKind(obj runtime.Object) string {
return ""
}

func ObjectSource(obj kclient.Object) v1.EventSource {
return v1.EventSource{
// Resource returns a non-nil pointer to a v1.EventResource for the given object.
func Resource(obj kclient.Object) *internalv1.EventResource {
return &internalv1.EventResource{
Kind: publicKind(obj),
Name: obj.GetName(),
UID: obj.GetUID(),
Expand Down
9 changes: 5 additions & 4 deletions pkg/event/id.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,22 @@ import (
"strings"

apiv1 "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1"
"github.com/acorn-io/z"
)

// ContentID returns a deterministic ID based on the content of a given event.
// The returned ID is a valid kubernetes resource name (metadata.name).
func ContentID(e *apiv1.Event) (string, error) {
fieldSet := strings.Join([]string{
fieldSet := []string{
e.Type,
string(e.Severity),
e.Source.String(),
z.Dereference(e.Resource).String(),
e.Description,
strconv.FormatInt(e.Observed.UnixMicro(), 10),
}, ",")
}

h := fnv.New128a()
if _, err := h.Write([]byte(fieldSet)); err != nil {
if _, err := h.Write([]byte(strings.Join(fieldSet, ","))); err != nil {
return "", err
}

Expand Down
12 changes: 6 additions & 6 deletions pkg/server/registry/apigroups/acorn/apps/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ func (s *eventRecordingStrategy) Create(ctx context.Context, obj types.Object) (
Details: details,
Description: fmt.Sprintf("App %s/%s created", obj.GetNamespace(), obj.GetName()),
AppName: obj.GetName(),
Source: event.ObjectSource(obj),
Observed: v1.MicroTime(metav1.NowMicro()),
Resource: event.Resource(obj),
Observed: v1.NowMicro(),
}); err != nil {
logrus.Warnf("Failed to record event: %s", err.Error())
}
Expand Down Expand Up @@ -117,8 +117,8 @@ func (s *eventRecordingStrategy) Delete(ctx context.Context, obj types.Object) (
Details: details,
Description: fmt.Sprintf("App %s/%s deleted", obj.GetNamespace(), obj.GetName()),
AppName: obj.GetName(),
Source: event.ObjectSource(obj),
Observed: v1.MicroTime(metav1.NowMicro()),
Resource: event.Resource(obj),
Observed: v1.NowMicro(),
}); err != nil {
logrus.Warnf("Failed to record event: %s", err.Error())
}
Expand Down Expand Up @@ -172,8 +172,8 @@ func (s *eventRecordingStrategy) Update(ctx context.Context, obj types.Object) (
Details: details,
Description: fmt.Sprintf("Spec field updated for App %s/%s", obj.GetNamespace(), obj.GetName()),
AppName: obj.GetName(),
Source: event.ObjectSource(obj),
Observed: v1.MicroTime(metav1.NowMicro()),
Resource: event.Resource(obj),
Observed: v1.NowMicro(),
}); err != nil {
logrus.Warnf("Failed to record event: %s", err)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/server/registry/apigroups/acorn/events/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ type prefix string
func (p prefix) matches(e apiv1.Event) bool {
return p.all() ||
strings.HasPrefix(e.Name, string(p)) ||
strings.HasPrefix(e.Source.String(), string(p))
strings.HasPrefix(z.Dereference(e.Resource).String(), string(p))
}

func (p prefix) all() bool {
Expand Down

0 comments on commit 1c8849a

Please sign in to comment.