Skip to content
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

Mirror from OCM around 56 #80

Merged
merged 7 commits into from
Apr 21, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion controllers/gatekeepersync/gatekeeper_constraint_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,9 @@ func (r *GatekeeperConstraintReconciler) sendComplianceEvent(
return nil
}

err := r.SendEvent(ctx, constraint, owner, msg, compliance)
reason := utils.EventReason(constraint.GetNamespace(), constraint.GetName())

err := r.SendEvent(ctx, constraint, owner, reason, msg, compliance)
if err != nil {
return err
}
Expand Down
145 changes: 110 additions & 35 deletions controllers/templatesync/template_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ type PolicyReconciler struct {
Config *rest.Config
Recorder record.EventRecorder
ClusterNamespace string
Clientset *kubernetes.Clientset
InstanceName string
DisableGkSync bool
createdGkConstraint *bool
}
Expand Down Expand Up @@ -135,8 +137,7 @@ func (r *PolicyReconciler) Reconcile(ctx context.Context, request reconcile.Requ
var dClient dynamic.Interface

if len(instance.Spec.PolicyTemplates) > 0 {
clientset := kubernetes.NewForConfigOrDie(r.Config)
discoveryClient = clientset.Discovery()
discoveryClient = r.Clientset.Discovery()

// initialize dynamic client
dClient, err = dynamic.NewForConfig(r.Config)
Expand Down Expand Up @@ -262,7 +263,8 @@ func (r *PolicyReconciler) Reconcile(ctx context.Context, request reconcile.Requ
resultError = err
errMsg := fmt.Sprintf("Failed to decode policy template with err: %s", err)

r.emitTemplateError(instance, tIndex, fmt.Sprintf("[template %v]", tIndex), false, errMsg)
//nolint:errcheck // it will already be requeued for the resultError.
r.emitTemplateError(ctx, instance, tIndex, fmt.Sprintf("[template %v]", tIndex), false, errMsg)
reqLogger.Error(resultError, "Failed to decode the policy template", "templateIndex", tIndex)

policyUserErrorsCounter.WithLabelValues(instance.Name, "", "format-error").Inc()
Expand Down Expand Up @@ -310,7 +312,9 @@ func (r *PolicyReconciler) Reconcile(ctx context.Context, request reconcile.Requ
resultError = fmt.Errorf("dependency on %s has conflicting compliance states", dep.Name)
errMsg := fmt.Sprintf("Failed to decode policy template with err: %s", resultError)

r.emitTemplateError(instance, tIndex, fmt.Sprintf("[template %v]", tIndex), isClusterScoped, errMsg)
//nolint:errcheck // it will already be requeued for the resultError.
r.emitTemplateError(ctx, instance, tIndex,
fmt.Sprintf("[template %v]", tIndex), isClusterScoped, errMsg)
reqLogger.Error(resultError, "Failed to decode the policy template", "templateIndex", tIndex)

depConflictErr = true
Expand Down Expand Up @@ -338,7 +342,8 @@ func (r *PolicyReconciler) Reconcile(ctx context.Context, request reconcile.Requ
errMsg := fmt.Sprintf("Failed to get name from policy template at index %v", tIndex)
resultError = k8serrors.NewBadRequest(errMsg)

r.emitTemplateError(instance, tIndex, fmt.Sprintf("[template %v]", tIndex), isClusterScoped, errMsg)
//nolint:errcheck // it will already be requeued for the resultError.
r.emitTemplateError(ctx, instance, tIndex, fmt.Sprintf("[template %v]", tIndex), isClusterScoped, errMsg)
reqLogger.Error(resultError, "Failed to process the policy template", "templateIndex", tIndex)

policyUserErrorsCounter.WithLabelValues(instance.Name, "", "format-error").Inc()
Expand Down Expand Up @@ -367,7 +372,8 @@ func (r *PolicyReconciler) Reconcile(ctx context.Context, request reconcile.Requ

errMsg += fmt.Sprintf(": %s", err)

r.emitTemplateError(instance, tIndex, tName, isClusterScoped, errMsg)
//nolint:errcheck // it will already be requeued for the resultError.
r.emitTemplateError(ctx, instance, tIndex, tName, isClusterScoped, errMsg)
tLogger.Error(err, "Could not find an API mapping for the object definition",
"group", gvk.Group,
"version", gvk.Version,
Expand Down Expand Up @@ -415,7 +421,8 @@ func (r *PolicyReconciler) Reconcile(ctx context.Context, request reconcile.Requ

resultError = err

r.emitTemplateError(instance, tIndex, tName, isClusterScoped, errMsg)
//nolint:errcheck // it will already be requeued for the resultError.
r.emitTemplateError(ctx, instance, tIndex, tName, isClusterScoped, errMsg)
tLogger.Error(err, "Unsupported policy-template kind found in object definition",
"group", gvk.Group,
"version", gvk.Version,
Expand All @@ -435,7 +442,8 @@ func (r *PolicyReconciler) Reconcile(ctx context.Context, request reconcile.Requ
errMsg := fmt.Sprintf("Templates are not supported for kind : %s", gvk.Kind)
resultError = k8serrors.NewBadRequest(errMsg)

r.emitTemplateError(instance, tIndex, tName, isClusterScoped, errMsg)
//nolint:errcheck // it will already be requeued for the resultError.
r.emitTemplateError(ctx, instance, tIndex, tName, isClusterScoped, errMsg)
tLogger.Error(resultError, "Failed to process the policy template")

policyUserErrorsCounter.WithLabelValues(instance.Name, tName, "format-error").Inc()
Expand Down Expand Up @@ -464,7 +472,8 @@ func (r *PolicyReconciler) Reconcile(ctx context.Context, request reconcile.Requ
resultError = err
errMsg := fmt.Sprintf("Failed to unmarshal the policy template: %s", err)

r.emitTemplateError(instance, tIndex, tName, isClusterScoped, errMsg)
//nolint:errcheck // it will already be requeued for the resultError.
r.emitTemplateError(ctx, instance, tIndex, tName, isClusterScoped, errMsg)
tLogger.Error(resultError, "Failed to unmarshal the policy template")

policySystemErrorsCounter.WithLabelValues(instance.Name, tName, "unmarshal-error").Inc()
Expand All @@ -486,7 +495,14 @@ func (r *PolicyReconciler) Reconcile(ctx context.Context, request reconcile.Requ
if err != nil {
if len(dependencyFailures) > 0 {
// template must be pending, do not create it
r.emitTemplatePending(instance, tIndex, tName, isClusterScoped, generatePendingMsg(dependencyFailures))
emitErr := r.emitTemplatePending(ctx, instance, tIndex, tName, isClusterScoped,
generatePendingMsg(dependencyFailures))
if emitErr != nil {
resultError = emitErr

continue
}

tLogger.Info("Dependencies were not satisfied for the policy template",
"namespace", instance.GetNamespace(),
"kind", gvk.Kind,
Expand Down Expand Up @@ -530,7 +546,8 @@ func (r *PolicyReconciler) Reconcile(ctx context.Context, request reconcile.Requ
resultError = err
errMsg := fmt.Sprintf("Failed to create policy template: %s", err)

r.emitTemplateError(instance, tIndex, tName, isClusterScoped, errMsg)
//nolint:errcheck // it will already be requeued for the resultError.
r.emitTemplateError(ctx, instance, tIndex, tName, isClusterScoped, errMsg)
tLogger.Error(resultError, "Failed to create policy template")

policySystemErrorsCounter.WithLabelValues(instance.Name, tName, "create-error").Inc()
Expand All @@ -555,7 +572,11 @@ func (r *PolicyReconciler) Reconcile(ctx context.Context, request reconcile.Requ
if isGkConstraintTemplate {
tLogger.Info("Emitting status event for " + gvk.Kind)
msg := fmt.Sprintf("%s %s was created successfully", gvk.Kind, tName)
r.emitTemplateSuccess(instance, tIndex, tName, isClusterScoped, msg)

emitErr := r.emitTemplateSuccess(ctx, instance, tIndex, tName, isClusterScoped, msg)
if emitErr != nil {
resultError = emitErr
}
}
}

Expand All @@ -574,7 +595,8 @@ func (r *PolicyReconciler) Reconcile(ctx context.Context, request reconcile.Requ
resultError = err
errMsg := fmt.Sprintf("Failed to get the object in the policy template: %s", err)

r.emitTemplateError(instance, tIndex, tName, isClusterScoped, errMsg)
//nolint:errcheck // it will already be requeued for the resultError.
r.emitTemplateError(ctx, instance, tIndex, tName, isClusterScoped, errMsg)
tLogger.Error(err, "Failed to get the object in the policy template",
"namespace", instance.GetNamespace(),
"kind", gvk.Kind,
Expand All @@ -588,12 +610,17 @@ func (r *PolicyReconciler) Reconcile(ctx context.Context, request reconcile.Requ

if len(dependencyFailures) > 0 {
// template must be pending, need to delete it and error
r.emitTemplatePending(instance, tIndex, tName, isClusterScoped, generatePendingMsg(dependencyFailures))
tLogger.Info("Dependencies were not satisfied for the policy template",
"namespace", instance.GetNamespace(),
"kind", gvk.Kind,
)

emitErr := r.emitTemplatePending(ctx, instance, tIndex, tName,
isClusterScoped, generatePendingMsg(dependencyFailures))
if emitErr != nil {
resultError = err
}

err = res.Delete(ctx, tName, metav1.DeleteOptions{})
if err != nil {
tLogger.Error(err, "Failed to delete a template that entered pending state",
Expand Down Expand Up @@ -665,7 +692,8 @@ func (r *PolicyReconciler) Reconcile(ctx context.Context, request reconcile.Requ

resultError = k8serrors.NewBadRequest(errMsg)

r.emitTemplateError(instance, tIndex, tName, isClusterScoped, errMsg)
//nolint:errcheck // it will already be requeued for the resultError.
r.emitTemplateError(ctx, instance, tIndex, tName, isClusterScoped, errMsg)
tLogger.Error(resultError, "Failed to create the policy template")

policyUserErrorsCounter.WithLabelValues(instance.Name, tName, "format-error").Inc()
Expand Down Expand Up @@ -711,7 +739,8 @@ func (r *PolicyReconciler) Reconcile(ctx context.Context, request reconcile.Requ
resultError = err
errMsg := fmt.Sprintf("Failed to update policy template %s: %s", tName, err)

r.emitTemplateError(instance, tIndex, tName, isClusterScoped, errMsg)
//nolint:errcheck // it will already be requeued for the resultError.
r.emitTemplateError(ctx, instance, tIndex, tName, isClusterScoped, errMsg)
tLogger.Error(err, "Failed to update the policy template")

policySystemErrorsCounter.WithLabelValues(instance.Name, tName, "patch-error").Inc()
Expand All @@ -734,7 +763,11 @@ func (r *PolicyReconciler) Reconcile(ctx context.Context, request reconcile.Requ
if isGkConstraintTemplate {
tLogger.Info("Emitting status event for " + gvk.Kind)
msg := fmt.Sprintf("%s %s was updated successfully", gvk.Kind, tName)
r.emitTemplateSuccess(instance, tIndex, tName, isClusterScoped, msg)

emitErr := r.emitTemplateSuccess(ctx, instance, tIndex, tName, isClusterScoped, msg)
if emitErr != nil {
resultError = emitErr
}
}
}

Expand Down Expand Up @@ -1186,26 +1219,39 @@ func overrideRemediationAction(instance *policiesv1.Policy, tObjectUnstructured
// policy framework. If the policy's status already reflects the current message, then no actions
// are taken.
func (r *PolicyReconciler) emitTemplateSuccess(
pol *policiesv1.Policy, tIndex int, tName string, clusterScoped bool, msg string,
) {
r.emitTemplateEvent(pol, tIndex, tName, clusterScoped, "Normal", "Compliant; ", msg)
ctx context.Context, pol *policiesv1.Policy, tIndex int, tName string, clusterScoped bool, msg string,
) error {
err := r.emitTemplateEvent(ctx, pol, tIndex, tName, clusterScoped, "Normal", "Compliant; ", msg)
if err != nil {
tlog := log.WithValues("Policy.Namespace", pol.Namespace, "Policy.Name", pol.Name, "template", tName)
tlog.Error(err, "Failed to emit template success event")
}

return err
}

// emitTemplateError performs actions that ensure correct reporting of template errors in the
// policy framework. If the policy's status already reflects the current error, then no actions
// are taken.
func (r *PolicyReconciler) emitTemplateError(
pol *policiesv1.Policy, tIndex int, tName string, clusterScoped bool, errMsg string,
) {
r.emitTemplateEvent(pol, tIndex, tName, clusterScoped, "Warning", "NonCompliant; template-error; ", errMsg)
ctx context.Context, pol *policiesv1.Policy, tIndex int, tName string, clusterScoped bool, errMsg string,
) error {
err := r.emitTemplateEvent(ctx, pol, tIndex, tName, clusterScoped,
"Warning", "NonCompliant; template-error; ", errMsg)
if err != nil {
tlog := log.WithValues("Policy.Namespace", pol.Namespace, "Policy.Name", pol.Name, "template", tName)
tlog.Error(err, "Failed to emit template error event")
}

return err
}

// emitTemplatePending performs actions that ensure correct reporting of pending dependencies in the
// policy framework. If the policy's status already reflects the current status, then no actions
// are taken.
func (r *PolicyReconciler) emitTemplatePending(
pol *policiesv1.Policy, tIndex int, tName string, clusterScoped bool, msg string,
) {
ctx context.Context, pol *policiesv1.Policy, tIndex int, tName string, clusterScoped bool, msg string,
) error {
msgMeta := "Pending; "
eventType := "Warning"

Expand All @@ -1215,33 +1261,62 @@ func (r *PolicyReconciler) emitTemplatePending(
eventType = "Normal"
}

r.emitTemplateEvent(pol, tIndex, tName, clusterScoped, eventType, msgMeta, msg)
err := r.emitTemplateEvent(ctx, pol, tIndex, tName, clusterScoped, eventType, msgMeta, msg)
if err != nil {
tlog := log.WithValues("Policy.Namespace", pol.Namespace, "Policy.Name", pol.Name, "template", tName)
tlog.Error(err, "Failed to emit template pending event")
}

return err
}

// emitTemplateEvent performs actions that ensure correct reporting of template sync events. If the
// policy's status already reflects the current status, then no actions are taken. The msgMeta and
// msg are concatenated without spaces, so any spacing should be included inside the msgMeta string.
func (r *PolicyReconciler) emitTemplateEvent(
pol *policiesv1.Policy, tIndex int, tName string, clusterScoped bool,
ctx context.Context, pol *policiesv1.Policy, tIndex int, tName string, clusterScoped bool,
eventType string, msgMeta string, msg string,
) {
) error {
// check if the error is already present in the policy status - if so, return early
if strings.Contains(getLatestStatusMessage(pol, tIndex), msgMeta+msg) {
return
return nil
}

// emit the non-compliance event
// emit an informational event
r.Recorder.Event(pol, eventType, "PolicyTemplateSync", msg)

// emit the compliance event
var policyComplianceReason string
if clusterScoped {
policyComplianceReason = fmt.Sprintf(utils.PolicyClusterScopedFmtStr, tName)
policyComplianceReason = utils.EventReason("", tName)
} else {
policyComplianceReason = fmt.Sprintf(utils.PolicyFmtStr, pol.GetNamespace(), tName)
policyComplianceReason = utils.EventReason(pol.GetNamespace(), tName)
}

r.Recorder.Event(pol, eventType, policyComplianceReason, msgMeta+msg)
sender := utils.ComplianceEventSender{
ClusterNamespace: pol.Namespace,
InstanceName: r.InstanceName,
ClientSet: r.Clientset,
ControllerName: ControllerName,
}

// emit an informational event
r.Recorder.Event(pol, eventType, "PolicyTemplateSync", msg)
ownerref := metav1.OwnerReference{
APIVersion: pol.APIVersion,
Kind: pol.Kind,
Name: pol.Name,
UID: pol.UID,
}

var compState policiesv1.ComplianceState
if strings.HasPrefix(msgMeta, "Compliant") {
compState = policiesv1.Compliant
} else if strings.HasPrefix(msgMeta, "NonCompliant") {
compState = policiesv1.NonCompliant
} else if strings.HasPrefix(msgMeta, "Pending") {
compState = policiesv1.Pending
}

return sender.SendEvent(ctx, nil, ownerref, policyComplianceReason, msgMeta+msg, compState)
}

// handleSyncSuccess performs common actions that should be run whenever a template is in sync,
Expand Down
Loading