|
|
@@ -244,7 +244,9 @@ func convertAliasFilterToLabelAnnotationFilter(aliasKey string, filterValue stri
|
|
|
return nil, fmt.Errorf("unsupported op type '%s' for alias conversion", op)
|
|
|
}
|
|
|
|
|
|
- return ops.Or(
|
|
|
+ // This handles the case where a label EXISTS/IS PRESENT for (is extant)
|
|
|
+ // for an aliased field. That's the primary case.
|
|
|
+ extantCaseNode := ops.Or(
|
|
|
ops.And(
|
|
|
ops.Contains(afilter.FieldLabel, aliasKey),
|
|
|
labelOp,
|
|
|
@@ -256,5 +258,27 @@ func convertAliasFilterToLabelAnnotationFilter(aliasKey string, filterValue stri
|
|
|
annotationOp,
|
|
|
),
|
|
|
),
|
|
|
- ), nil
|
|
|
+ )
|
|
|
+ var node ast.FilterNode
|
|
|
+ // This handles the special case of unallocated aliased value. There's
|
|
|
+ // two forms of this; first is where the label/annotation exists, but
|
|
|
+ // has an empty string value. That's actually handled by the extant case,
|
|
|
+ // because the API passes through that empty string. The other is when
|
|
|
+ // the aliased label/annotation doesn't exist for an allocation. That's
|
|
|
+ // what this modification to the tree handles. This matters when you're
|
|
|
+ // trying to drill into/identify workloads "not allocated" within that
|
|
|
+ // specific aliased field.
|
|
|
+ if filterValue == "" || filterValue == UnallocatedSuffix {
|
|
|
+ node = ops.Or(
|
|
|
+ extantCaseNode,
|
|
|
+ ops.And(
|
|
|
+ ops.Not(ops.Contains(afilter.FieldLabel, aliasKey)),
|
|
|
+ ops.Not(ops.Contains(afilter.FieldAnnotation, aliasKey)),
|
|
|
+ ),
|
|
|
+ )
|
|
|
+ } else {
|
|
|
+ node = extantCaseNode
|
|
|
+ }
|
|
|
+
|
|
|
+ return node, nil
|
|
|
}
|