Skip to content

add reconcile-reources flag #176

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ const (
flagReconcileDefaultMaxConcurrency = "reconcile-default-max-concurrent-syncs"
flagReconcileResourceMaxConcurrency = "reconcile-resource-max-concurrent-syncs"
flagFeatureGates = "feature-gates"
flagReconcileResources = "reconcile-resources"
envVarAWSRegion = "AWS_REGION"
)

Expand Down Expand Up @@ -104,6 +105,7 @@ type Config struct {
ReconcileResourceResyncSeconds []string
ReconcileDefaultMaxConcurrency int
ReconcileResourceMaxConcurrency []string
ReconcileResources string
// TODO(a-hilaly): migrate to k8s.io/component-base and implement a proper parser for feature gates.
FeatureGates featuregate.FeatureGates
featureGatesRaw string
Expand Down Expand Up @@ -250,6 +252,11 @@ func (cfg *Config) BindFlags() {
"Valid keys are feature names and valid values are 'true' or 'false'."+
"Available features: "+strings.Join(featuregate.GetDefaultFeatureGates().GetFeatureNames(), ", "),
)
flag.StringVar(
&cfg.ReconcileResources, flagReconcileResources,
"",
"A comma-separated list of resource kinds to reconcile. If unspecified, all resources will be reconciled.",
)
}

// SetupLogger initializes the logger used in the service controller
Expand Down Expand Up @@ -389,6 +396,12 @@ func (cfg *Config) validateReconcileConfigResources(supportedGVKs []schema.Group
return fmt.Errorf("invalid value for flag '%s': %v", flagReconcileResourceMaxConcurrency, err)
}
}

// Also validate the resource filter settings
if err := cfg.validateReconcileResources(validResourceNames); err != nil {
return err
}

return nil
}

Expand Down Expand Up @@ -564,3 +577,56 @@ func parseFeatureGates(featureGatesRaw string) (map[string]bool, error) {

return featureGatesMap, nil
}

// GetReconcileResources returns a slice of resource kinds that should be reconciled.
func (cfg *Config) GetReconcileResources() ([]string, error) {
return parseReconcileResourcesString(cfg.ReconcileResources)
}

// parseReconcileResourcesString parses the reconcileResources flag and returns a slice
// of resource kinds to reconcile.
func parseReconcileResourcesString(resources string) ([]string, error) {
resources = strings.TrimSpace(resources)
if resources == "" {
return nil, nil
}

visited := make(map[string]bool)
resourceKinds := []string{}

for _, kind := range strings.Split(resources, ",") {
kind = strings.TrimSpace(kind)
if kind == "" {
return nil, fmt.Errorf("invalid resource kind: empty kind")
}
if _, ok := visited[kind]; ok {
return nil, fmt.Errorf("duplicate resource kind '%s'", kind)
}
visited[kind] = true
resourceKinds = append(resourceKinds, kind)
}
return resourceKinds, nil
}

// validateReconcileResources validates that the specified resource kinds are supported by the controller.
func (cfg *Config) validateReconcileResources(validResourceNames []string) error {
resources, err := cfg.GetReconcileResources()
if err != nil {
return fmt.Errorf("invalid value for flag '%s': %v", flagReconcileResources, err)
}
if len(resources) == 0 {
return nil
}

for _, resource := range resources {
if !ackutil.InStrings(resource, validResourceNames) {
return fmt.Errorf(
"invalid value for flag '%s': resource kind '%s' is not supported by this controller. Valid resource kinds are: %s",
flagReconcileResources,
resource,
strings.Join(validResourceNames, ", "),
)
}
}
return nil
}
29 changes: 28 additions & 1 deletion pkg/runtime/service_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
ackmetrics "github.com/aws-controllers-k8s/runtime/pkg/metrics"
ackrtcache "github.com/aws-controllers-k8s/runtime/pkg/runtime/cache"
acktypes "github.com/aws-controllers-k8s/runtime/pkg/types"
ackutil "github.com/aws-controllers-k8s/runtime/pkg/util"
)

const (
Expand Down Expand Up @@ -271,7 +272,33 @@ func (c *serviceController) BindControllerManager(mgr ctrlrt.Manager, cfg ackcfg
c.fieldExportReconciler = rec
}

for _, rmf := range c.rmFactories {
// Get the list of resources to reconcile from the config
reconcileResources, err := cfg.GetReconcileResources()
if err != nil {
return fmt.Errorf("error parsing reconcile resources: %v", err)
}

if len(reconcileResources) == 0 {
c.log.Info("No resources? Did they all go on vacation? Defaulting to reconciling all resources.")
}
// Filter the resource manager factories
filteredRMFs := c.rmFactories
if len(reconcileResources) > 0 {
filteredRMFs = make(map[string]acktypes.AWSResourceManagerFactory)
for key, rmf := range c.rmFactories {
rd := rmf.ResourceDescriptor()
resourceKind := rd.GroupVersionKind().Kind

if ackutil.InStrings(resourceKind, reconcileResources) {
filteredRMFs[key] = rmf
c.log.Info("including reconciler for resource kind", "kind", resourceKind)
} else {
c.log.Info("excluding reconciler for resource kind", "kind", resourceKind, "reason", "not in reconcile-resources flag")
}
}
}

for _, rmf := range filteredRMFs {
rec := NewReconciler(c, rmf, c.log, cfg, c.metrics, cache)
if err := rec.BindControllerManager(mgr); err != nil {
return err
Expand Down