vmware-tanzu/cartographer

owner short-circuits best-match selection unless labelled

Open

#868 opened on May 20, 2022

 (0 comments) (0 reactions) (0 assignees)Go (64 forks)auto 404
buggood first issue

Repository metrics

Stars
 (452 stars)
PR merge metrics
 (PR metrics pending)

Description

Bug description:

irrespective of the supplychains available in a cluster, the Workload reconciler currently bails out reconciling a Workload if it has no labels set. such behavior prevents folks writing supplychains from performing selection based solely on fields instead of labels.

Steps to reproduce:

  1. create a workload with no labels
# workload.yaml
apiVersion: carto.run/v1alpha1
kind: Workload
metadata:
  name: no-labels
spec: {image: foo}
  1. submit it
$ kubectl apply -f workload.yaml
  1. observe its status
$ k get workload no-labels -o jsonpath={.status.conditions} | jq '.'

[
  {
    "lastTransitionTime": "2022-05-20T18:10:50Z",
    "message": "workload has no labels to match to supply chain",
    "reason": "WorkloadLabelsMissing",
    "status": "False",
    "type": "SupplyChainReady"
  },
  {
    "lastTransitionTime": "2022-05-20T18:10:50Z",
    "message": "workload has no labels to match to supply chain",
    "reason": "WorkloadLabelsMissing",
    "status": "False",
    "type": "Ready"
  }
]

Expected behavior:

Have the reconciliation actually trying to perform the selection based on bestmatch. e.g., without a supplychain that selects based solely on spec.image, I should see:

$ k get workload no-labels -o jsonpath={.status.conditions} | jq '.'
[
  {
    "lastTransitionTime": "2022-05-20T18:14:47Z",
    "message": "no supply chain found where full selector is satisfied by labels: map[]",       // maybe even this msg should be better?
    "reason": "SupplyChainNotFound",
    "status": "False",
    "type": "SupplyChainReady"
  },
  {
    "lastTransitionTime": "2022-05-20T18:14:47Z",
    "message": "no supply chain found where full selector is satisfied by labels: map[]",
    "reason": "SupplyChainNotFound",
    "status": "False",
    "type": "Ready"
  }
]

but then, submitting a supplychain that selects on spec.image,

apiVersion: carto.run/v1alpha1
kind: ClusterSupplyChain
metadata:
  name: foo
spec:
  resources: []
  selectorMatchFields:
  - key: spec.image
    operator: Exists

I should see that despite no labels, we do get it reconciled:

$ k get workload no-labels -o jsonpath={.status.conditions} | jq '.'
[
  {
    "lastTransitionTime": "2022-05-20T18:17:51Z",
    "message": "",
    "reason": "Ready",
    "status": "True",
    "type": "SupplyChainReady"
  },
  {
    "lastTransitionTime": "2022-05-20T18:17:53Z",
    "message": "",
    "reason": "ResourceSubmissionComplete",
    "status": "True",
    "type": "ResourcesSubmitted"
  },
  {
    "lastTransitionTime": "2022-05-20T18:17:53Z",
    "message": "",
    "reason": "Ready",
    "status": "True",
    "type": "Ready"
  }
]

Actual behavior:

See above - a clustersupplychain that selects based on fields and no labels ends up not being usable.

Versions:

  • local (kind)
  • main (as of 693036beb08f237ad45e3715c92a61a7e718cd81)
  • not relevant, but, v1.23.4 (no joke, that's the version)

Additional context:

main offender:

func (r *WorkloadReconciler) getSupplyChainsForWorkload(ctx context.Context, workload *v1alpha1.Workload) (*v1alpha1.ClusterSupplyChain, error) {
        log := logr.FromContextOrDiscard(ctx)
        if len(workload.Labels) == 0 {
                r.conditionManager.AddPositive(conditions.WorkloadMissingLabelsCondition())
                log.Info("workload is missing required labels")
                return nil, fmt.Errorf("workload [%s/%s] is missing required labels",
                        workload.Namespace, workload.Name)
        }

(see pkg/controllers/workload_reconciler.go)

Contributor guide