cmd flags fixes, fix the bug with multi source (#149)

This commit is contained in:
Yerken 2017-04-12 18:13:03 +02:00 committed by Martin Linkhorst
parent 0604fa919d
commit 0b43cf511f
6 changed files with 59 additions and 26 deletions

13
main.go
View File

@ -37,6 +37,7 @@ import (
"github.com/kubernetes-incubator/external-dns/provider" "github.com/kubernetes-incubator/external-dns/provider"
"github.com/kubernetes-incubator/external-dns/registry" "github.com/kubernetes-incubator/external-dns/registry"
"github.com/kubernetes-incubator/external-dns/source" "github.com/kubernetes-incubator/external-dns/source"
"github.com/spf13/pflag"
) )
var ( var (
@ -46,6 +47,9 @@ var (
func main() { func main() {
cfg := externaldns.NewConfig() cfg := externaldns.NewConfig()
if err := cfg.ParseFlags(os.Args); err != nil { if err := cfg.ParseFlags(os.Args); err != nil {
if err == pflag.ErrHelp {
os.Exit(0)
}
log.Fatalf("flag parsing error: %v", err) log.Fatalf("flag parsing error: %v", err)
} }
if cfg.Version { if cfg.Version {
@ -80,7 +84,12 @@ func main() {
source.Register("service", source.NewServiceSource(client, cfg.Namespace, cfg.Compatibility)) source.Register("service", source.NewServiceSource(client, cfg.Namespace, cfg.Compatibility))
source.Register("ingress", source.NewIngressSource(client, cfg.Namespace)) source.Register("ingress", source.NewIngressSource(client, cfg.Namespace))
sources := source.NewMultiSource(source.LookupMultiple(cfg.Sources...)...) sources, err := source.LookupMultiple(cfg.Sources)
if err != nil {
log.Fatal(err)
}
multiSource := source.NewMultiSource(sources)
var p provider.Provider var p provider.Provider
switch cfg.Provider { switch cfg.Provider {
@ -116,7 +125,7 @@ func main() {
ctrl := controller.Controller{ ctrl := controller.Controller{
Zone: cfg.Zone, Zone: cfg.Zone,
Source: sources, Source: multiSource,
Registry: r, Registry: r,
Policy: policy, Policy: policy,
Interval: cfg.Interval, Interval: cfg.Interval,

View File

@ -59,26 +59,25 @@ func NewConfig() *Config {
// ParseFlags adds and parses flags from command line // ParseFlags adds and parses flags from command line
func (cfg *Config) ParseFlags(args []string) error { func (cfg *Config) ParseFlags(args []string) error {
flags := pflag.NewFlagSet("", pflag.ContinueOnError) flags := pflag.NewFlagSet("external-dns", pflag.ContinueOnError)
flags.BoolVar(&cfg.InCluster, "in-cluster", false, "whether to use in-cluster config") flags.BoolVar(&cfg.InCluster, "in-cluster", false, "whether to use in-cluster config")
flags.StringVar(&cfg.KubeConfig, "kubeconfig", "", "path to a local kubeconfig file") flags.StringVar(&cfg.KubeConfig, "kubeconfig", "", "path to a local kubeconfig file")
flags.StringVar(&cfg.Namespace, "namespace", v1.NamespaceAll, "the namespace to look for endpoints; all namespaces by default") flags.StringVar(&cfg.Namespace, "namespace", v1.NamespaceAll, "the namespace to look for endpoints; all namespaces by default")
flags.StringVar(&cfg.Zone, "zone", "", "the ID of the hosted zone to target") flags.StringVar(&cfg.Zone, "zone", "", "the ID of the hosted zone to target")
flags.StringArrayVar(&cfg.Sources, "source", nil, "the sources to gather endpoints from") flags.StringArrayVar(&cfg.Sources, "source", nil, "the sources to gather endpoints: [service, ingress], e.g. --source service --source ingress")
flags.StringVar(&cfg.Provider, "provider", "", "the DNS provider to materialize the records in") flags.StringVar(&cfg.Provider, "provider", "", "the DNS provider to materialize the records in: <aws|google>")
flags.StringVar(&cfg.GoogleProject, "google-project", "", "gcloud project to target") flags.StringVar(&cfg.GoogleProject, "google-project", "", "gcloud project to target")
flags.StringVar(&cfg.Policy, "policy", "sync", "the policy to use. options: [\"sync\", \"upsert-only\"]") flags.StringVar(&cfg.Policy, "policy", "sync", "the policy to use: <sync|upsert-only>")
flags.BoolVar(&cfg.Compatibility, "compatibility", false, "enable to process annotation semantics from legacy implementations") flags.BoolVar(&cfg.Compatibility, "compatibility", false, "enable to process annotation semantics from legacy implementations")
flags.StringVar(&cfg.MetricsAddress, "metrics-address", defaultMetricsAddress, "address to expose metrics on") flags.StringVar(&cfg.MetricsAddress, "metrics-address", defaultMetricsAddress, "address to expose metrics on")
flags.StringVar(&cfg.LogFormat, "log-format", defaultLogFormat, "log format output: <text|json>") flags.StringVar(&cfg.LogFormat, "log-format", defaultLogFormat, "log format output: <text|json>")
flags.DurationVar(&cfg.Interval, "interval", time.Minute, "interval between synchronizations") flags.DurationVar(&cfg.Interval, "interval", time.Minute, "interval between synchronizations")
flags.BoolVar(&cfg.Once, "once", false, "run once and exit") flags.BoolVar(&cfg.Once, "once", false, "run once and exit")
flags.BoolVar(&cfg.DryRun, "dry-run", true, "dry-run mode") flags.BoolVar(&cfg.DryRun, "dry-run", true, "run without updating DNS provider")
flags.BoolVar(&cfg.Debug, "debug", false, "debug mode") flags.BoolVar(&cfg.Debug, "debug", false, "debug mode")
flags.BoolVar(&cfg.Version, "version", false, "display the version") flags.BoolVar(&cfg.Version, "version", false, "display the version")
flags.StringVar(&cfg.Registry, "registry", "noop", "type of registry for ownership: <noop|txt>") flags.StringVar(&cfg.Registry, "registry", "noop", "type of registry for ownership: <noop|txt>")
flags.StringVar(&cfg.RecordOwnerID, "record-owner-id", "", "id of the current external dns for labeling owned records") flags.StringVar(&cfg.RecordOwnerID, "record-owner-id", "", "id for keeping track of the managed records")
flags.StringVar(&cfg.TXTPrefix, "txt-prefix", "", `prefix of the associated TXT records DNS name; if --txt-prefix="abc-", flags.StringVar(&cfg.TXTPrefix, "txt-prefix", "", `prefix assigned to DNS name of the associated TXT record; e.g. for --txt-prefix=abc_ [CNAME example.org] <-> [TXT abc_example.org]`)
corresponding txt record for CNAME [example.org] will have DNSName [abc-example.org]. Required for CNAME ownership support`)
return flags.Parse(args) return flags.Parse(args)
} }

View File

@ -40,6 +40,6 @@ func (ms *multiSource) Endpoints() ([]*endpoint.Endpoint, error) {
} }
// NewMultiSource creates a new multiSource. // NewMultiSource creates a new multiSource.
func NewMultiSource(children ...Source) Source { func NewMultiSource(children []Source) Source {
return &multiSource{children: children} return &multiSource{children: children}
} }

View File

@ -69,7 +69,7 @@ func testMultiSourceEndpoints(t *testing.T) {
} }
// Create our object under test and get the endpoints. // Create our object under test and get the endpoints.
source := NewMultiSource(sources...) source := NewMultiSource(sources)
endpoints, err := source.Endpoints() endpoints, err := source.Endpoints()
if err != nil { if err != nil {

View File

@ -16,6 +16,8 @@ limitations under the License.
package source package source
import "fmt"
var store = map[string]Source{} var store = map[string]Source{}
// Register registers a Source under a given name. // Register registers a Source under a given name.
@ -29,10 +31,16 @@ func Lookup(name string) Source {
} }
// LookupMultiple returns multiple Sources given multiple names. // LookupMultiple returns multiple Sources given multiple names.
func LookupMultiple(names ...string) (sources []Source) { func LookupMultiple(names []string) ([]Source, error) {
sources := []Source{}
for _, name := range names { for _, name := range names {
sources = append(sources, Lookup(name)) source := Lookup(name)
if source == nil {
return nil, fmt.Errorf("%s source could not be identified", name)
}
sources = append(sources, source)
} }
return sources return sources, nil
} }

View File

@ -53,8 +53,10 @@ func testRegisterAndLookup(t *testing.T) {
// testLookupMultiple tests that Sources can be looked up by providing multiple names. // testLookupMultiple tests that Sources can be looked up by providing multiple names.
func testLookupMultiple(t *testing.T) { func testLookupMultiple(t *testing.T) {
for _, tc := range []struct { for _, tc := range []struct {
title string title string
givenAndExpected map[string]Source registered map[string]Source
names []string
expectError bool
}{ }{
{ {
"multiple registered sources are found by names", "multiple registered sources are found by names",
@ -62,24 +64,39 @@ func testLookupMultiple(t *testing.T) {
"foo": NewMockSource(nil), "foo": NewMockSource(nil),
"bar": NewMockSource(nil), "bar": NewMockSource(nil),
}, },
[]string{"foo", "bar"},
false,
},
{
"multiple registered sources, one source not registered",
map[string]Source{
"foo": NewMockSource(nil),
"bar": NewMockSource(nil),
},
[]string{"foo", "baz"},
true,
}, },
} { } {
t.Run(tc.title, func(t *testing.T) { t.Run(tc.title, func(t *testing.T) {
for k, v := range tc.givenAndExpected { for k, v := range tc.registered {
Register(k, v) Register(k, v)
} }
names, sources := []string{}, []Source{} lookup, err := LookupMultiple(tc.names)
for k, v := range tc.givenAndExpected { if !tc.expectError && err != nil {
names = append(names, k) t.Fatal(err)
sources = append(sources, v)
} }
lookup := LookupMultiple(names...) if tc.expectError {
if err == nil {
t.Fatal("look up should fail if source not registered")
}
t.Skip()
}
for i := range names { for i, name := range tc.names {
if lookup[i] != sources[i] { if lookup[i] != tc.registered[name] {
t.Errorf("expected %#v, got %#v", sources[i], lookup[i]) t.Errorf("expected %#v, got %#v", tc.registered[name], lookup[i])
} }
} }
}) })