Skip to content
Merged
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
57 changes: 28 additions & 29 deletions controllers/cmd/placement/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package placement
import (
"fmt"
"os"
"strings"

secretmanager "cloud.google.com/go/secretmanager/apiv1"
"github.com/spf13/cobra"
Expand All @@ -21,10 +22,21 @@ func envOr(key, fallback string) string {
return fallback
}

// parseDomains splits a comma-separated domain list, trimming whitespace and
// dropping empty entries.
func parseDomains(csv string) []string {
var domains []string
for _, d := range strings.Split(csv, ",") {
if d = strings.TrimSpace(d); d != "" {
domains = append(domains, d)
}
}
return domains
}

// NewCommand returns the placement subcommand.
func NewCommand(rf *setup.RootFlags) *cobra.Command {
var candidateNames, baseDomains []string
var smProject, maestroHTTPAddr string
var smProject, hcDNSDomains string

cmd := &cobra.Command{
Use: "placement",
Expand All @@ -33,8 +45,8 @@ func NewCommand(rf *setup.RootFlags) *cobra.Command {
if v := envOr("SECRETMANAGER_PROJECT", ""); v != "" && !cmd.Flags().Changed("secretmanager-project") {
smProject = v
}
if v := envOr("MAESTRO_HTTP_ADDR", ""); v != "" && !cmd.Flags().Changed("maestro-http-addr") {
maestroHTTPAddr = v
if smProject == "" {
return fmt.Errorf("--secretmanager-project is required (or $SECRETMANAGER_PROJECT)")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cristianoveiga i realize this may make more complex the local runs of this controller. let me know if you want me to reinstate the mc list flag.. but then we also need to add other params like maintenance...

alternatively, we go the externalsecret route. and on local deployment we can create our own secret?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea of having the candidates list (either via a flag or a configmap/secret), but I think we can deal with that separately (in a future PR)

}

ctx := cmd.Context()
Expand All @@ -44,26 +56,15 @@ func NewCommand(rf *setup.RootFlags) *cobra.Command {
return fmt.Errorf("create logger: %w", err)
}

var selector placement.Selector
var candidates []placement.Candidate

if smProject != "" {
smClient, err := secretmanager.NewClient(ctx)
if err != nil {
return fmt.Errorf("create secret manager client: %w", err)
}
defer smClient.Close() //nolint:errcheck
selector = placement.NewDynamicSelector(smClient, smProject, maestroHTTPAddr)
} else {
candidates = make([]placement.Candidate, 0, len(candidateNames))
for i, name := range candidateNames {
c := placement.Candidate{Name: name}
if i < len(baseDomains) {
c.BaseDomains = []string{baseDomains[i]}
}
candidates = append(candidates, c)
}
selector = placement.NewRoundRobinSelector()
smClient, err := secretmanager.NewClient(ctx)
if err != nil {
return fmt.Errorf("create secret manager client: %w", err)
}
defer smClient.Close() //nolint:errcheck

selector, err := placement.NewDynamicSelector(smClient, smProject, parseDomains(hcDNSDomains))
if err != nil {
return fmt.Errorf("create selector: %w", err)
}

scheme := setup.NewScheme()
Expand All @@ -72,7 +73,7 @@ func NewCommand(rf *setup.RootFlags) *cobra.Command {
return fmt.Errorf("create manager: %w", err)
}

rec := placement.NewReconciler(selector, candidates, log, mgr.GetClient())
rec := placement.NewReconciler(selector, log, mgr.GetClient())

if err := ctrl.NewControllerManagedBy(mgr).
For(&privatev1.Cluster{}).
Expand All @@ -85,10 +86,8 @@ func NewCommand(rf *setup.RootFlags) *cobra.Command {
},
}

cmd.Flags().StringSliceVar(&candidateNames, "candidates", nil, "MC names (comma-separated); ignored when --secretmanager-project is set")
cmd.Flags().StringSliceVar(&baseDomains, "base-domains", nil, "Base domains per MC, paired with --candidates")
cmd.Flags().StringVar(&smProject, "secretmanager-project", "", "GCP project for Secret Manager MC/DNS discovery [$SECRETMANAGER_PROJECT]; enables dynamic selector")
cmd.Flags().StringVar(&maestroHTTPAddr, "maestro-http-addr", "http://maestro.hyperfleet.svc.cluster.local:8000", "Maestro HTTP API URL for consumer discovery [$MAESTRO_HTTP_ADDR]")
cmd.Flags().StringVar(&smProject, "secretmanager-project", "", "GCP project for Secret Manager mc-registration discovery [$SECRETMANAGER_PROJECT] (required)")
cmd.Flags().StringVar(&hcDNSDomains, "hc-dns-domains", "", "Comma-separated list of HC DNS zone domains to round-robin across")

return cmd
}
28 changes: 28 additions & 0 deletions controllers/cmd/placement/cmd_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package placement

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestParseDomains(t *testing.T) {
tests := []struct {
name string
input string
expect []string
}{
{"single domain", "example.com", []string{"example.com"}},
{"multiple domains", "a.example.com,b.example.com", []string{"a.example.com", "b.example.com"}},
{"trims whitespace", " a.example.com , b.example.com ", []string{"a.example.com", "b.example.com"}},
{"drops empty entries from trailing comma", "a.example.com,", []string{"a.example.com"}},
{"drops whitespace-only entries", "a.example.com, , ,b.example.com", []string{"a.example.com", "b.example.com"}},
{"empty string → nil", "", nil},
{"only commas → nil", ",,,", nil},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
assert.Equal(t, tc.expect, parseDomains(tc.input))
})
}
}
Loading
Loading