VOL-2496 Add "event listen" command to voltctl

Change-Id: I8f1fb34b55f56c8125142ac289e2f19fc170d804
diff --git a/pkg/filter/filter.go b/pkg/filter/filter.go
index d78a21a..0c18394 100644
--- a/pkg/filter/filter.go
+++ b/pkg/filter/filter.go
@@ -113,6 +113,31 @@
 	return result, nil
 }
 
+// returns False if the filter does not match
+// returns true if the filter does match or the operation is unsupported
+func testField(v FilterTerm, field reflect.Value) bool {
+	switch v.Op {
+	case RE:
+		if !v.re.MatchString(fmt.Sprintf("%v", field)) {
+			return false
+		}
+	case EQ:
+		// This seems to work for most comparisons
+		if fmt.Sprintf("%v", field) != v.Value {
+			return false
+		}
+	case NE:
+		// This seems to work for most comparisons
+		if fmt.Sprintf("%v", field) == v.Value {
+			return false
+		}
+	default:
+		// For unsupported operations, always pass
+	}
+
+	return true
+}
+
 func (f Filter) Evaluate(item interface{}) bool {
 	val := reflect.ValueOf(item)
 
@@ -122,23 +147,22 @@
 			return false
 		}
 
-		switch v.Op {
-		case RE:
-			if !v.re.MatchString(fmt.Sprintf("%v", field)) {
+		if (field.Kind() == reflect.Slice) || (field.Kind() == reflect.Array) {
+			// For an array, check to see if any item matches
+			someMatch := false
+			for i := 0; i < field.Len(); i++ {
+				arrayElem := field.Index(i)
+				if testField(v, arrayElem) {
+					someMatch = true
+				}
+			}
+			if !someMatch {
 				return false
 			}
-		case EQ:
-			// This seems to work for most comparisons
-			if fmt.Sprintf("%v", field) != v.Value {
+		} else {
+			if !testField(v, field) {
 				return false
 			}
-		case NE:
-			// This seems to work for most comparisons
-			if fmt.Sprintf("%v", field) == v.Value {
-				return false
-			}
-		default:
-			// For unsupported operations, always pass
 		}
 	}
 	return true