Skip to content

Commit

Permalink
feat: status for cert manager not installed in tls policies
Browse files Browse the repository at this point in the history
Signed-off-by: KevFan <[email protected]>
  • Loading branch information
KevFan committed Oct 2, 2024
1 parent 84f8a86 commit e8ab3d4
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 30 deletions.
15 changes: 5 additions & 10 deletions controllers/state_of_the_world.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
istioclientnetworkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3"
istioclientgosecurityv1beta1 "istio.io/client-go/pkg/apis/security/v1beta1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"
Expand Down Expand Up @@ -95,7 +96,6 @@ func NewPolicyMachineryController(manager ctrlruntime.Manager, client *dynamic.D
controller.WithObjectLinks(
kuadrantv1beta1.LinkKuadrantToGatewayClasses,
),
controller.WithReconcile(buildReconciler(client)),
}

ok, err := kuadrantgatewayapi.IsGatewayAPIInstalled(manager.GetRESTMapper())
Expand Down Expand Up @@ -195,18 +195,20 @@ func NewPolicyMachineryController(manager ctrlruntime.Manager, client *dynamic.D
logger.Info("cert manager is not installed, skipping related watches and reconcilers", "err", err)
} else {
controllerOpts = append(controllerOpts, certManagerControllerOpts()...)
// TODO: add tls policy specific tasks to workflow
}

controllerOpts = append(controllerOpts, controller.WithReconcile(buildReconciler(client, manager.GetRESTMapper())))

return controller.NewController(controllerOpts...)
}

