feat(filter): add exclude_services support across providers and CLI (#749)#754
feat(filter): add exclude_services support across providers and CLI (#749)#754ThryLox wants to merge 3 commits into
Conversation
…rojectdiscovery#749) Adds exclude_services (-es, --exclude-service) filtering support to cloudlist. Allows users to specify service exclusions in provider YAML configs and CLI options to filter out unwanted services across AWS, GCP, Azure, DigitalOcean, Kubernetes, and other supported cloud providers.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughAdds Changesexclude_services feature
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
pkg/providers/gcp/gcp.go (1)
246-263: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winThe fallback here still expands an explicit empty selection into all GCP services.
If
servicesis provided but all requested entries are unsupported, Line 254 repopulates the fullServiceslist beforeexclude_servicesis applied. That violates the intended filter semantics and can turnservices: [unknown]into full GCP enumeration.As per coding guidelines, "Respect service filtering: Services() must list supported services, and providers should honor -s filters when gathering resources."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/providers/gcp/gcp.go` around lines 246 - 263, The service-selection logic in gcp.go is expanding an explicit filtered request into all GCP services when `services` is present but yields no supported entries. Update the `services` handling in the GCP provider so `options.GetMetadata("services")` is honored strictly, and only fall back to the full `Services` list when the metadata key is absent, not when it is present but empty/unsupported; keep the `exclude_services` filtering in `schema.ServiceMap` after that.Source: Coding guidelines
pkg/providers/custom/custom.go (2)
91-109: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick winPersist the computed service map on
p.
servicesis never assigned top.Services, so this filtering result is discarded and the local becomes unused. This will fail compilation once the file is built.Suggested fix
if es, ok := block.GetMetadata("exclude_services"); ok { for _, s := range strings.Split(es, ",") { delete(services, strings.TrimSpace(s)) } } + p.Services = services np, err := networkpolicy.New(networkpolicy.DefaultOptions)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/providers/custom/custom.go` around lines 91 - 109, The computed service filtering in custom provider setup is never stored, so the result is lost and `services` becomes effectively unused. Update the logic in `custom.go` after building the map from `block.GetMetadata("services")`, applying the default `Services`, and removing `exclude_services` so that the final map is assigned to `p.Services` on the provider struct. Keep the existing filtering flow intact, but make sure the computed map is persisted on `p` before returning.
92-109: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winThis still re-enables all services when the allowlist matches nothing.
If
servicesis explicitly set but every value is unsupported, Lines 100-103 repopulate the full default set before the new exclusion step runs. That breaks the service-filter contract; track whetherserviceswas specified, rather than keying fallback offlen(services).As per coding guidelines, "Respect service filtering: Services() must list supported services, and providers should honor -s filters when gathering resources."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/providers/custom/custom.go` around lines 92 - 109, The service selection logic in the custom provider is falling back to all Services whenever the allowlist produces an empty map, which overrides an explicitly provided but unsupported services filter. Update the logic in the block that reads block.GetMetadata("services") and applies exclude_services so it tracks whether services was specified and only uses the default Services set when no allowlist was provided at all. Keep the filtering behavior in Services()/custom provider resource gathering consistent with the -s contract and preserve the supportedServicesMap/strings.TrimSpace handling.Source: Coding guidelines
pkg/providers/vercel/vercel.go (1)
28-49: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winVercel has the same allowlist-empty fallback bug.
When
servicesis explicitly provided but none of those names are supported, Lines 40-43 restore every default service before the newexclude_servicesblock runs. That defeats the filter and should resolve to an empty selection instead.As per coding guidelines, "Respect service filtering: Services() must list supported services, and providers should honor -s filters when gathering resources."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/providers/vercel/vercel.go` around lines 28 - 49, The service selection logic in Vercel falls back to all default services when a provided services filter matches none, which breaks the intended allowlist behavior. Update the service-building flow in the provider’s Services handling so that an explicit metadata filter from options.GetMetadata("services") only includes supported names and, when it yields no matches, stays empty instead of restoring Services; keep exclude_services applied afterward to the selected set. Use the existing supportedServicesMap, services map, and Services slice to locate the fix.Source: Coding guidelines
pkg/providers/dnssimple/dnssimple.go (1)
60-77: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winDon't treat an empty allowlist intersection as "all services".
When
servicesis present but none of the requested names are supported, Line 68 restores the full default set and the newexclude_servicesblock deletes from that. The effective selection should stay empty instead.As per coding guidelines, "Respect service filtering: Services() must list supported services, and providers should honor -s filters when gathering resources."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/providers/dnssimple/dnssimple.go` around lines 60 - 77, The service filtering logic in dnssimple should not fall back to all defaults when the provided services allowlist has no supported intersection; keep the selection empty instead. Update the services construction in the initialization path that builds the ServiceMap from options.GetMetadata("services") and applies exclude_services so len(services) only triggers the default Services set when the services metadata is absent, not when it was present but matched nothing. Ensure the final filtering behavior in dnssimple honors the requested service names and preserves an empty result when appropriate.Source: Coding guidelines
pkg/providers/ovh/ovh.go (1)
27-46: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winThis service selection still falls back to full discovery for an explicit-but-invalid allowlist.
If the user sets
servicesand every value is unsupported, Lines 37-40 rebuild the default set, so the newexclude_servicesremoval operates on all services rather than none. The empty intersection needs to remain empty.As per coding guidelines, "Respect service filtering: Services() must list supported services, and providers should honor -s filters when gathering resources."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/providers/ovh/ovh.go` around lines 27 - 46, The service filtering logic in ovh.go currently falls back to the full default set when the explicit services allowlist contains no supported entries, which causes exclude_services to operate on all services instead of none. Update the Services() selection path so the presence of a services metadata filter is honored even when the intersection is empty: only populate the default Services set when no services filter was provided, and keep the resulting service map empty for an explicit-but-invalid allowlist before applying exclude_services.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/runner/runner.go`:
- Around line 41-43: The runner is flattening provider-specific exclude lists
into shared global state in runner.go, which causes each schema.OptionBlock to
inherit the union of all YAML exclusions. Update the logic around
GetExcludeServiceNames, options.ExcludeServices, and the later provider stamping
so per-provider exclude_services stays attached to each provider item unless the
CLI flag was explicitly provided. Keep the metadata on each schema.OptionBlock
and only merge or override it in the CLI-driven path.
In `@pkg/providers/k8s/kubernetes.go`:
- Around line 84-88: The Kubernetes provider does not fully honor the
exclude_services filter because Resources() still lists Services unconditionally
even when service has been removed from the services map. Update the
resource-gathering logic in Kubernetes.Resources() to skip calling
p.clientSet.CoreV1().Services("").List(...) when p.services.Has("service") is
false, and only process service resources when the filter allows them. Keep the
filter handling consistent with the existing exclude_services parsing in the
provider.
In `@pkg/schema/schema_test.go`:
- Around line 93-117: Extend TestOptionBlockParsesExcludeServices to cover the
explicit allowlist case in Options.ParseServices: add a scenario where the
Options entry includes services: [unknown] alongside exclude_services, and
assert that ParseServices(supported) returns no services instead of falling back
to all supported ones. Use the existing Options and ParseServices symbols in
schema_test.go so the regression is caught when the allowlist contains only
unsupported values.
In `@pkg/schema/schema.go`:
- Around line 322-337: The service filter logic in schema handling is falling
back to all supported services even when the metadata key is present but filters
down to nothing. Update the service initialization in the schema metadata
parsing path so that the “default to all services” behavior only happens when
the services metadata is absent, not when it exists but yields an empty
intersection; use the existing services parsing and supportedServicesMap logic
to distinguish those cases.
---
Outside diff comments:
In `@pkg/providers/custom/custom.go`:
- Around line 91-109: The computed service filtering in custom provider setup is
never stored, so the result is lost and `services` becomes effectively unused.
Update the logic in `custom.go` after building the map from
`block.GetMetadata("services")`, applying the default `Services`, and removing
`exclude_services` so that the final map is assigned to `p.Services` on the
provider struct. Keep the existing filtering flow intact, but make sure the
computed map is persisted on `p` before returning.
- Around line 92-109: The service selection logic in the custom provider is
falling back to all Services whenever the allowlist produces an empty map, which
overrides an explicitly provided but unsupported services filter. Update the
logic in the block that reads block.GetMetadata("services") and applies
exclude_services so it tracks whether services was specified and only uses the
default Services set when no allowlist was provided at all. Keep the filtering
behavior in Services()/custom provider resource gathering consistent with the -s
contract and preserve the supportedServicesMap/strings.TrimSpace handling.
In `@pkg/providers/dnssimple/dnssimple.go`:
- Around line 60-77: The service filtering logic in dnssimple should not fall
back to all defaults when the provided services allowlist has no supported
intersection; keep the selection empty instead. Update the services construction
in the initialization path that builds the ServiceMap from
options.GetMetadata("services") and applies exclude_services so len(services)
only triggers the default Services set when the services metadata is absent, not
when it was present but matched nothing. Ensure the final filtering behavior in
dnssimple honors the requested service names and preserves an empty result when
appropriate.
In `@pkg/providers/gcp/gcp.go`:
- Around line 246-263: The service-selection logic in gcp.go is expanding an
explicit filtered request into all GCP services when `services` is present but
yields no supported entries. Update the `services` handling in the GCP provider
so `options.GetMetadata("services")` is honored strictly, and only fall back to
the full `Services` list when the metadata key is absent, not when it is present
but empty/unsupported; keep the `exclude_services` filtering in
`schema.ServiceMap` after that.
In `@pkg/providers/ovh/ovh.go`:
- Around line 27-46: The service filtering logic in ovh.go currently falls back
to the full default set when the explicit services allowlist contains no
supported entries, which causes exclude_services to operate on all services
instead of none. Update the Services() selection path so the presence of a
services metadata filter is honored even when the intersection is empty: only
populate the default Services set when no services filter was provided, and keep
the resulting service map empty for an explicit-but-invalid allowlist before
applying exclude_services.
In `@pkg/providers/vercel/vercel.go`:
- Around line 28-49: The service selection logic in Vercel falls back to all
default services when a provided services filter matches none, which breaks the
intended allowlist behavior. Update the service-building flow in the provider’s
Services handling so that an explicit metadata filter from
options.GetMetadata("services") only includes supported names and, when it
yields no matches, stays empty instead of restoring Services; keep
exclude_services applied afterward to the selected set. Use the existing
supportedServicesMap, services map, and Services slice to locate the fix.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 20c5fcd9-0957-47ee-b3c6-e658eadface9
📒 Files selected for processing (23)
internal/runner/options.gointernal/runner/runner.gopkg/providers/alibaba/alibaba.gopkg/providers/arvancloud/arvancloud.gopkg/providers/aws/aws.gopkg/providers/azure/azure.gopkg/providers/cloudflare/cloudflare.gopkg/providers/custom/custom.gopkg/providers/digitalocean/digitalocean.gopkg/providers/dnssimple/dnssimple.gopkg/providers/gcp/gcp.gopkg/providers/heroku/heroku.gopkg/providers/hetzner/hetzner.gopkg/providers/k8s/kubernetes.gopkg/providers/linode/linode.gopkg/providers/namecheap/namecheap.gopkg/providers/openstack/openstack.gopkg/providers/ovh/ovh.gopkg/providers/scaleway/scaleway.gopkg/providers/terraform/terraform.gopkg/providers/vercel/vercel.gopkg/schema/schema.gopkg/schema/schema_test.go
…calls Addressed CodeRabbit review feedback: tracked servicesSpecified boolean in ParseServices to prevent falling back to all services when an explicit allowlist yields empty results, moved K8s Services API list call inside the service check block, and added regression unit tests.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (11)
pkg/providers/arvancloud/arvancloud.go (1)
44-56: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winDon't use
GetMetadata's bool as theservicespresence signal.
GetMetadatareturnsfalsefor both a missing key and a present-but-empty value. Here that means an explicit emptyservicesselection is treated as “not specified”, so the fallback branch re-enables all services. Use raw key presence (or a schema helper that preserves presence separately from the resolved value) before defaulting. As per coding guidelines, providers should honor service filtering instead of falling back to the full service set.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/providers/arvancloud/arvancloud.go` around lines 44 - 56, The service-selection logic in arvancloud.go is using GetMetadata("services")’s boolean as the presence check, which conflates a missing key with an explicitly empty value. Update the services parsing in the provider initialization to detect raw key presence separately from the resolved metadata value, and only fall back to Services when the key is truly absent. Keep the existing supportedServicesMap filtering and ensure an empty explicit services selection does not re-enable all services.Source: Coding guidelines
pkg/providers/aws/aws.go (1)
91-104: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winDon't use
GetMetadata's bool as theservicespresence signal.
GetMetadatareturnsfalsefor both a missing key and a present-but-empty value. Here that means an explicit emptyservicesselection is treated as “not specified”, so the fallback branch re-enables all services. Use raw key presence (or a schema helper that preserves presence separately from the resolved value) before defaulting. As per coding guidelines, providers should honor service filtering instead of falling back to the full service set.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/providers/aws/aws.go` around lines 91 - 104, The service-selection logic in aws.go is using GetMetadata("services") as the presence check, which cannot distinguish a missing key from an explicitly empty value. Update the block that populates services in the provider code to detect raw key presence separately from the resolved metadata value, and only fall back to the full Services list when the key is truly absent. Keep the filtering behavior in the services parsing path so an empty services selection does not re-enable all services.Source: Coding guidelines
pkg/providers/vercel/vercel.go (1)
33-45: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winDon't use
GetMetadata's bool as theservicespresence signal.
GetMetadatareturnsfalsefor both a missing key and a present-but-empty value. Here that means an explicit emptyservicesselection is treated as “not specified”, so the fallback branch re-enables all services. Use raw key presence (or a schema helper that preserves presence separately from the resolved value) before defaulting. As per coding guidelines, providers should honor service filtering instead of falling back to the full service set.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/providers/vercel/vercel.go` around lines 33 - 45, The services selection in the vercel provider should not rely on GetMetadata’s boolean return to detect presence, because an explicit empty value is being treated as missing and triggers the full Services fallback. Update the logic in the vercel provider’s metadata parsing to check raw key presence separately from the resolved value, then only default to Services when the key is truly absent. Keep the supportedServicesMap filtering behavior intact so explicit service filtering is honored.Source: Coding guidelines
pkg/providers/alibaba/alibaba.go (1)
50-62: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winDon't use
GetMetadata's bool as theservicespresence signal.
GetMetadatareturnsfalsefor both a missing key and a present-but-empty value. Here that means an explicit emptyservicesselection is treated as “not specified”, so the fallback branch re-enables all services. Use raw key presence (or a schema helper that preserves presence separately from the resolved value) before defaulting. As per coding guidelines, providers should honor service filtering instead of falling back to the full service set.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/providers/alibaba/alibaba.go` around lines 50 - 62, The Alibaba provider’s service selection logic is using GetMetadata’s boolean as the presence check, which cannot distinguish a missing services key from an explicitly empty value. Update the logic in the alibaba provider’s metadata parsing path to detect raw key presence separately (or use a helper that preserves presence) before defaulting. In the code that builds the services map, keep an explicit empty services selection empty instead of falling back to Services, and only populate all services when the key is truly absent.Source: Coding guidelines
pkg/providers/custom/custom.go (1)
92-105: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winDon't use
GetMetadata's bool as theservicespresence signal.
GetMetadatareturnsfalsefor both a missing key and a present-but-empty value. Here that means an explicit emptyservicesselection is treated as “not specified”, so the fallback branch re-enables all services. Use raw key presence (or a schema helper that preserves presence separately from the resolved value) before defaulting. As per coding guidelines, providers should honor service filtering instead of falling back to the full service set.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/providers/custom/custom.go` around lines 92 - 105, The service-selection logic in custom provider setup is using GetMetadata("services") as both value and presence check, which makes an explicit empty services selection fall back to all Services. Update the metadata handling in custom.go so the code first checks raw key presence (or an equivalent helper that distinguishes missing vs empty) before deciding whether to populate services, and keep the filtered set empty when the key is present but empty. Use the existing services map population around supportedServicesMap and Services as the place to apply the fix.Source: Coding guidelines
pkg/providers/dnssimple/dnssimple.go (1)
61-77: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winTrim
servicesentries before matching.This branch still matches raw
strings.Splitoutput againstsupportedServicesMap, so an explicit value likeservices: "dns, other"only works for tokens without surrounding spaces.exclude_servicesis trimmed already; the allowlist should use the same normalization or call the shared parser added in this PR. As per coding guidelines, "Respect service filtering: Services() must list supported services, and providers should honor -s filters when gathering resources."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/providers/dnssimple/dnssimple.go` around lines 61 - 77, The services allowlist in dnssimple still matches raw strings from strings.Split, so values with surrounding spaces are not recognized. Update the services parsing in the servicesSpecified branch to trim each token before checking supportedServicesMap, or reuse the shared parser used elsewhere in this PR, and keep exclude_services trimming behavior consistent in dnssimple.Services/options handling.Source: Coding guidelines
pkg/providers/linode/linode.go (1)
50-65: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winTrim allowlist entries before the supported-service lookup.
Right now only
exclude_servicesnormalizes whitespace. Ifservicescontains comma-separated values with spaces, supported entries are ignored because the map lookup uses the raw token. Using the shared schema parser here would keep Linode aligned with the intended resolution semantics. As per coding guidelines, "Respect service filtering: Services() must list supported services, and providers should honor -s filters when gathering resources."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/providers/linode/linode.go` around lines 50 - 65, The service allowlist parsing in the Linode provider does not trim whitespace before checking supported entries, so comma-separated values in the services metadata can be skipped. Update the services handling in linode.go where options.GetMetadata("services") is processed so each token is normalized with trimming before the supportedServicesMap lookup, matching the exclude_services behavior and the intended Services()/filter semantics.Source: Coding guidelines
pkg/providers/digitalocean/digitalocean.go (1)
34-50: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winTrim
servicesentries before matching.The allowlist loop compares raw CSV tokens to
supportedServicesMap, soservices: "droplet, app"silently dropsapp.exclude_servicesis already trimmed, and the schema-layer service parser in this PR trims both lists. Please eitherstrings.TrimSpace(s)here or delegate this whole block to the shared parser so provider filtering stays consistent. As per coding guidelines, "Respect service filtering: Services() must list supported services, and providers should honor -s filters when gathering resources."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/providers/digitalocean/digitalocean.go` around lines 34 - 50, The DigitalOcean service filter in digitalocean.go is matching raw CSV tokens against supportedServicesMap, so values with spaces are skipped while exclude_services already trims inputs. Update the Services()/metadata parsing block to trim each token before checking the allowlist, or reuse the shared service parser used elsewhere so the services and exclude_services handling stays consistent and honors -s filters correctly.Source: Coding guidelines
pkg/providers/heroku/heroku.go (1)
41-56: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winNormalize allowlisted service names too.
exclude_servicestrims each entry, butservicesdoes not. That makes explicit filters brittle:services: "app, other"works differently depending on whitespace. Please trimsin the allowlist loop or replace this block with the shared schema parser. As per coding guidelines, "Respect service filtering: Services() must list supported services, and providers should honor -s filters when gathering resources."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/providers/heroku/heroku.go` around lines 41 - 56, The service allowlist handling in Heroku metadata parsing is inconsistent because the `services` entries are not trimmed while `exclude_services` entries are; update the `services` loop in the Heroku provider so each value is normalized with trimming before checking `supportedServicesMap`, or switch the block to the shared schema parser used elsewhere. Make sure `servicesSpecified` still honors explicit filters in `Services()` and that names like `app, other` resolve correctly regardless of whitespace.Source: Coding guidelines
pkg/providers/k8s/kubernetes.go (1)
72-88: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winTrim explicit
servicesvalues here as well.This constructor still matches raw
strings.Splitoutput againstsupportedServicesMap, soservices: "service, ingress"dropsingressif the token is space-prefixed. That diverges from the shared schema service parser and makes Kubernetes filtering behave differently from the rest of this feature. As per coding guidelines, "Respect service filtering: Services() must list supported services, and providers should honor -s filters when gathering resources."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/providers/k8s/kubernetes.go` around lines 72 - 88, The Kubernetes provider’s explicit services parsing in the constructor still uses raw strings from strings.Split, so space-prefixed entries like " ingress" fail to match supportedServicesMap. Update the services handling in kubernetes.go to trim each token before lookup, keeping it aligned with the shared schema parser and the Services()/filtering behavior. Use the existing services map setup and the options.GetMetadata("services") branch as the place to normalize values before adding them.Source: Coding guidelines
pkg/providers/scaleway/scaleway.go (1)
37-52: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winMake
servicesparsing matchexclude_servicesparsing.The new allowlist path still uses raw split tokens, so whitespace-padded values won't match
supportedServicesMap. Since the exclude path already trims and the schema helper in this PR trims both, this provider now has slightly different filter behavior than the rest of the stack. As per coding guidelines, "Respect service filtering: Services() must list supported services, and providers should honor -s filters when gathering resources."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/providers/scaleway/scaleway.go` around lines 37 - 52, The services allowlist parsing in Scaleway should match the trimming behavior used by exclude_services and the schema helper. Update the services handling in the Scaleway provider’s metadata parsing so the loop in the Services()/options path trims each split token before checking supportedServicesMap and adding to services, keeping filter behavior consistent with the rest of the stack.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@pkg/providers/alibaba/alibaba.go`:
- Around line 50-62: The Alibaba provider’s service selection logic is using
GetMetadata’s boolean as the presence check, which cannot distinguish a missing
services key from an explicitly empty value. Update the logic in the alibaba
provider’s metadata parsing path to detect raw key presence separately (or use a
helper that preserves presence) before defaulting. In the code that builds the
services map, keep an explicit empty services selection empty instead of falling
back to Services, and only populate all services when the key is truly absent.
In `@pkg/providers/arvancloud/arvancloud.go`:
- Around line 44-56: The service-selection logic in arvancloud.go is using
GetMetadata("services")’s boolean as the presence check, which conflates a
missing key with an explicitly empty value. Update the services parsing in the
provider initialization to detect raw key presence separately from the resolved
metadata value, and only fall back to Services when the key is truly absent.
Keep the existing supportedServicesMap filtering and ensure an empty explicit
services selection does not re-enable all services.
In `@pkg/providers/aws/aws.go`:
- Around line 91-104: The service-selection logic in aws.go is using
GetMetadata("services") as the presence check, which cannot distinguish a
missing key from an explicitly empty value. Update the block that populates
services in the provider code to detect raw key presence separately from the
resolved metadata value, and only fall back to the full Services list when the
key is truly absent. Keep the filtering behavior in the services parsing path so
an empty services selection does not re-enable all services.
In `@pkg/providers/custom/custom.go`:
- Around line 92-105: The service-selection logic in custom provider setup is
using GetMetadata("services") as both value and presence check, which makes an
explicit empty services selection fall back to all Services. Update the metadata
handling in custom.go so the code first checks raw key presence (or an
equivalent helper that distinguishes missing vs empty) before deciding whether
to populate services, and keep the filtered set empty when the key is present
but empty. Use the existing services map population around supportedServicesMap
and Services as the place to apply the fix.
In `@pkg/providers/digitalocean/digitalocean.go`:
- Around line 34-50: The DigitalOcean service filter in digitalocean.go is
matching raw CSV tokens against supportedServicesMap, so values with spaces are
skipped while exclude_services already trims inputs. Update the
Services()/metadata parsing block to trim each token before checking the
allowlist, or reuse the shared service parser used elsewhere so the services and
exclude_services handling stays consistent and honors -s filters correctly.
In `@pkg/providers/dnssimple/dnssimple.go`:
- Around line 61-77: The services allowlist in dnssimple still matches raw
strings from strings.Split, so values with surrounding spaces are not
recognized. Update the services parsing in the servicesSpecified branch to trim
each token before checking supportedServicesMap, or reuse the shared parser used
elsewhere in this PR, and keep exclude_services trimming behavior consistent in
dnssimple.Services/options handling.
In `@pkg/providers/heroku/heroku.go`:
- Around line 41-56: The service allowlist handling in Heroku metadata parsing
is inconsistent because the `services` entries are not trimmed while
`exclude_services` entries are; update the `services` loop in the Heroku
provider so each value is normalized with trimming before checking
`supportedServicesMap`, or switch the block to the shared schema parser used
elsewhere. Make sure `servicesSpecified` still honors explicit filters in
`Services()` and that names like `app, other` resolve correctly regardless of
whitespace.
In `@pkg/providers/k8s/kubernetes.go`:
- Around line 72-88: The Kubernetes provider’s explicit services parsing in the
constructor still uses raw strings from strings.Split, so space-prefixed entries
like " ingress" fail to match supportedServicesMap. Update the services handling
in kubernetes.go to trim each token before lookup, keeping it aligned with the
shared schema parser and the Services()/filtering behavior. Use the existing
services map setup and the options.GetMetadata("services") branch as the place
to normalize values before adding them.
In `@pkg/providers/linode/linode.go`:
- Around line 50-65: The service allowlist parsing in the Linode provider does
not trim whitespace before checking supported entries, so comma-separated values
in the services metadata can be skipped. Update the services handling in
linode.go where options.GetMetadata("services") is processed so each token is
normalized with trimming before the supportedServicesMap lookup, matching the
exclude_services behavior and the intended Services()/filter semantics.
In `@pkg/providers/scaleway/scaleway.go`:
- Around line 37-52: The services allowlist parsing in Scaleway should match the
trimming behavior used by exclude_services and the schema helper. Update the
services handling in the Scaleway provider’s metadata parsing so the loop in the
Services()/options path trims each split token before checking
supportedServicesMap and adding to services, keeping filter behavior consistent
with the rest of the stack.
In `@pkg/providers/vercel/vercel.go`:
- Around line 33-45: The services selection in the vercel provider should not
rely on GetMetadata’s boolean return to detect presence, because an explicit
empty value is being treated as missing and triggers the full Services fallback.
Update the logic in the vercel provider’s metadata parsing to check raw key
presence separately from the resolved value, then only default to Services when
the key is truly absent. Keep the supportedServicesMap filtering behavior intact
so explicit service filtering is honored.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 4b55ec4a-4af2-476a-9c39-6000ed4ec9c3
📒 Files selected for processing (21)
pkg/providers/alibaba/alibaba.gopkg/providers/arvancloud/arvancloud.gopkg/providers/aws/aws.gopkg/providers/azure/azure.gopkg/providers/cloudflare/cloudflare.gopkg/providers/custom/custom.gopkg/providers/digitalocean/digitalocean.gopkg/providers/dnssimple/dnssimple.gopkg/providers/gcp/gcp.gopkg/providers/heroku/heroku.gopkg/providers/hetzner/hetzner.gopkg/providers/k8s/kubernetes.gopkg/providers/linode/linode.gopkg/providers/namecheap/namecheap.gopkg/providers/openstack/openstack.gopkg/providers/ovh/ovh.gopkg/providers/scaleway/scaleway.gopkg/providers/terraform/terraform.gopkg/providers/vercel/vercel.gopkg/schema/schema.gopkg/schema/schema_test.go
🚧 Files skipped from review as they are similar to previous changes (10)
- pkg/providers/ovh/ovh.go
- pkg/providers/namecheap/namecheap.go
- pkg/providers/terraform/terraform.go
- pkg/providers/cloudflare/cloudflare.go
- pkg/schema/schema_test.go
- pkg/providers/openstack/openstack.go
- pkg/providers/hetzner/hetzner.go
- pkg/providers/azure/azure.go
- pkg/schema/schema.go
- pkg/providers/gcp/gcp.go
Addressed CodeRabbit review feedback: stopped flattening per-provider YAML exclude_services options into shared global state in NewRunner, preserving provider-specific YAML exclusions unless explicitly overridden by the CLI flag.
Summary
Fixes #749 by adding first-class support for
exclude_services(-es,--exclude-service) across provider configuration YAML files and CLI flags.Context & Problem
While
cloudlistpreviously supportedservices:as a positive allowlist, users had no clean way to express "enumerate everything except service X". Skipping a single noisy service required manually listing every other supported service in the provider config.Key Changes
-es/--exclude-serviceflags tointernal/runner/options.goand updatedOptionBlockYAML unmarshaling inpkg/schema/schema.go.ParseServiceshelper and updated all 19 provider implementations (AWS, GCP, Azure, DigitalOcean, Kubernetes, etc.) to subtract excluded services during enumeration.pkg/schema/schema_test.goverifying YAML parsing and service exclusion maps.Summary by CodeRabbit
--exclude-service(-es) andexclude_servicessettings to omit specific services from provider discovery.servicesis explicitly provided but contains only unsupported entries, it no longer falls back to enabling all services.exclude_servicesparsing and for the “no fallback when services are explicitly unsupported” behavior.