Skip to content

04 - Plugin Configuration

This section covers the configuration methods every plugin must implement: RateLimit() and LabelConfig().

Configuration Methods

The ResourcePlugin interface requires three configuration methods:

Method Required Purpose
RateLimit() Yes Limits requests to protect the target system
LabelConfig() Yes Extracts human-readable labels for discovered resources
DiscoveryFilters() Optional Excludes certain resources from discovery

We'll implement the first two now. DiscoveryFilters() is covered in the Advanced section.

RateLimit

SFTP servers typically limit concurrent connections. The RateLimit() method tells formae how fast it can send requests to your plugin.

func (p *Plugin) RateLimit() plugin.RateLimitConfig {
    return plugin.RateLimitConfig{
        Scope:                            plugin.RateLimitScopeNamespace,
        MaxRequestsPerSecondForNamespace: 5,
    }
}

Configuration Fields

Field Description
Scope Currently only RateLimitScopeNamespace is supported
MaxRequestsPerSecondForNamespace Maximum requests per second across all resource types

Choosing a Rate Limit

Consider your target system's limits:

  • SFTP servers: Often allow 5-10 concurrent connections
  • Cloud APIs: Check the provider's documentation (AWS: varies by service, typically 10-100 RPS)
  • SaaS APIs: Usually documented in API docs (e.g., "100 requests per minute")

For our SFTP plugin, we'll use 5 requests per second as a conservative default.

Why Rate Limiting Matters

formae runs multiple operations concurrently:

  • User-triggered applies and destroys
  • Background synchronization (periodic reads)
  • Discovery scans

Without rate limiting, these could overwhelm your target system. The rate limiter ensures all operations share a fair quota.

LabelConfig

When formae discovers resources, it needs a human-readable label to display. The LabelConfig() method tells formae how to extract labels from your resources.

func (p *Plugin) LabelConfig() plugin.LabelConfig {
    return plugin.LabelConfig{
        DefaultQuery: "$.path",
    }
}

Configuration Fields

Field Description
DefaultQuery JSONPath expression applied to all resources
ResourceOverrides Per-resource-type overrides (optional)

JSONPath for Labels

The DefaultQuery is a JSONPath expression that extracts a label from the resource's JSON representation. For our File resource:

{
  "path": "/data/config.txt",
  "content": "...",
  "permissions": "0644"
}

Using $.path extracts /data/config.txt as the label.

Resource Overrides

If your plugin has multiple resource types with different naming conventions, use ResourceOverrides:

func (p *Plugin) LabelConfig() plugin.LabelConfig {
    return plugin.LabelConfig{
        DefaultQuery: "$.path",
        ResourceOverrides: map[string]string{
            "SFTP::Config::Setting": "$.name",
        },
    }
}

For our simple SFTP plugin with only one resource type, we don't need overrides.

DiscoveryFilters (Optional)

The DiscoveryFilters() method excludes certain resources from discovery. For now, we return nil to discover all files:

func (p *Plugin) DiscoveryFilters() []plugin.MatchFilter {
    return nil
}

This is covered in detail in the Advanced section.

Update sftp.go

The template already has these methods. Update RateLimit() and LabelConfig() with our values:

// RateLimit returns the rate limiting configuration for this plugin.
// SFTP servers typically limit concurrent connections, so we use a
// conservative limit of 5 requests per second.
func (p *Plugin) RateLimit() plugin.RateLimitConfig {
    return plugin.RateLimitConfig{
        Scope:                            plugin.RateLimitScopeNamespace,
        MaxRequestsPerSecondForNamespace: 5,
    }
}

// DiscoveryFilters returns filters to exclude resources from discovery.
// We discover all files, so return nil.
func (p *Plugin) DiscoveryFilters() []plugin.MatchFilter {
    return nil
}

// LabelConfig returns the configuration for extracting labels from resources.
// For files, the path is the natural label.
func (p *Plugin) LabelConfig() plugin.LabelConfig {
    return plugin.LabelConfig{
        DefaultQuery: "$.path",
    }
}

Verify

To verify that the configuration methods compile correctly:

cd formae-plugin-sftp
make build

Summary

With configuration methods complete, your plugin now tells formae:

  1. Rate limit: 5 requests per second to protect the SFTP server
  2. Labels: Use the file path as the display name for discovered files
  3. Discovery filters: Discover all files (no exclusions)

Next: 05 - Create - Implement file creation using TDD