Skip to content

Commit

Permalink
refactor: list missing dependencies in status message
Browse files Browse the repository at this point in the history
Signed-off-by: KevFan <[email protected]>
  • Loading branch information
KevFan committed Jan 14, 2025
1 parent e1f802c commit b446956
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 108 deletions.
36 changes: 26 additions & 10 deletions controllers/auth_policies_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,8 @@ func (r *AuthPolicyValidator) Validate(ctx context.Context, _ []controller.Resou
defer logger.V(1).Info("finished validating auth policies")

state.Store(StateAuthPolicyValid, lo.SliceToMap(policies, func(policy machinery.Policy) (string, error) {
if !r.isGatewayAPIInstalled {
return policy.GetLocator(), kuadrant.MissingGatewayAPIError()
}

if !r.isGatewayProviderInstalled {
return policy.GetLocator(), kuadrant.MissingGatewayProviderError()
}

if !r.isAuthorinoOperatorInstalled {
return policy.GetLocator(), kuadrant.MissingAuthorinoOperatorError()
if err := r.isMissingDependency(); err != nil {
return policy.GetLocator(), err
}

var err error
Expand All @@ -74,3 +66,27 @@ func (r *AuthPolicyValidator) Validate(ctx context.Context, _ []controller.Resou

return nil
}

func (r *AuthPolicyValidator) isMissingDependency() error {
isMissingDependency := false
var missingDependencies []string

if !r.isGatewayAPIInstalled {
isMissingDependency = true
missingDependencies = append(missingDependencies, "Gateway API")
}
if !r.isGatewayProviderInstalled {
isMissingDependency = true
missingDependencies = append(missingDependencies, "Gateway API provider (istio / envoy gateway)")
}
if !r.isAuthorinoOperatorInstalled {
isMissingDependency = true
missingDependencies = append(missingDependencies, "Authorino Operator")
}

if isMissingDependency {
return kuadrant.NewErrDependencyNotInstalled(missingDependencies...)
}

return nil
}
28 changes: 22 additions & 6 deletions controllers/dnspolicies_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,8 @@ func (r *DNSPoliciesValidator) validate(ctx context.Context, _ []controller.Reso
logger.V(1).Info("validating dns policies", "policies", len(policies))

state.Store(StateDNSPolicyAcceptedKey, lo.SliceToMap(policies, func(p machinery.Policy) (string, error) {
if !r.isGatewayAPIInstalled {
return p.GetLocator(), kuadrant.MissingGatewayAPIError()
}

if !r.isDNSOperatorInstalled {
return p.GetLocator(), kuadrant.MissingDNSOperatorError()
if err := r.isMissingDependency(); err != nil {
return p.GetLocator(), err
}

policy := p.(*kuadrantv1.DNSPolicy)
Expand All @@ -77,6 +73,26 @@ func (r *DNSPoliciesValidator) validate(ctx context.Context, _ []controller.Reso
return nil
}

func (r *DNSPoliciesValidator) isMissingDependency() error {
isMissingDependency := false
var missingDependencies []string

if !r.isGatewayAPIInstalled {
isMissingDependency = true
missingDependencies = append(missingDependencies, "Gateway API")
}
if !r.isDNSOperatorInstalled {
isMissingDependency = true
missingDependencies = append(missingDependencies, "DNS Operator")
}

if isMissingDependency {
return kuadrant.NewErrDependencyNotInstalled(missingDependencies...)
}

return nil
}

// isTargetRefsFound Policies are already linked to their targets.
// If the target ref length and length of targetables by this policy is not the same, then the policy could not find the target.
func isTargetRefsFound(topology *machinery.Topology, p *kuadrantv1.DNSPolicy) error {
Expand Down
59 changes: 31 additions & 28 deletions controllers/kuadrant_status_updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const (

type KuadrantStatusUpdater struct {
Client *dynamic.DynamicClient
isGatwayAPIInstalled bool
isGatewayAPIInstalled bool
isGatewayProviderInstalled bool
isLimitadorOperatorInstalled bool
isAuthorinoOperatorInstalled bool
Expand All @@ -37,7 +37,7 @@ type KuadrantStatusUpdater struct {
func NewKuadrantStatusUpdater(client *dynamic.DynamicClient, isGatewayAPIInstalled, isGatewayProviderInstalled, isLimitadorOperatorInstalled, isAuthorinoOperatorInstalled bool) *KuadrantStatusUpdater {
return &KuadrantStatusUpdater{
Client: client,
isGatwayAPIInstalled: isGatewayAPIInstalled,
isGatewayAPIInstalled: isGatewayAPIInstalled,
isGatewayProviderInstalled: isGatewayProviderInstalled,
isLimitadorOperatorInstalled: isLimitadorOperatorInstalled,
isAuthorinoOperatorInstalled: isAuthorinoOperatorInstalled,
Expand Down Expand Up @@ -128,32 +128,7 @@ func (r *KuadrantStatusUpdater) readyCondition(topology *machinery.Topology, log
Message: "Kuadrant is ready",
}

if !r.isGatwayAPIInstalled {
err := kuadrant.MissingGatewayAPIError()
cond.Status = metav1.ConditionFalse
cond.Reason = string(err.Reason())
cond.Message = err.Error()
return cond
}

if !r.isGatewayProviderInstalled {
err := kuadrant.MissingGatewayProviderError()
cond.Status = metav1.ConditionFalse
cond.Reason = string(err.Reason())
cond.Message = err.Error()
return cond
}

if !r.isLimitadorOperatorInstalled {
err := kuadrant.MissingLimitadorOperatorError()
cond.Status = metav1.ConditionFalse
cond.Reason = string(err.Reason())
cond.Message = err.Error()
return cond
}

if !r.isAuthorinoOperatorInstalled {
err := kuadrant.MissingAuthorinoOperatorError()
if err := r.isMissingDependency(); err != nil {
cond.Status = metav1.ConditionFalse
cond.Reason = string(err.Reason())
cond.Message = err.Error()
Expand All @@ -177,6 +152,34 @@ func (r *KuadrantStatusUpdater) readyCondition(topology *machinery.Topology, log
return cond
}

func (r *KuadrantStatusUpdater) isMissingDependency() kuadrant.PolicyError {
isMissingDependency := false
var missingDependencies []string

if !r.isGatewayAPIInstalled {
isMissingDependency = true
missingDependencies = append(missingDependencies, "Gateway API")
}
if !r.isGatewayProviderInstalled {
isMissingDependency = true
missingDependencies = append(missingDependencies, "Gateway API provider (istio / envoy gateway)")
}
if !r.isAuthorinoOperatorInstalled {
isMissingDependency = true
missingDependencies = append(missingDependencies, "Authorino Operator")
}
if !r.isLimitadorOperatorInstalled {
isMissingDependency = true
missingDependencies = append(missingDependencies, "Limitador Operator")
}

if isMissingDependency {
return kuadrant.NewErrDependencyNotInstalled(missingDependencies...)
}

return nil
}

func checkLimitadorReady(topology *machinery.Topology, logger logr.Logger) *string {
limitadorObj := GetLimitadorFromTopology(topology)
if limitadorObj == nil {
Expand Down
36 changes: 26 additions & 10 deletions controllers/ratelimit_policies_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,8 @@ func (r *RateLimitPolicyValidator) Validate(ctx context.Context, _ []controller.
defer logger.V(1).Info("finished validating rate limit policies")

state.Store(StateRateLimitPolicyValid, lo.SliceToMap(policies, func(policy machinery.Policy) (string, error) {
if !r.isGatewayAPIInstalled {
return policy.GetLocator(), kuadrant.MissingGatewayAPIError()
}

if !r.isGatewayProviderInstalled {
return policy.GetLocator(), kuadrant.MissingGatewayProviderError()
}

if !r.isLimitadorOperatorInstalled {
return policy.GetLocator(), kuadrant.MissingLimitadorOperatorError()
if err := r.isMissingDependency(); err != nil {
return policy.GetLocator(), err
}

var err error
Expand All @@ -74,3 +66,27 @@ func (r *RateLimitPolicyValidator) Validate(ctx context.Context, _ []controller.

return nil
}

func (r *RateLimitPolicyValidator) isMissingDependency() error {
isMissingDependency := false
var missingDependencies []string

if !r.isGatewayAPIInstalled {
isMissingDependency = true
missingDependencies = append(missingDependencies, "Gateway API")
}
if !r.isGatewayProviderInstalled {
isMissingDependency = true
missingDependencies = append(missingDependencies, "Gateway API provider (istio / envoy gateway)")
}
if !r.isLimitadorOperatorInstalled {
isMissingDependency = true
missingDependencies = append(missingDependencies, "Limitador Operator")
}

if isMissingDependency {
return kuadrant.NewErrDependencyNotInstalled(missingDependencies...)
}

return nil
}
50 changes: 33 additions & 17 deletions controllers/tlspolicies_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type TLSPoliciesValidator struct {
isCertManagerInstalled bool
}

func (t *TLSPoliciesValidator) Subscription() *controller.Subscription {
func (r *TLSPoliciesValidator) Subscription() *controller.Subscription {
return &controller.Subscription{
Events: []controller.ResourceEventMatcher{
{Kind: &machinery.GatewayGroupKind},
Expand All @@ -40,43 +40,39 @@ func (t *TLSPoliciesValidator) Subscription() *controller.Subscription {
{Kind: &CertManagerIssuerKind},
{Kind: &CertManagerClusterIssuerKind},
},
ReconcileFunc: t.Validate,
ReconcileFunc: r.Validate,
}
}

func (t *TLSPoliciesValidator) Validate(ctx context.Context, _ []controller.ResourceEvent, topology *machinery.Topology, _ error, state *sync.Map) error {
func (r *TLSPoliciesValidator) Validate(ctx context.Context, _ []controller.ResourceEvent, topology *machinery.Topology, _ error, state *sync.Map) error {
logger := controller.LoggerFromContext(ctx).WithName("TLSPoliciesValidator").WithName("Validate")

policies := lo.Filter(topology.Policies().Items(), filterForTLSPolicies)
logger.V(1).Info("validating tls policies", "policies", len(policies))

state.Store(TLSPolicyAcceptedKey, lo.SliceToMap(policies, func(p machinery.Policy) (string, error) {
if !t.isGatewayAPIInstalled {
return p.GetLocator(), kuadrant.MissingGatewayAPIError()
}

if !t.isCertManagerInstalled {
return p.GetLocator(), kuadrant.MissingCertManagerError()
if err := r.isMissingDependency(); err != nil {
return p.GetLocator(), err
}

policy := p.(*kuadrantv1.TLSPolicy)
// Validate target ref
if err := t.isTargetRefsFound(topology, policy); err != nil {
if err := r.isTargetRefsFound(topology, policy); err != nil {
return p.GetLocator(), err
}

// Validate if there's a conflicting policy
if err := t.isConflict(policies, policy); err != nil {
if err := r.isConflict(policies, policy); err != nil {
return p.GetLocator(), err
}

// Validate IssuerRef kind is correct
if err := t.isValidIssuerKind(policy); err != nil {
if err := r.isValidIssuerKind(policy); err != nil {
return p.GetLocator(), err
}

// Validate Issuer is present on cluster through the topology
if err := t.isIssuerFound(topology, policy); err != nil {
if err := r.isIssuerFound(topology, policy); err != nil {
return p.GetLocator(), err
}

Expand All @@ -88,10 +84,30 @@ func (t *TLSPoliciesValidator) Validate(ctx context.Context, _ []controller.Reso
return nil
}

func (r *TLSPoliciesValidator) isMissingDependency() error {
isMissingDependency := false
var missingDependencies []string

if !r.isGatewayAPIInstalled {
isMissingDependency = true
missingDependencies = append(missingDependencies, "Gateway API")
}
if !r.isCertManagerInstalled {
isMissingDependency = true
missingDependencies = append(missingDependencies, "Cert Manager")
}

if isMissingDependency {
return kuadrant.NewErrDependencyNotInstalled(missingDependencies...)
}

return nil
}

// isTargetRefsFound Policies are already linked to their targets. If the target ref length and length of targetables by this policy is not the same,
// then the policy could not find the target
// TODO: What should happen if multiple target refs is supported in the future in terms of reporting in log and policy status?
func (t *TLSPoliciesValidator) isTargetRefsFound(topology *machinery.Topology, p *kuadrantv1.TLSPolicy) error {
func (r *TLSPoliciesValidator) isTargetRefsFound(topology *machinery.Topology, p *kuadrantv1.TLSPolicy) error {
if len(p.GetTargetRefs()) != len(topology.Targetables().Children(p)) {
return kuadrant.NewErrTargetNotFound(kuadrantv1.TLSPolicyGroupKind.Kind, p.Spec.TargetRef.LocalPolicyTargetReference, apierrors.NewNotFound(controller.GatewaysResource.GroupResource(), p.GetName()))
}
Expand All @@ -100,7 +116,7 @@ func (t *TLSPoliciesValidator) isTargetRefsFound(topology *machinery.Topology, p
}

// isConflict Validates if there's already an older policy with the same target ref
func (t *TLSPoliciesValidator) isConflict(policies []machinery.Policy, p *kuadrantv1.TLSPolicy) error {
func (r *TLSPoliciesValidator) isConflict(policies []machinery.Policy, p *kuadrantv1.TLSPolicy) error {
conflictingP, ok := lo.Find(policies, func(item machinery.Policy) bool {
conflictTLSPolicy := item.(*kuadrantv1.TLSPolicy)
return p != conflictTLSPolicy && conflictTLSPolicy.DeletionTimestamp == nil &&
Expand All @@ -116,7 +132,7 @@ func (t *TLSPoliciesValidator) isConflict(policies []machinery.Policy, p *kuadra
}

// isValidIssuerKind Validates that the Issuer Ref kind is either empty, Issuer or ClusterIssuer
func (t *TLSPoliciesValidator) isValidIssuerKind(p *kuadrantv1.TLSPolicy) error {
func (r *TLSPoliciesValidator) isValidIssuerKind(p *kuadrantv1.TLSPolicy) error {
if !lo.Contains([]string{"", certmanv1.IssuerKind, certmanv1.ClusterIssuerKind}, p.Spec.IssuerRef.Kind) {
return kuadrant.NewErrInvalid(kuadrantv1.TLSPolicyGroupKind.Kind, fmt.Errorf(`invalid value %q for issuerRef.kind. Must be empty, %q or %q`,
p.Spec.IssuerRef.Kind, certmanv1.IssuerKind, certmanv1.ClusterIssuerKind))
Expand All @@ -126,7 +142,7 @@ func (t *TLSPoliciesValidator) isValidIssuerKind(p *kuadrantv1.TLSPolicy) error
}

// isIssuerFound Validates that the Issuer specified can be found in the topology
func (t *TLSPoliciesValidator) isIssuerFound(topology *machinery.Topology, p *kuadrantv1.TLSPolicy) error {
func (r *TLSPoliciesValidator) isIssuerFound(topology *machinery.Topology, p *kuadrantv1.TLSPolicy) error {
_, ok := lo.Find(topology.Objects().Children(p), func(item machinery.Object) bool {
runtimeObj, ok := item.(*controller.RuntimeObject)
if !ok {
Expand Down
Loading

0 comments on commit b446956

Please sign in to comment.