@@ -6,6 +6,7 @@ package connection
66import (
77 "fmt"
88 "slices"
9+ "strconv"
910 "strings"
1011
1112 "github.com/aws/aws-sdk-go-v2/aws"
@@ -19,14 +20,43 @@ type DiscoveryFilters struct {
1920 General GeneralDiscoveryFilters
2021}
2122
22- // ensure all underlying reference types aren't `nil`
23- func EmptyDiscoveryFilters () DiscoveryFilters {
24- return DiscoveryFilters {
25- General : GeneralDiscoveryFilters {Regions : []string {}, ExcludeRegions : []string {}, Tags : map [string ]string {}, ExcludeTags : map [string ]string {}},
26- Ec2 : Ec2DiscoveryFilters {InstanceIds : []string {}, ExcludeInstanceIds : []string {}},
27- Ecr : EcrDiscoveryFilters {Tags : []string {}, ExcludeTags : []string {}},
28- Ecs : EcsDiscoveryFilters {},
23+ func DiscoveryFiltersFromOpts (opts map [string ]string ) DiscoveryFilters {
24+ d := DiscoveryFilters {
25+ General : GeneralDiscoveryFilters {
26+ Regions : parseCsvSliceOpt (opts , "regions" ),
27+ ExcludeRegions : parseCsvSliceOpt (opts , "exclude:regions" ),
28+ Tags : parseMapOpt (opts , "tag:" ),
29+ ExcludeTags : parseMapOpt (opts , "exclude:tag:" ),
30+ },
31+ Ec2 : Ec2DiscoveryFilters {
32+ InstanceIds : parseCsvSliceOpt (opts , "ec2:instance-ids" ),
33+ ExcludeInstanceIds : parseCsvSliceOpt (opts , "ec2:exclude:instance-ids" ),
34+ },
35+ Ecr : EcrDiscoveryFilters {
36+ Tags : parseCsvSliceOpt (opts , "ecr:tags" ),
37+ ExcludeTags : parseCsvSliceOpt (opts , "ecr:exclude:tags" ),
38+ },
39+ Ecs : EcsDiscoveryFilters {
40+ OnlyRunningContainers : parseBoolOpt (opts , "ecs:only-running-containers" , false ),
41+ DiscoverInstances : parseBoolOpt (opts , "ecs:discover-instances" , false ),
42+ DiscoverImages : parseBoolOpt (opts , "ecs:discover-images" , false ),
43+ },
2944 }
45+
46+ // TODO: backward compatibility, remove in future versions
47+ ec2Tags := parseMapOpt (opts , "ec2:tag:" )
48+ ec2ExcludeTags := parseMapOpt (opts , "ec2:exclude:tag:" )
49+ for k , v := range ec2Tags {
50+ if _ , exists := d .General .Tags [k ]; ! exists {
51+ d .General .Tags [k ] = v
52+ }
53+ }
54+ for k , v := range ec2ExcludeTags {
55+ if _ , exists := d .General .ExcludeTags [k ]; ! exists {
56+ d .General .ExcludeTags [k ] = v
57+ }
58+ }
59+ return d
3060}
3161
3262type GeneralDiscoveryFilters struct {
@@ -107,3 +137,58 @@ type EcsDiscoveryFilters struct {
107137 DiscoverImages bool
108138 DiscoverInstances bool
109139}
140+
141+ // Given a key-value pair that matches a key, return the boolean value of the key.
142+ // If the key is not found or the value cannot be parsed as a boolean, return the default value.
143+ // Example: key = "ecs:only-running-containers", opts = {"ecs:only-running-containers": "true"}
144+ // Returns: true
145+ func parseBoolOpt (opts map [string ]string , key string , defaultVal bool ) bool {
146+ for k , v := range opts {
147+ if k == key {
148+ parsed , err := strconv .ParseBool (v )
149+ if err == nil {
150+ return parsed
151+ }
152+ }
153+ }
154+ return defaultVal
155+ }
156+
157+ // Given a map of options and a key prefix, return a map of key-value pairs
158+ // where the keys start with the given prefix, with the prefix removed.
159+ // Example:
160+ // keyPrefix = "tag:"
161+ // opts = {"tag:env": "prod", "tag:role": "web"}
162+ // returns {"env": "prod", "role": "web"}
163+ func parseMapOpt (opts map [string ]string , keyPrefix string ) map [string ]string {
164+ res := map [string ]string {}
165+ for k , v := range opts {
166+ if k == "" || v == "" {
167+ continue
168+ }
169+ if ! strings .HasPrefix (k , keyPrefix ) {
170+ continue
171+ }
172+ res [strings .TrimPrefix (k , keyPrefix )] = v
173+ }
174+ return res
175+ }
176+
177+ // Given a map of options and a key, return a slice of strings
178+ // where the key matches the given key. The value is split by commas.
179+ // Example:
180+ // key = "regions"
181+ // opts = {"regions": "us-east-1,us-west-2"}
182+ // returns []string{"us-east-1", "us-west-2"}
183+ func parseCsvSliceOpt (opts map [string ]string , key string ) []string {
184+ res := []string {}
185+ for k , v := range opts {
186+ if k == "" || v == "" {
187+ continue
188+ }
189+ if k == key {
190+ res = append (res , strings .Split (v , "," )... )
191+ }
192+ }
193+ return res
194+ }
0 commit comments