func buildReconciler(client *dynamic.DynamicClient) controller.ReconcileFunc {
func buildReconciler(client *dynamic.DynamicClient, restMapper meta.RESTMapper) controller.ReconcileFunc {
reconciler := &controller.Workflow{
Precondition: (&controller.Workflow{
Precondition: NewEventLogger().Log,
Tasks: []controller.ReconcileFunc{
NewTopologyFileReconciler(client, operatorNamespace).Reconcile,
NewIsCertManagerInstalledTask(restMapper).Reconcile,
},
}).Run,
Tasks: []controller.ReconcileFunc{
Expand Down Expand Up @@ -370,13 +372,6 @@ func (e *EventLogger) Log(ctx context.Context, resourceEvents []controller.Resou
return nil
}

func NewTLSPolicyWorkflow(client *dynamic.DynamicClient) *controller.Workflow {
return &controller.Workflow{
Precondition: NewValidateTLSPolicyTask().Reconcile,
Postcondition: NewTLSPolicyStatusTask(client).Reconcile,
}
}

func isObjectOwnedByKind(o client.Object, ownerGroup, ownerKind string) bool {
for _, o := range o.GetOwnerReferences() {
oGV, err := schema.ParseGroupVersion(o.APIVersion)
Expand Down
68 changes: 53 additions & 15 deletions controllers/tlspolicy_tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"

kuadrantv1alpha1 "github.com/kuadrant/kuadrant-operator/api/v1alpha1"
kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi"
"github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant"
"github.com/kuadrant/kuadrant-operator/pkg/library/utils"
)
Expand All @@ -37,6 +38,13 @@ var (
CertManagerClusterIssuerKind = schema.GroupKind{Group: certmanager.GroupName, Kind: certmanagerv1.ClusterIssuerKind}
)

func NewTLSPolicyWorkflow(client *dynamic.DynamicClient) *controller.Workflow {
return &controller.Workflow{
Precondition: NewValidateTLSPolicyTask().Reconcile,
Postcondition: NewTLSPolicyStatusTask(client).Reconcile,
}
}

type ValidateTLSPolicyTask struct{}

func NewValidateTLSPolicyTask() *ValidateTLSPolicyTask {
Expand Down Expand Up @@ -72,12 +80,25 @@ func (t *ValidateTLSPolicyTask) Reconcile(ctx context.Context, _ []controller.Re
return gw, ok
})

isCertManagerInstalled := false
installed, ok := s.Load(IsCertManagerInstalledKey)
if ok {
isCertManagerInstalled = installed.(bool)
} else {
logger.V(1).Error(errors.New("isCertManagerInstalled was not found in sync map, defaulting to false"), "sync map error")
}

for _, policy := range policies {
if policy.DeletionTimestamp != nil {
logger.V(1).Info("tls policy is marked for deletion, skipping", "name", policy.Name, "namespace", policy.Namespace)
continue
}

if !isCertManagerInstalled {
s.Store(TLSPolicyAcceptedKey(policy.GetUID()), kuadrant.NewErrDependencyNotInstalled("Cert Manager"))
continue
}

// TODO: This should be only one target ref for now, but what should happen if multiple target refs is supported in the future?
targetRefs := policy.GetTargetRefs()
for _, targetRef := range targetRefs {
Expand All @@ -92,12 +113,12 @@ func (t *ValidateTLSPolicyTask) Reconcile(ctx context.Context, _ []controller.Re
// Can't find gateway target ref
if !ok {
logger.Info("tls policy cannot find target ref", "name", policy.Name, "namespace", policy.Namespace)
s.Store(TLSPolicyValidKey(policy.GetUID()), false)
s.Store(TLSPolicyAcceptedKey(policy.GetUID()), kuadrant.NewErrTargetNotFound(policy.Kind(), policy.GetTargetRef(), apierrors.NewNotFound(kuadrantv1alpha1.TLSPoliciesResource.GroupResource(), policy.GetName())))
continue
}

logger.Info("tls policy found target ref", "name", policy.Name, "namespace", policy.Namespace)
s.Store(TLSPolicyValidKey(policy.GetUID()), true)
s.Store(TLSPolicyAcceptedKey(policy.GetUID()), nil)
}
}

Expand Down Expand Up @@ -136,7 +157,7 @@ func (t *TLSPolicyStatusTask) Reconcile(ctx context.Context, _ []controller.Reso

for _, policy := range policies {
if policy.DeletionTimestamp != nil {
logger.Info("tls policy is marked for deletion", "name", policy.Name, "namespace", policy.Namespace)
logger.V(1).Info("tls policy is marked for deletion, skipping", "name", policy.Name, "namespace", policy.Namespace)
continue
}

Expand All @@ -147,18 +168,10 @@ func (t *TLSPolicyStatusTask) Reconcile(ctx context.Context, _ []controller.Reso
}

var err error
isValid, ok := s.Load(TLSPolicyValidKey(policy.GetUID()))
// Should not happen unless this was triggered by an event where the ValidateTLSPolicyTask.Reconcile function was not called
if !ok {
err = fmt.Errorf("unable to find %s key in sync map", policy.GetUID())
logger.Error(err, "unexpected error")
continue
}
// Target Ref not found
if !isValid.(bool) {
err = kuadrant.NewErrTargetNotFound(policy.Kind(), policy.GetTargetRef(), apierrors.NewNotFound(kuadrantv1alpha1.TLSPoliciesResource.GroupResource(), policy.GetName()))
accepted, ok := s.Load(TLSPolicyAcceptedKey(policy.GetUID()))
if ok && accepted != nil {
err = accepted.(error)
}

meta.SetStatusCondition(&newStatus.Conditions, *kuadrant.AcceptedCondition(policy, err))

// Do not set enforced condition if Accepted condition is false
Expand Down Expand Up @@ -316,6 +329,31 @@ func (t *TLSPolicyStatusTask) isCertificatesReady(ctx context.Context, p machine
return nil
}

func TLSPolicyValidKey(uid types.UID) string {
const IsCertManagerInstalledKey = "IsCertManagerInstalled"

func NewIsCertManagerInstalledTask(restMapper meta.RESTMapper) IsCertManagerInstalledTask {
return IsCertManagerInstalledTask{
restMapper: restMapper,
}
}

type IsCertManagerInstalledTask struct {
restMapper meta.RESTMapper
}

func (t IsCertManagerInstalledTask) Reconcile(ctx context.Context, _ []controller.ResourceEvent, topology *machinery.Topology, _ error, s *sync.Map) error {

Check failure on line 344 in controllers/tlspolicy_tasks.go

View workflow job for this annotation

GitHub Actions / Lint

unused-parameter: parameter 'topology' seems to be unused, consider removing or renaming it as _ (revive)
logger := controller.LoggerFromContext(ctx).WithName("IsCertManagerInstalledTask").WithName("Reconcile")
isCertManagerInstalled, err := kuadrantgatewayapi.IsCertManagerInstalled(t.restMapper, logger)

if err != nil {
logger.Error(err, "error checking IsCertManagerInstalled")
}

s.Store(IsCertManagerInstalledKey, isCertManagerInstalled)

return nil
}

func TLSPolicyAcceptedKey(uid types.UID) string {
return fmt.Sprintf("TLSPolicyValid:%s", uid)
}
4 changes: 2 additions & 2 deletions controllers/tlspolicy_tasks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant"
)

func TestTLSPolicyValidKey(t *testing.T) {
func TestTLSPolicyAcceptedKey(t *testing.T) {
type args struct {
uid types.UID
}
Expand All @@ -42,7 +42,7 @@ func TestTLSPolicyValidKey(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := TLSPolicyValidKey(tt.args.uid); got != tt.want {
if got := TLSPolicyAcceptedKey(tt.args.uid); got != tt.want {
t.Errorf("TLSPolicyValidKey() = %v, want %v", got, tt.want)
}
})
Expand Down
7 changes: 4 additions & 3 deletions pkg/library/kuadrant/apimachinery_status_conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ import (
const (
PolicyConditionEnforced gatewayapiv1alpha2.PolicyConditionType = "Enforced"

PolicyReasonEnforced gatewayapiv1alpha2.PolicyConditionReason = "Enforced"
PolicyReasonOverridden gatewayapiv1alpha2.PolicyConditionReason = "Overridden"
PolicyReasonUnknown gatewayapiv1alpha2.PolicyConditionReason = "Unknown"
PolicyReasonEnforced gatewayapiv1alpha2.PolicyConditionReason = "Enforced"
PolicyReasonOverridden gatewayapiv1alpha2.PolicyConditionReason = "Overridden"
PolicyReasonUnknown gatewayapiv1alpha2.PolicyConditionReason = "Unknown"
PolicyReasonMissingDependency gatewayapiv1alpha2.PolicyConditionReason = "MissingDependency"
)

func NewAffectedPolicyMap() *AffectedPolicyMap {
Expand Down
20 changes: 20 additions & 0 deletions pkg/library/kuadrant/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,23 @@ func reasonForError(err error) gatewayapiv1alpha2.PolicyConditionReason {
}
return ""
}

func NewErrDependencyNotInstalled(dependencyName string) ErrDependencyNotInstalled {
return ErrDependencyNotInstalled{
dependencyName: dependencyName,
}
}

var _ PolicyError = ErrDependencyNotInstalled{}

type ErrDependencyNotInstalled struct {
dependencyName string
}

func (e ErrDependencyNotInstalled) Error() string {
return fmt.Sprintf("%s is not installed, please restart pod once dependency has been installed", e.dependencyName)
}

func (e ErrDependencyNotInstalled) Reason() gatewayapiv1alpha2.PolicyConditionReason {
return PolicyReasonMissingDependency
}

0 comments on commit e8ab3d4

Please sign in to comment.