Skip to content

Commit

Permalink
adding enforcement actions in log and events
Browse files Browse the repository at this point in the history
Signed-off-by: Jaydip Gabani <gabanijaydip@gmail.com>
  • Loading branch information
JaydipGabani committed Jul 25, 2024
1 parent 4fb224b commit 329b7e1
Show file tree
Hide file tree
Showing 17 changed files with 223 additions and 164 deletions.
3 changes: 2 additions & 1 deletion cmd/gator/test/gatortest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ func Test_formatOutput(t *testing.T) {
constraint:
object:
kind: kind
enforcementaction: []
enforcementaction: ""
scopedenforcementactions: []
violatingObject:
bar: xyz
trace: xyz
Expand Down
5 changes: 4 additions & 1 deletion cmd/gator/test/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,10 @@ func formatOutput(flagOutput string, results []*test.GatorResult, stats []*instr

func enforceableFailure(results []*test.GatorResult) bool {
for _, result := range results {
for _, action := range result.EnforcementAction {
if result.EnforcementAction == string(util.Deny) {
return true
}
for _, action := range result.ScopedEnforcementActions {
if action == string(util.Deny) {
return true
}
Expand Down
84 changes: 43 additions & 41 deletions pkg/audit/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,14 @@ type Manager struct {

// StatusViolation represents each violation under status.
type StatusViolation struct {
Group string `json:"group"`
Version string `json:"version"`
Kind string `json:"kind"`
Name string `json:"name"`
Namespace string `json:"namespace,omitempty"`
Message string `json:"message"`
EnforcementAction string `json:"enforcementAction"`
Group string `json:"group"`
Version string `json:"version"`
Kind string `json:"kind"`
Name string `json:"name"`
Namespace string `json:"namespace,omitempty"`
Message string `json:"message"`
EnforcementAction string `json:"enforcementAction"`
EnforcementActions []string `json:"enforcementActions,omitempty"`
}

// ConstraintMsg represents publish message for each constraint.
Expand All @@ -117,6 +118,7 @@ type PubsubMsg struct {
Namespace string `json:"namespace,omitempty"`
Message string `json:"message,omitempty"`
EnforcementAction string `json:"enforcementAction,omitempty"`
EnforcementActions []string `json:"enforcementActions,omitempty"`
ConstraintAnnotations map[string]string `json:"constraintAnnotations,omitempty"`
ResourceGroup string `json:"resourceGroup,omitempty"`
ResourceAPIVersion string `json:"resourceAPIVersion,omitempty"`
Expand Down Expand Up @@ -873,11 +875,8 @@ func (am *Manager) addAuditResponsesToUpdateLists(
}

totalViolationsPerConstraint[key]++

for _, action := range r.EnforcementAction {
ea := util.EnforcementAction(action)
totalViolationsPerEnforcementAction[ea]++
}
ea := util.EnforcementAction(r.EnforcementAction)
totalViolationsPerEnforcementAction[ea]++

gvk := r.obj.GroupVersionKind()
namespace := r.obj.GetNamespace()
Expand All @@ -886,33 +885,33 @@ func (am *Manager) addAuditResponsesToUpdateLists(
if len(msg) > msgSize {
msg = truncateString(msg, msgSize)
}
action := strings.Join(r.EnforcementAction, "/")
violation := &StatusViolation{
Group: gvk.Group,
Version: gvk.Version,
Kind: gvk.Kind,
Namespace: namespace,
Name: name,
Message: msg,
EnforcementAction: action,
Group: gvk.Group,
Version: gvk.Version,
Kind: gvk.Kind,
Namespace: namespace,
Name: name,
Message: msg,
EnforcementAction: r.EnforcementAction,
EnforcementActions: r.ScopedEnforcementActions,
}
// since keyQueue is a LimitQueue, it guarantees len <= limit after a push.
// the limit on size ensures Push() has O(1) time complexity.
keyQueue.Push(violation)

details := r.Metadata["details"]
labels := r.obj.GetLabels()
logViolation(am.log, constraint, action, gvk, namespace, name, msg, details, labels)
logViolation(am.log, constraint, ea, r.ScopedEnforcementActions, gvk, namespace, name, msg, details, labels)
if *pubsubController.PubsubEnabled {
err := am.pubsubSystem.Publish(context.Background(), *auditConnection, *auditChannel, violationMsg(constraint, action, gvk, namespace, name, msg, details, labels, timestamp))
err := am.pubsubSystem.Publish(context.Background(), *auditConnection, *auditChannel, violationMsg(constraint, ea, r.ScopedEnforcementActions, gvk, namespace, name, msg, details, labels, timestamp))
if err != nil {
am.log.Error(err, "pubsub audit Publishing")
}
}
if *emitAuditEvents {
uid := r.obj.GetUID()
rv := r.obj.GetResourceVersion()
emitEvent(constraint, timestamp, action, gvk, namespace, name, rv, msg, am.gkNamespace, uid, am.eventRecorder)
emitEvent(constraint, timestamp, ea, strings.Join(r.ScopedEnforcementActions, ","), gvk, namespace, name, rv, msg, am.gkNamespace, uid, am.eventRecorder)
}
}
}
Expand Down Expand Up @@ -1158,7 +1157,7 @@ func logConstraint(l logr.Logger, gvknn *util.KindVersionName, enforcementAction
)
}

func violationMsg(constraint *unstructured.Unstructured, enforcementAction string, resourceGroupVersionKind schema.GroupVersionKind, rnamespace, rname, message string, details interface{}, rlabels map[string]string, timestamp string) interface{} {
func violationMsg(constraint *unstructured.Unstructured, enforcementAction util.EnforcementAction, scopedEnforcementActions []string, resourceGroupVersionKind schema.GroupVersionKind, rnamespace, rname, message string, details interface{}, rlabels map[string]string, timestamp string) interface{} {
userConstraintAnnotations := constraint.GetAnnotations()
delete(userConstraintAnnotations, "kubectl.kubernetes.io/last-applied-configuration")

Expand All @@ -1172,7 +1171,8 @@ func violationMsg(constraint *unstructured.Unstructured, enforcementAction strin
Kind: constraint.GetKind(),
Name: constraint.GetName(),
Namespace: constraint.GetNamespace(),
EnforcementAction: enforcementAction,
EnforcementAction: string(enforcementAction),
EnforcementActions: scopedEnforcementActions,
ConstraintAnnotations: userConstraintAnnotations,
ResourceGroup: resourceGroupVersionKind.Group,
ResourceAPIVersion: resourceGroupVersionKind.Version,
Expand All @@ -1185,7 +1185,7 @@ func violationMsg(constraint *unstructured.Unstructured, enforcementAction strin

func logViolation(l logr.Logger,
constraint *unstructured.Unstructured,
enforcementAction string, resourceGroupVersionKind schema.GroupVersionKind, rnamespace, rname, message string, details interface{}, rlabels map[string]string,
enforcementAction util.EnforcementAction, scopedEnforcementActions []string, resourceGroupVersionKind schema.GroupVersionKind, rnamespace, rname, message string, details interface{}, rlabels map[string]string,
) {
userConstraintAnnotations := constraint.GetAnnotations()
delete(userConstraintAnnotations, "kubectl.kubernetes.io/last-applied-configuration")
Expand All @@ -1200,6 +1200,7 @@ func logViolation(l logr.Logger,
logging.ConstraintName, constraint.GetName(),
logging.ConstraintNamespace, constraint.GetNamespace(),
logging.ConstraintAction, enforcementAction,
logging.ConstraintEnforcementActions, scopedEnforcementActions,
logging.ConstraintAnnotations, userConstraintAnnotations,
logging.ResourceGroup, resourceGroupVersionKind.Group,
logging.ResourceAPIVersion, resourceGroupVersionKind.Version,
Expand All @@ -1211,24 +1212,25 @@ func logViolation(l logr.Logger,
}

func emitEvent(constraint *unstructured.Unstructured,
timestamp string, enforcementAction string, resourceGroupVersionKind schema.GroupVersionKind, rnamespace, rname, rrv, message, gkNamespace string, ruid types.UID,
timestamp string, enforcementAction util.EnforcementAction, scopedEnforcementActions string, resourceGroupVersionKind schema.GroupVersionKind, rnamespace, rname, rrv, message, gkNamespace string, ruid types.UID,
eventRecorder record.EventRecorder,
) {
annotations := map[string]string{
"process": "audit",
"auditTimestamp": timestamp,
logging.EventType: "violation_audited",
logging.ConstraintGroup: constraint.GroupVersionKind().Group,
logging.ConstraintAPIVersion: constraint.GroupVersionKind().Version,
logging.ConstraintKind: constraint.GetKind(),
logging.ConstraintName: constraint.GetName(),
logging.ConstraintNamespace: constraint.GetNamespace(),
logging.ConstraintAction: enforcementAction,
logging.ResourceGroup: resourceGroupVersionKind.Group,
logging.ResourceAPIVersion: resourceGroupVersionKind.Version,
logging.ResourceKind: resourceGroupVersionKind.Kind,
logging.ResourceNamespace: rnamespace,
logging.ResourceName: rname,
"process": "audit",
"auditTimestamp": timestamp,
logging.EventType: "violation_audited",
logging.ConstraintGroup: constraint.GroupVersionKind().Group,
logging.ConstraintAPIVersion: constraint.GroupVersionKind().Version,
logging.ConstraintKind: constraint.GetKind(),
logging.ConstraintName: constraint.GetName(),
logging.ConstraintNamespace: constraint.GetNamespace(),
logging.ConstraintAction: string(enforcementAction),
logging.ConstraintEnforcementActions: scopedEnforcementActions,
logging.ResourceGroup: resourceGroupVersionKind.Group,
logging.ResourceAPIVersion: resourceGroupVersionKind.Version,
logging.ResourceKind: resourceGroupVersionKind.Kind,
logging.ResourceNamespace: rnamespace,
logging.ResourceName: rname,
}

reason := "AuditViolation"
Expand Down
2 changes: 1 addition & 1 deletion pkg/audit/result_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func TestResult_ToResult(t *testing.T) {
aResult := types.Result{
Target: "targetA",
Msg: "violationA",
EnforcementAction: []string{"deny"},
EnforcementAction: "deny",
}

responses := types.Responses{
Expand Down
2 changes: 1 addition & 1 deletion pkg/expansion/aggregate.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func OverrideEnforcementAction(action string, resps *types.Responses) {

for _, resp := range resps.ByTarget {
for _, res := range resp.Results {
res.EnforcementAction = []string{action}
res.EnforcementAction = action
}
}
}
Expand Down
16 changes: 8 additions & 8 deletions pkg/expansion/aggregate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ func TestOverrideEnforcementAction(t *testing.T) {
{
Target: "targetA",
Msg: "violationA",
EnforcementAction: []string{"deny"},
EnforcementAction: "deny",
},
},
},
Expand All @@ -201,7 +201,7 @@ func TestOverrideEnforcementAction(t *testing.T) {
{
Target: "targetA",
Msg: "violationA",
EnforcementAction: []string{"deny"},
EnforcementAction: "deny",
},
},
},
Expand All @@ -219,7 +219,7 @@ func TestOverrideEnforcementAction(t *testing.T) {
{
Target: "targetA",
Msg: "violationA",
EnforcementAction: []string{"warn"},
EnforcementAction: "warn",
},
},
},
Expand All @@ -229,12 +229,12 @@ func TestOverrideEnforcementAction(t *testing.T) {
{
Target: "targetB",
Msg: "violationB",
EnforcementAction: []string{"warn"},
EnforcementAction: "warn",
},
{
Target: "targetB",
Msg: "violationC",
EnforcementAction: []string{"warn"},
EnforcementAction: "warn",
},
},
},
Expand All @@ -248,7 +248,7 @@ func TestOverrideEnforcementAction(t *testing.T) {
{
Target: "targetA",
Msg: "violationA",
EnforcementAction: []string{"deny"},
EnforcementAction: "deny",
},
},
},
Expand All @@ -258,12 +258,12 @@ func TestOverrideEnforcementAction(t *testing.T) {
{
Target: "targetB",
Msg: "violationB",
EnforcementAction: []string{"deny"},
EnforcementAction: "deny",
},
{
Target: "targetB",
Msg: "violationC",
EnforcementAction: []string{"deny"},
EnforcementAction: "deny",
},
},
},
Expand Down
27 changes: 15 additions & 12 deletions pkg/gator/test/test_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,26 +196,29 @@ func TestTest(t *testing.T) {
want: []*GatorResult{
{
Result: types.Result{
Target: target.Name,
Msg: "never validate",
Constraint: constraintGatorValidate,
EnforcementAction: []string{"deny", "warn"},
Target: target.Name,
Msg: "never validate",
Constraint: constraintGatorValidate,
EnforcementAction: "scoped",
ScopedEnforcementActions: []string{"deny", "warn"},
},
},
{
Result: types.Result{
Target: target.Name,
Msg: "never validate",
Constraint: constraintGatorValidate,
EnforcementAction: []string{"deny", "warn"},
Target: target.Name,
Msg: "never validate",
Constraint: constraintGatorValidate,
EnforcementAction: "scoped",
ScopedEnforcementActions: []string{"deny", "warn"},
},
},
{
Result: types.Result{
Target: target.Name,
Msg: "never validate",
Constraint: constraintGatorValidate,
EnforcementAction: []string{"deny", "warn"},
Target: target.Name,
Msg: "never validate",
Constraint: constraintGatorValidate,
EnforcementAction: "scoped",
ScopedEnforcementActions: []string{"deny", "warn"},
},
},
},
Expand Down
5 changes: 2 additions & 3 deletions pkg/gator/test/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package test

import (
"sort"
"strings"

"github.com/open-policy-agent/frameworks/constraint/pkg/instrumentation"
"github.com/open-policy-agent/frameworks/constraint/pkg/types"
Expand Down Expand Up @@ -67,8 +66,8 @@ func (r *GatorResponses) Results() []*GatorResult {
// responses to individual constraints. This is a stopgap to make tests easier
// to write until then.
sort.Slice(res, func(i, j int) bool {
if strings.Join(res[i].EnforcementAction, "/") != strings.Join(res[j].EnforcementAction, "/") {
return strings.Join(res[i].EnforcementAction, "/") < strings.Join(res[j].EnforcementAction, "/")
if res[i].EnforcementAction != res[j].EnforcementAction {
return res[i].EnforcementAction < res[j].EnforcementAction
}
return res[i].Msg < res[j].Msg
})
Expand Down
53 changes: 27 additions & 26 deletions pkg/logging/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,33 @@ import (

// Log keys.
const (
Process = "process"
Details = "details"
EventType = "event_type"
TemplateName = "template_name"
ConstraintNamespace = "constraint_namespace"
ConstraintName = "constraint_name"
ConstraintGroup = "constraint_group"
ConstraintKind = "constraint_kind"
ConstraintAPIVersion = "constraint_api_version"
ConstraintStatus = "constraint_status"
ConstraintAction = "constraint_action"
ConstraintAnnotations = "constraint_annotations"
AuditID = "audit_id"
ConstraintViolations = "constraint_violations"
ResourceGroup = "resource_group"
ResourceKind = "resource_kind"
ResourceLabels = "resource_labels"
ResourceAPIVersion = "resource_api_version"
ResourceNamespace = "resource_namespace"
ResourceName = "resource_name"
ResourceSourceType = "resource_source_type"
RequestUsername = "request_username"
MutationApplied = "mutation_applied"
Mutator = "mutator"
DebugLevel = 1 // r.log.Debug(foo) == r.log.V(logging.DebugLevel).Info(foo)
ExecutionStats = "execution_stats"
Process = "process"
Details = "details"
EventType = "event_type"
TemplateName = "template_name"
ConstraintNamespace = "constraint_namespace"
ConstraintName = "constraint_name"
ConstraintGroup = "constraint_group"
ConstraintKind = "constraint_kind"
ConstraintAPIVersion = "constraint_api_version"
ConstraintStatus = "constraint_status"
ConstraintAction = "constraint_action"
ConstraintEnforcementActions = "constraint_enforcement_actions"
ConstraintAnnotations = "constraint_annotations"
AuditID = "audit_id"
ConstraintViolations = "constraint_violations"
ResourceGroup = "resource_group"
ResourceKind = "resource_kind"
ResourceLabels = "resource_labels"
ResourceAPIVersion = "resource_api_version"
ResourceNamespace = "resource_namespace"
ResourceName = "resource_name"
ResourceSourceType = "resource_source_type"
RequestUsername = "request_username"
MutationApplied = "mutation_applied"
Mutator = "mutator"
DebugLevel = 1 // r.log.Debug(foo) == r.log.V(logging.DebugLevel).Info(foo)
ExecutionStats = "execution_stats"
)

func LogStatsEntries(client *constraintclient.Client, logger logr.Logger, entries []*instrumentation.StatsEntry, msg string) {
Expand Down
Loading

0 comments on commit 329b7e1

Please sign in to comment.