List operation support wildcard match method (#181)

diff --git a/pkg/validate/instance.go b/pkg/validate/instance.go
index 1cebe73..fe1c2ab 100644
--- a/pkg/validate/instance.go
+++ b/pkg/validate/instance.go
@@ -5,7 +5,7 @@
 const (
 	key                   = "key"
 	commonNameRegexString = `^[a-zA-Z0-9]*$|^[a-zA-Z0-9][a-zA-Z0-9_\-.]*[a-zA-Z0-9]$`
-	getKeyRegexString     = `^[a-zA-Z0-9]*$|^[a-zA-Z0-9][a-zA-Z0-9_\-.]*[a-zA-Z0-9]$|^beginWith\([a-zA-Z0-9][a-zA-Z0-9_\-.]*\)$`
+	getKeyRegexString     = `^[a-zA-Z0-9]*$|^[a-zA-Z0-9][a-zA-Z0-9_\-.]*[a-zA-Z0-9]$|^beginWith\([a-zA-Z0-9][a-zA-Z0-9_\-.]*\)$|^wildcard\([a-zA-Z0-9][a-zA-Z0-9_\-.*]*\)$`
 	asciiRegexString      = `^[\x00-\x7F]*$`
 	allCharString         = `.*`
 )
diff --git a/server/service/mongo/kv/kv_dao.go b/server/service/mongo/kv/kv_dao.go
index 138776f..378e559 100644
--- a/server/service/mongo/kv/kv_dao.go
+++ b/server/service/mongo/kv/kv_dao.go
@@ -123,8 +123,14 @@
 	filter := bson.M{"domain": domain, "project": project}
 	if opts.Key != "" {
 		filter["key"] = opts.Key
-		if strings.HasPrefix(opts.Key, "beginWith") {
-			filter["key"] = bson.M{"$regex": getValue(opts.Key), "$options": "$i"}
+		switch {
+		case strings.HasPrefix(opts.Key, "beginWith("):
+			value := strings.ReplaceAll(getValue(opts.Key), ".", "\\.")
+			filter["key"] = bson.M{"$regex": value, "$options": "$i"}
+		case strings.HasPrefix(opts.Key, "wildcard("):
+			value := strings.ReplaceAll(getValue(opts.Key), ".", "\\.")
+			value = strings.ReplaceAll(value, "*", ".*")
+			filter["key"] = bson.M{"$regex": value, "$options": "$i"}
 		}
 	}
 	if len(opts.Labels) != 0 {