-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Justin Kulikauskas <[email protected]>
- Loading branch information
1 parent
343128b
commit af50a33
Showing
9 changed files
with
439 additions
and
11 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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,110 @@ | ||
// Copyright Contributors to the Open Cluster Management project | ||
|
||
package compliance | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"time" | ||
|
||
corev1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
|
||
nucleusv1beta1 "open-cluster-management.io/governance-policy-nucleus/api/v1beta1" | ||
) | ||
|
||
// Can't be an interface because then Emit couldn't be a method | ||
type K8sEmitter struct { | ||
Client client.Client // TODO: required | ||
Source corev1.EventSource // TODO: optional? | ||
|
||
// TODO: debatable for inclusion; allows tweaks of the event like adding/removing labels | ||
// if not included, we could skip creating the event, just build it for the user to send | ||
// but if it is included, we can build bigger things on top of this, and still have extensibility | ||
Mutators []func(corev1.Event) (corev1.Event, error) | ||
} | ||
|
||
// TODO: maybe this would be a good interface for multiple emitters? | ||
func (e K8sEmitter) Emit(ctx context.Context, pl nucleusv1beta1.PolicyLike) error { | ||
_, err := e.EmitEvent(ctx, pl) | ||
|
||
return err | ||
} | ||
|
||
func (e K8sEmitter) EmitEvent(ctx context.Context, pl nucleusv1beta1.PolicyLike) (*corev1.Event, error) { | ||
plGVK := pl.GetObjectKind().GroupVersionKind() | ||
time := time.Now() | ||
|
||
// This event name matches the convention of recorders from client-go | ||
name := fmt.Sprintf("%v.%x", pl.Parent().Name, time.UnixNano()) | ||
|
||
// The reason must match a pattern looked for by the policy framework | ||
var reason string | ||
if ns := pl.GetNamespace(); ns != "" { | ||
reason = "policy: " + ns + "/" + pl.GetName() | ||
} else { | ||
reason = "policy: " + pl.GetName() | ||
} | ||
|
||
// The message must begin with the compliance, then should go into a descriptive message | ||
message := string(pl.ComplianceState()) + "; " + pl.ComplianceMessage() | ||
|
||
evType := "Normal" | ||
if pl.ComplianceState() != nucleusv1beta1.Compliant { | ||
evType = "Warning" | ||
} | ||
|
||
event := corev1.Event{ | ||
TypeMeta: metav1.TypeMeta{ | ||
Kind: "Event", | ||
APIVersion: "v1", | ||
}, | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: name, | ||
Namespace: pl.ParentNamespace(), | ||
Labels: pl.GetLabels(), | ||
Annotations: pl.GetAnnotations(), | ||
}, | ||
InvolvedObject: corev1.ObjectReference{ | ||
Kind: pl.Parent().Kind, | ||
Namespace: pl.ParentNamespace(), | ||
Name: pl.Parent().Name, | ||
UID: pl.Parent().UID, | ||
APIVersion: pl.Parent().APIVersion, | ||
}, | ||
Reason: reason, | ||
Message: message, | ||
Source: e.Source, | ||
FirstTimestamp: metav1.NewTime(time), | ||
LastTimestamp: metav1.NewTime(time), | ||
Count: 1, | ||
Type: evType, | ||
EventTime: metav1.NewMicroTime(time), // does this break anything? | ||
Series: nil, | ||
Action: "ComplianceStateUpdate", | ||
Related: &corev1.ObjectReference{ | ||
Kind: plGVK.Kind, | ||
Namespace: pl.GetNamespace(), | ||
Name: pl.GetName(), | ||
UID: pl.GetUID(), | ||
APIVersion: plGVK.GroupVersion().String(), | ||
ResourceVersion: pl.GetResourceVersion(), | ||
}, | ||
ReportingController: e.Source.Component, | ||
ReportingInstance: e.Source.Host, | ||
} | ||
|
||
for _, mutatorFunc := range e.Mutators { | ||
var err error | ||
|
||
event, err = mutatorFunc(event) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
err := e.Client.Create(ctx, &event) | ||
|
||
return &event, err | ||
} |
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Oops, something went wrong.