From 076ae3dfe4ccbc2f92f667cbcc028e5e9feb8db7 Mon Sep 17 00:00:00 2001 From: Ole Markus With Date: Thu, 21 Jan 2021 20:11:31 +0100 Subject: [PATCH] Remove coredns dnsprovider --- dns-controller/cmd/dns-controller/BUILD.bazel | 1 - dns-controller/cmd/dns-controller/main.go | 13 +- dns-controller/docs/flags.md | 2 +- dns-controller/pkg/dns/BUILD.bazel | 1 - dns-controller/pkg/dns/dnscontroller.go | 85 +-- .../dnsprovider/providers/coredns/BUILD.bazel | 37 - .../dnsprovider/providers/coredns/coredns.go | 96 --- .../providers/coredns/coredns_test.go | 273 ------- .../providers/coredns/interface.go | 41 - .../providers/coredns/rrchangeset.go | 152 ---- .../dnsprovider/providers/coredns/rrset.go | 49 -- .../dnsprovider/providers/coredns/rrsets.go | 115 --- .../providers/coredns/stubs/BUILD.bazel | 9 - .../providers/coredns/stubs/corednsapi.go | 85 --- .../pkg/dnsprovider/providers/coredns/zone.go | 42 -- .../dnsprovider/providers/coredns/zones.go | 50 -- go.mod | 2 - go.sum | 2 - hack/.staticcheck_failures | 1 - protokube/cmd/protokube/BUILD.bazel | 1 - protokube/cmd/protokube/main.go | 11 +- vendor/github.com/coreos/go-semver/LICENSE | 202 ----- vendor/github.com/coreos/go-semver/NOTICE | 5 - .../coreos/go-semver/semver/BUILD.bazel | 12 - .../coreos/go-semver/semver/semver.go | 296 -------- .../coreos/go-semver/semver/sort.go | 38 - vendor/github.com/miekg/coredns/LICENSE | 201 ----- .../coredns/middleware/etcd/msg/BUILD.bazel | 13 - .../miekg/coredns/middleware/etcd/msg/path.go | 46 -- .../coredns/middleware/etcd/msg/service.go | 203 ----- vendor/go.etcd.io/etcd/LICENSE | 202 ----- vendor/go.etcd.io/etcd/NOTICE | 5 - vendor/go.etcd.io/etcd/client/BUILD.bazel | 30 - vendor/go.etcd.io/etcd/client/README.md | 112 --- vendor/go.etcd.io/etcd/client/auth_role.go | 236 ------ vendor/go.etcd.io/etcd/client/auth_user.go | 319 -------- vendor/go.etcd.io/etcd/client/cancelreq.go | 18 - vendor/go.etcd.io/etcd/client/client.go | 710 ------------------ .../go.etcd.io/etcd/client/cluster_error.go | 37 - vendor/go.etcd.io/etcd/client/curl.go | 70 -- vendor/go.etcd.io/etcd/client/discover.go | 40 - vendor/go.etcd.io/etcd/client/doc.go | 73 -- vendor/go.etcd.io/etcd/client/json.go | 72 -- vendor/go.etcd.io/etcd/client/keys.go | 679 ----------------- vendor/go.etcd.io/etcd/client/members.go | 303 -------- vendor/go.etcd.io/etcd/client/util.go | 53 -- .../go.etcd.io/etcd/pkg/pathutil/BUILD.bazel | 9 - vendor/go.etcd.io/etcd/pkg/pathutil/path.go | 31 - vendor/go.etcd.io/etcd/pkg/srv/BUILD.bazel | 10 - vendor/go.etcd.io/etcd/pkg/srv/srv.go | 142 ---- vendor/go.etcd.io/etcd/pkg/types/BUILD.bazel | 16 - vendor/go.etcd.io/etcd/pkg/types/doc.go | 17 - vendor/go.etcd.io/etcd/pkg/types/id.go | 39 - vendor/go.etcd.io/etcd/pkg/types/set.go | 195 ----- vendor/go.etcd.io/etcd/pkg/types/slice.go | 22 - vendor/go.etcd.io/etcd/pkg/types/urls.go | 82 -- vendor/go.etcd.io/etcd/pkg/types/urlsmap.go | 107 --- vendor/go.etcd.io/etcd/version/BUILD.bazel | 10 - vendor/go.etcd.io/etcd/version/version.go | 56 -- vendor/modules.txt | 12 - 60 files changed, 23 insertions(+), 5768 deletions(-) delete mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/BUILD.bazel delete mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/coredns.go delete mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/coredns_test.go delete mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/interface.go delete mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/rrchangeset.go delete mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/rrset.go delete mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/rrsets.go delete mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/stubs/BUILD.bazel delete mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/stubs/corednsapi.go delete mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/zone.go delete mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/zones.go delete mode 100644 vendor/github.com/coreos/go-semver/LICENSE delete mode 100644 vendor/github.com/coreos/go-semver/NOTICE delete mode 100644 vendor/github.com/coreos/go-semver/semver/BUILD.bazel delete mode 100644 vendor/github.com/coreos/go-semver/semver/semver.go delete mode 100644 vendor/github.com/coreos/go-semver/semver/sort.go delete mode 100644 vendor/github.com/miekg/coredns/LICENSE delete mode 100644 vendor/github.com/miekg/coredns/middleware/etcd/msg/BUILD.bazel delete mode 100644 vendor/github.com/miekg/coredns/middleware/etcd/msg/path.go delete mode 100644 vendor/github.com/miekg/coredns/middleware/etcd/msg/service.go delete mode 100644 vendor/go.etcd.io/etcd/LICENSE delete mode 100644 vendor/go.etcd.io/etcd/NOTICE delete mode 100644 vendor/go.etcd.io/etcd/client/BUILD.bazel delete mode 100644 vendor/go.etcd.io/etcd/client/README.md delete mode 100644 vendor/go.etcd.io/etcd/client/auth_role.go delete mode 100644 vendor/go.etcd.io/etcd/client/auth_user.go delete mode 100644 vendor/go.etcd.io/etcd/client/cancelreq.go delete mode 100644 vendor/go.etcd.io/etcd/client/client.go delete mode 100644 vendor/go.etcd.io/etcd/client/cluster_error.go delete mode 100644 vendor/go.etcd.io/etcd/client/curl.go delete mode 100644 vendor/go.etcd.io/etcd/client/discover.go delete mode 100644 vendor/go.etcd.io/etcd/client/doc.go delete mode 100644 vendor/go.etcd.io/etcd/client/json.go delete mode 100644 vendor/go.etcd.io/etcd/client/keys.go delete mode 100644 vendor/go.etcd.io/etcd/client/members.go delete mode 100644 vendor/go.etcd.io/etcd/client/util.go delete mode 100644 vendor/go.etcd.io/etcd/pkg/pathutil/BUILD.bazel delete mode 100644 vendor/go.etcd.io/etcd/pkg/pathutil/path.go delete mode 100644 vendor/go.etcd.io/etcd/pkg/srv/BUILD.bazel delete mode 100644 vendor/go.etcd.io/etcd/pkg/srv/srv.go delete mode 100644 vendor/go.etcd.io/etcd/pkg/types/BUILD.bazel delete mode 100644 vendor/go.etcd.io/etcd/pkg/types/doc.go delete mode 100644 vendor/go.etcd.io/etcd/pkg/types/id.go delete mode 100644 vendor/go.etcd.io/etcd/pkg/types/set.go delete mode 100644 vendor/go.etcd.io/etcd/pkg/types/slice.go delete mode 100644 vendor/go.etcd.io/etcd/pkg/types/urls.go delete mode 100644 vendor/go.etcd.io/etcd/pkg/types/urlsmap.go delete mode 100644 vendor/go.etcd.io/etcd/version/BUILD.bazel delete mode 100644 vendor/go.etcd.io/etcd/version/version.go diff --git a/dns-controller/cmd/dns-controller/BUILD.bazel b/dns-controller/cmd/dns-controller/BUILD.bazel index cdc12a10b4dec..77213fdbb5d2f 100644 --- a/dns-controller/cmd/dns-controller/BUILD.bazel +++ b/dns-controller/cmd/dns-controller/BUILD.bazel @@ -12,7 +12,6 @@ go_library( "//dns-controller/pkg/watchers:go_default_library", "//dnsprovider/pkg/dnsprovider:go_default_library", "//dnsprovider/pkg/dnsprovider/providers/aws/route53:go_default_library", - "//dnsprovider/pkg/dnsprovider/providers/coredns:go_default_library", "//dnsprovider/pkg/dnsprovider/providers/google/clouddns:go_default_library", "//pkg/resources/digitalocean/dns:go_default_library", "//pkg/wellknownports:go_default_library", diff --git a/dns-controller/cmd/dns-controller/main.go b/dns-controller/cmd/dns-controller/main.go index a3ae9991232ec..bc5ad5436bd7d 100644 --- a/dns-controller/cmd/dns-controller/main.go +++ b/dns-controller/cmd/dns-controller/main.go @@ -17,14 +17,12 @@ limitations under the License. package main import ( - "bytes" "flag" "fmt" "io" "log" "net/http" "os" - "strings" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/spf13/pflag" @@ -37,7 +35,6 @@ import ( "k8s.io/kops/dns-controller/pkg/watchers" "k8s.io/kops/dnsprovider/pkg/dnsprovider" "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/aws/route53" - k8scoredns "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/coredns" _ "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns" _ "k8s.io/kops/pkg/resources/digitalocean/dns" "k8s.io/kops/pkg/wellknownports" @@ -68,7 +65,7 @@ func main() { flags.BoolVar(&watchIngress, "watch-ingress", true, "Configure hostnames found in ingress resources") flags.StringSliceVar(&gossipSeeds, "gossip-seed", gossipSeeds, "If set, will enable gossip zones and seed using the provided addresses") flags.StringSliceVarP(&zones, "zone", "z", []string{}, "Configure permitted zones and their mappings") - flags.StringVar(&dnsProviderID, "dns", "aws-route53", "DNS provider we should use (aws-route53, google-clouddns, digitalocean, coredns, gossip)") + flags.StringVar(&dnsProviderID, "dns", "aws-route53", "DNS provider we should use (aws-route53, google-clouddns, digitalocean, gossip)") flag.StringVar(&gossipProtocol, "gossip-protocol", "mesh", "mesh/memberlist") flags.StringVar(&gossipListen, "gossip-listen", fmt.Sprintf("0.0.0.0:%d", wellknownports.DNSControllerGossipWeaveMesh), "The address on which to listen if gossip is enabled") flags.StringVar(&gossipSecret, "gossip-secret", gossipSecret, "Secret to use to secure gossip") @@ -115,13 +112,7 @@ func main() { var dnsProviders []dnsprovider.Interface if dnsProviderID != "gossip" { var file io.Reader - if dnsProviderID == k8scoredns.ProviderName { - var lines []string - lines = append(lines, "etcd-endpoints = "+dnsServer) - lines = append(lines, "zones = "+zones[0]) - config := "[global]\n" + strings.Join(lines, "\n") + "\n" - file = bytes.NewReader([]byte(config)) - } + dnsProvider, err := dnsprovider.GetDnsProvider(dnsProviderID, file) if err != nil { klog.Errorf("Error initializing DNS provider %q: %v", dnsProviderID, err) diff --git a/dns-controller/docs/flags.md b/dns-controller/docs/flags.md index dc688148a7a03..16a8207ff6225 100644 --- a/dns-controller/docs/flags.md +++ b/dns-controller/docs/flags.md @@ -3,7 +3,7 @@ The `dns-controller` executable takes the following command line options: * `--dns` - DNS provider we should use. Valid options are: `aws-route53`, - `google-clouddns` or `coredns`. + `google-clouddns`, `gossip`, and `digitalocean`. * `--gossip-listen` - The address on which to listen if gossip is enabled. * `--gossip-seed` - If set, will enable gossip zones and seed using the provided address. diff --git a/dns-controller/pkg/dns/BUILD.bazel b/dns-controller/pkg/dns/BUILD.bazel index d211fb63b6fdb..9eb5fdea1f96a 100644 --- a/dns-controller/pkg/dns/BUILD.bazel +++ b/dns-controller/pkg/dns/BUILD.bazel @@ -14,7 +14,6 @@ go_library( deps = [ "//dns-controller/pkg/util:go_default_library", "//dnsprovider/pkg/dnsprovider:go_default_library", - "//dnsprovider/pkg/dnsprovider/providers/coredns:go_default_library", "//dnsprovider/pkg/dnsprovider/rrstype:go_default_library", "//vendor/k8s.io/klog/v2:go_default_library", ], diff --git a/dns-controller/pkg/dns/dnscontroller.go b/dns-controller/pkg/dns/dnscontroller.go index 5ac673c71fca6..f1d44ac06246c 100644 --- a/dns-controller/pkg/dns/dnscontroller.go +++ b/dns-controller/pkg/dns/dnscontroller.go @@ -30,7 +30,6 @@ import ( "k8s.io/kops/dns-controller/pkg/util" "k8s.io/kops/dnsprovider/pkg/dnsprovider" - k8scoredns "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/coredns" "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" ) @@ -492,33 +491,6 @@ func (o *dnsOp) deleteRecords(k recordKey) error { return fmt.Errorf("no suitable zone found for %q", fqdn) } - // TODO: work-around before ResourceRecordSets.List() is implemented for CoreDNS - if isCoreDNSZone(zone) { - rrsProvider, ok := zone.ResourceRecordSets() - if !ok { - return fmt.Errorf("zone does not support resource records %q", zone.Name()) - } - - dnsRecords, err := rrsProvider.Get(fqdn) - if err != nil { - return fmt.Errorf("Failed to get DNS record %s with error: %v", fqdn, err) - } - - for _, dnsRecord := range dnsRecords { - if string(dnsRecord.Type()) == string(k.RecordType) { - cs, err := o.getChangeset(zone) - if err != nil { - return err - } - - klog.V(2).Infof("Deleting resource record %s %s", fqdn, k.RecordType) - cs.Remove(dnsRecord) - } - } - - return nil - } - // when DNS provider is aws-route53 or google-clouddns rrs, err := o.listRecords(zone) if err != nil { @@ -548,11 +520,6 @@ func (o *dnsOp) deleteRecords(k recordKey) error { return nil } -func isCoreDNSZone(zone dnsprovider.Zone) bool { - _, ok := zone.(k8scoredns.Zone) - return ok -} - func FixWildcards(s string) string { return strings.Replace(s, "\\052", "*", 1) } @@ -572,44 +539,30 @@ func (o *dnsOp) updateRecords(k recordKey, newRecords []string, ttl int64) error } var existing dnsprovider.ResourceRecordSet - // TODO: work-around before ResourceRecordSets.List() is implemented for CoreDNS - if isCoreDNSZone(zone) { - dnsRecords, err := rrsProvider.Get(fqdn) - if err != nil { - return fmt.Errorf("Failed to get DNS record %s with error: %v", fqdn, err) - } - for _, dnsRecord := range dnsRecords { - if string(dnsRecord.Type()) == string(k.RecordType) { - klog.V(8).Infof("Found matching record: %s %s", k.RecordType, fqdn) - existing = dnsRecord - } + // when DNS provider is aws-route53 or google-clouddns + rrs, err := o.listRecords(zone) + if err != nil { + return fmt.Errorf("error querying resource records for zone %q: %v", zone.Name(), err) + } + + for _, rr := range rrs { + rrName := EnsureDotSuffix(FixWildcards(rr.Name())) + if rrName != fqdn { + klog.V(8).Infof("Skipping record %q (name != %s)", rrName, fqdn) + continue } - } else { - // when DNS provider is aws-route53 or google-clouddns - rrs, err := o.listRecords(zone) - if err != nil { - return fmt.Errorf("error querying resource records for zone %q: %v", zone.Name(), err) + if string(rr.Type()) != string(k.RecordType) { + klog.V(8).Infof("Skipping record %q (type %s != %s)", rrName, rr.Type(), k.RecordType) + continue } - for _, rr := range rrs { - rrName := EnsureDotSuffix(FixWildcards(rr.Name())) - if rrName != fqdn { - klog.V(8).Infof("Skipping record %q (name != %s)", rrName, fqdn) - continue - } - if string(rr.Type()) != string(k.RecordType) { - klog.V(8).Infof("Skipping record %q (type %s != %s)", rrName, rr.Type(), k.RecordType) - continue - } - - if existing != nil { - klog.Warningf("Found multiple matching records: %v and %v", existing, rr) - } else { - klog.V(8).Infof("Found matching record: %s %s", k.RecordType, rrName) - } - existing = rr + if existing != nil { + klog.Warningf("Found multiple matching records: %v and %v", existing, rr) + } else { + klog.V(8).Infof("Found matching record: %s %s", k.RecordType, rrName) } + existing = rr } cs, err := o.getChangeset(zone) diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/BUILD.bazel b/dnsprovider/pkg/dnsprovider/providers/coredns/BUILD.bazel deleted file mode 100644 index af150f6aa4a16..0000000000000 --- a/dnsprovider/pkg/dnsprovider/providers/coredns/BUILD.bazel +++ /dev/null @@ -1,37 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") - -go_library( - name = "go_default_library", - srcs = [ - "coredns.go", - "interface.go", - "rrchangeset.go", - "rrset.go", - "rrsets.go", - "zone.go", - "zones.go", - ], - importpath = "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/coredns", - visibility = ["//visibility:public"], - deps = [ - "//dnsprovider/pkg/dnsprovider:go_default_library", - "//dnsprovider/pkg/dnsprovider/providers/coredns/stubs:go_default_library", - "//dnsprovider/pkg/dnsprovider/rrstype:go_default_library", - "//vendor/github.com/miekg/coredns/middleware/etcd/msg:go_default_library", - "//vendor/go.etcd.io/etcd/client:go_default_library", - "//vendor/gopkg.in/gcfg.v1:go_default_library", - "//vendor/k8s.io/klog/v2:go_default_library", - ], -) - -go_test( - name = "go_default_test", - srcs = ["coredns_test.go"], - embed = [":go_default_library"], - deps = [ - "//dnsprovider/pkg/dnsprovider:go_default_library", - "//dnsprovider/pkg/dnsprovider/providers/coredns/stubs:go_default_library", - "//dnsprovider/pkg/dnsprovider/rrstype:go_default_library", - "//dnsprovider/pkg/dnsprovider/tests:go_default_library", - ], -) diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/coredns.go b/dnsprovider/pkg/dnsprovider/providers/coredns/coredns.go deleted file mode 100644 index 64989c0608d1c..0000000000000 --- a/dnsprovider/pkg/dnsprovider/providers/coredns/coredns.go +++ /dev/null @@ -1,96 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package coredns is the implementation of pkg/dnsprovider interface for CoreDNS -package coredns - -import ( - "fmt" - "io" - "strconv" - "strings" - - etcdc "go.etcd.io/etcd/client" - gcfg "gopkg.in/gcfg.v1" - "k8s.io/klog/v2" - "k8s.io/kops/dnsprovider/pkg/dnsprovider" -) - -// "coredns" should be used to use this DNS provider -const ( - ProviderName = "coredns" -) - -// Config to override defaults -type Config struct { - Global struct { - EtcdEndpoints string `gcfg:"etcd-endpoints"` - DNSZones string `gcfg:"zones"` - CoreDNSEndpoints string `gcfg:"coredns-endpoints"` - } -} - -func init() { - dnsprovider.RegisterDNSProvider(ProviderName, func(config io.Reader) (dnsprovider.Interface, error) { - return newCoreDNSProviderInterface(config) - }) -} - -// newCoreDnsProviderInterface creates a new instance of an CoreDNS DNS Interface. -func newCoreDNSProviderInterface(config io.Reader) (*Interface, error) { - etcdEndpoints := "http://federation-dns-server-etcd:2379" - etcdPathPrefix := "skydns" - dnsZones := "" - - // Possibly override defaults with config below - if config != nil { - var cfg Config - if err := gcfg.ReadInto(&cfg, config); err != nil { - klog.Errorf("Couldn't read config: %v", err) - return nil, err - } - etcdEndpoints = cfg.Global.EtcdEndpoints - dnsZones = cfg.Global.DNSZones - } - klog.Infof("Using CoreDNS DNS provider") - - if dnsZones == "" { - return nil, fmt.Errorf("need to provide at least one DNS Zone") - } - - etcdCfg := etcdc.Config{ - Endpoints: strings.Split(etcdEndpoints, ","), - Transport: etcdc.DefaultTransport, - } - - c, err := etcdc.New(etcdCfg) - if err != nil { - return nil, fmt.Errorf("create etcd client from the config failed") - } - etcdKeysAPI := etcdc.NewKeysAPI(c) - - intf := newInterfaceWithStub(etcdKeysAPI) - intf.etcdPathPrefix = etcdPathPrefix - zoneList := strings.Split(dnsZones, ",") - - intf.zones = Zones{intf: intf} - for index, zoneName := range zoneList { - zone := Zone{domain: zoneName, id: strconv.Itoa(index), zones: &intf.zones} - intf.zones.zoneList = append(intf.zones.zoneList, zone) - } - - return intf, nil -} diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/coredns_test.go b/dnsprovider/pkg/dnsprovider/providers/coredns/coredns_test.go deleted file mode 100644 index 824cb861c7689..0000000000000 --- a/dnsprovider/pkg/dnsprovider/providers/coredns/coredns_test.go +++ /dev/null @@ -1,273 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package coredns - -import ( - "context" - "flag" - "fmt" - "os" - "strconv" - "strings" - "testing" - - "k8s.io/kops/dnsprovider/pkg/dnsprovider" - corednstesting "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/coredns/stubs" - "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" - "k8s.io/kops/dnsprovider/pkg/dnsprovider/tests" -) - -func newTestInterface() (dnsprovider.Interface, error) { - // Use this to test the real cloud service. - // return dnsprovider.GetDnsProvider(ProviderName, strings.NewReader("\n[global]\nproject-id = federation0-cluster00")) - return newFakeInterface() // Use this to stub out the entire cloud service -} - -func newFakeInterface() (dnsprovider.Interface, error) { - service := corednstesting.NewEtcdKeysAPIStub() - intf := newInterfaceWithStub(service) - intf.etcdPathPrefix = "skydns" - - zoneList := strings.Split("example.com,federation.io", ",") - intf.zones = Zones{intf: intf} - for index, zoneName := range zoneList { - zone := Zone{domain: zoneName, id: strconv.Itoa(index), zones: &intf.zones} - intf.zones.zoneList = append(intf.zones.zoneList, zone) - } - - return intf, nil -} - -var intf dnsprovider.Interface - -func TestMain(m *testing.M) { - fmt.Printf("Parsing flags.\n") - flag.Parse() - var err error - fmt.Printf("Getting new test interface.\n") - intf, err = newTestInterface() - if err != nil { - fmt.Printf("Error creating interface: %v", err) - os.Exit(1) - } - fmt.Printf("Running tests...\n") - os.Exit(m.Run()) -} - -// zones returns the zones interface for the configured dns provider account/project, -// or fails if it can't be found -func zones(t *testing.T) dnsprovider.Zones { - zonesInterface, supported := intf.Zones() - if !supported { - t.Fatalf("Zones interface not supported by interface %v", intf) - } else { - t.Logf("Got zones %v\n", zonesInterface) - } - return zonesInterface -} - -// firstZone returns the first zone for the configured dns provider account/project, -// or fails if it can't be found -func firstZone(t *testing.T) dnsprovider.Zone { - t.Logf("Getting zones") - z := zones(t) - zones, err := z.List() - if err != nil { - t.Fatalf("Failed to list zones: %v", err) - } else { - t.Logf("Got zone list: %v\n", zones) - } - if len(zones) < 1 { - t.Fatalf("Zone listing returned %d, expected >= %d", len(zones), 1) - } else { - t.Logf("Got at least 1 zone in list:%v\n", zones[0]) - } - return zones[0] -} - -/* rrs returns the ResourceRecordSets interface for a given zone */ -func rrs(t *testing.T, zone dnsprovider.Zone) (r dnsprovider.ResourceRecordSets) { - rrsets, supported := zone.ResourceRecordSets() - if !supported { - t.Fatalf("ResourceRecordSets interface not supported by zone %v", zone) - return r - } - return rrsets -} - -func getRrOrFail(t *testing.T, rrsets dnsprovider.ResourceRecordSets, name string) []dnsprovider.ResourceRecordSet { - rrsetList, err := rrsets.Get(name) - if err != nil { - t.Fatalf("Failed to get recordset: %v", err) - } else if len(rrsetList) == 0 { - t.Logf("Did not Get recordset: %v", name) - } else { - t.Logf("Got recordsets: %v", rrsetList) - } - return rrsetList -} - -func getExampleRrs(zone dnsprovider.Zone) dnsprovider.ResourceRecordSet { - rrsets, _ := zone.ResourceRecordSets() - return rrsets.New("www11."+zone.Name(), []string{"10.10.10.10", "169.20.20.20"}, 180, rrstype.A) -} - -func addRrsetOrFail(ctx context.Context, t *testing.T, rrsets dnsprovider.ResourceRecordSets, rrset dnsprovider.ResourceRecordSet) { - err := rrsets.StartChangeset().Add(rrset).Apply(ctx) - if err != nil { - t.Fatalf("Failed to add recordsets: %v", err) - } -} - -/* TestZonesList verifies that listing of zones succeeds */ -func TestZonesList(t *testing.T) { - firstZone(t) -} - -/* TestZonesID verifies that the id of the zone is unique */ -func TestZonesID(t *testing.T) { - zone := firstZone(t) - - zoneID := zone.ID() - if zoneID != "0" { - t.Fatalf("Unexpected zone id: %q", zoneID) - } -} - -/* TestResourceRecordSetsGet verifies that getting of RRS succeeds */ -func TestResourceRecordSetsGet(t *testing.T) { - getRrOrFail(t, rrs(t, firstZone(t)), "example.com") -} - -/* TestResourceRecordSetsAddSuccess verifies that addition of a valid RRS succeeds */ -func TestResourceRecordSetsAddSuccess(t *testing.T) { - ctx := context.Background() - - zone := firstZone(t) - sets := rrs(t, zone) - set := getExampleRrs(zone) - addRrsetOrFail(ctx, t, sets, set) - defer sets.StartChangeset().Remove(set).Apply(ctx) - t.Logf("Successfully added resource record set: %v", set) - if sets.Zone().ID() != zone.ID() { - t.Errorf("Zone for rrset does not match expected") - } -} - -/* TestResourceRecordSetsAdditionVisible verifies that added RRS is visible after addition */ -func TestResourceRecordSetsAdditionVisible(t *testing.T) { - ctx := context.Background() - - zone := firstZone(t) - sets := rrs(t, zone) - rrset := getExampleRrs(zone) - addRrsetOrFail(ctx, t, sets, rrset) - defer sets.StartChangeset().Remove(rrset).Apply(ctx) - t.Logf("Successfully added resource record set: %v", rrset) - - record := getRrOrFail(t, sets, rrset.Name()) - if record == nil { - t.Errorf("Failed to find added resource record set %s", rrset.Name()) - } -} - -/* TestResourceRecordSetsAddDuplicateFailure verifies that addition of a duplicate RRS fails */ -func TestResourceRecordSetsAddDuplicateFailure(t *testing.T) { - ctx := context.Background() - - zone := firstZone(t) - sets := rrs(t, zone) - rrset := getExampleRrs(zone) - addRrsetOrFail(ctx, t, sets, rrset) - defer sets.StartChangeset().Remove(rrset).Apply(ctx) - t.Logf("Successfully added resource record set: %v", rrset) - // Try to add it again, and verify that the call fails. - err := sets.StartChangeset().Add(rrset).Apply(ctx) - if err == nil { - defer sets.StartChangeset().Remove(rrset).Apply(ctx) - t.Errorf("Should have failed to add duplicate resource record %v, but succeeded instead.", rrset) - } else { - t.Logf("Correctly failed to add duplicate resource record %v: %v", rrset, err) - } -} - -/* TestResourceRecordSetsRemove verifies that the removal of an existing RRS succeeds */ -func TestResourceRecordSetsRemove(t *testing.T) { - ctx := context.Background() - - zone := firstZone(t) - sets := rrs(t, zone) - rrset := getExampleRrs(zone) - addRrsetOrFail(ctx, t, sets, rrset) - err := sets.StartChangeset().Remove(rrset).Apply(ctx) - if err != nil { - // Try again to clean up. - defer sets.StartChangeset().Remove(rrset).Apply(ctx) - t.Errorf("Failed to remove resource record set %v after adding", rrset) - } else { - t.Logf("Successfully removed resource set %v after adding", rrset) - } -} - -/* TestResourceRecordSetsRemoveGone verifies that a removed RRS no longer exists */ -func TestResourceRecordSetsRemoveGone(t *testing.T) { - ctx := context.Background() - - zone := firstZone(t) - sets := rrs(t, zone) - rrset := getExampleRrs(zone) - addRrsetOrFail(ctx, t, sets, rrset) - err := sets.StartChangeset().Remove(rrset).Apply(ctx) - if err != nil { - // Try again to clean up. - defer sets.StartChangeset().Remove(rrset).Apply(ctx) - t.Errorf("Failed to remove resource record set %v after adding", rrset) - } else { - t.Logf("Successfully removed resource set %v after adding", rrset) - } - - record := getRrOrFail(t, sets, rrset.Name()) - if record != nil { - t.Errorf("Deleted resource record set %v is still present", rrset) - } -} - -/* TestResourceRecordSetsReplace verifies that replacing an RRS works */ -func TestResourceRecordSetsReplace(t *testing.T) { - zone := firstZone(t) - tests.CommonTestResourceRecordSetsReplace(t, zone) -} - -/* TestResourceRecordSetsReplaceAll verifies that we can remove an RRS and create one with a different name */ -func TestResourceRecordSetsReplaceAll(t *testing.T) { - zone := firstZone(t) - tests.CommonTestResourceRecordSetsReplaceAll(t, zone) -} - -/* TestResourceRecordSetsDifferentTypes verifies that we can add records with same name, but different types */ -func TestResourceRecordSetsDifferentTypes(t *testing.T) { - zone := firstZone(t) - tests.CommonTestResourceRecordSetsDifferentTypes(t, zone) -} - -// TestContract verifies the general interface contract -func TestContract(t *testing.T) { - zone := firstZone(t) - sets := rrs(t, zone) - - tests.TestContract(t, sets) -} diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/interface.go b/dnsprovider/pkg/dnsprovider/providers/coredns/interface.go deleted file mode 100644 index 30ec511bc5c91..0000000000000 --- a/dnsprovider/pkg/dnsprovider/providers/coredns/interface.go +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package coredns - -import ( - "k8s.io/kops/dnsprovider/pkg/dnsprovider" - "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/coredns/stubs" -) - -// Compile time check for interface adherence -var _ dnsprovider.Interface = Interface{} - -type Interface struct { - etcdKeysAPI stubs.EtcdKeysAPI - etcdPathPrefix string - zones Zones -} - -// newInterfaceWithStub facilitates stubbing out the underlying etcd -// library for testing purposes. It returns an provider-independent interface. -func newInterfaceWithStub(etcdKeysAPI stubs.EtcdKeysAPI) *Interface { - return &Interface{etcdKeysAPI: etcdKeysAPI} -} - -func (i Interface) Zones() (dnsprovider.Zones, bool) { - return i.zones, true -} diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/rrchangeset.go b/dnsprovider/pkg/dnsprovider/providers/coredns/rrchangeset.go deleted file mode 100644 index b998347b71b9e..0000000000000 --- a/dnsprovider/pkg/dnsprovider/providers/coredns/rrchangeset.go +++ /dev/null @@ -1,152 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package coredns - -import ( - "context" - "encoding/json" - "fmt" - "hash/fnv" - - dnsmsg "github.com/miekg/coredns/middleware/etcd/msg" - etcdc "go.etcd.io/etcd/client" - "k8s.io/kops/dnsprovider/pkg/dnsprovider" -) - -// Compile time check for interface adherence -var _ dnsprovider.ResourceRecordChangeset = &ResourceRecordChangeset{} - -type ChangeSetType string - -const ( - ADDITION = ChangeSetType("ADDITION") - DELETION = ChangeSetType("DELETION") - UPSERT = ChangeSetType("UPSERT") -) - -type ChangeSet struct { - cstype ChangeSetType - rrset dnsprovider.ResourceRecordSet -} - -type ResourceRecordChangeset struct { - zone *Zone - rrsets *ResourceRecordSets - - changeset []ChangeSet -} - -func (c *ResourceRecordChangeset) Add(rrset dnsprovider.ResourceRecordSet) dnsprovider.ResourceRecordChangeset { - c.changeset = append(c.changeset, ChangeSet{cstype: ADDITION, rrset: rrset}) - return c -} - -func (c *ResourceRecordChangeset) Remove(rrset dnsprovider.ResourceRecordSet) dnsprovider.ResourceRecordChangeset { - c.changeset = append(c.changeset, ChangeSet{cstype: DELETION, rrset: rrset}) - return c -} - -func (c *ResourceRecordChangeset) IsEmpty() bool { - return len(c.changeset) == 0 -} - -func (c *ResourceRecordChangeset) Upsert(rrset dnsprovider.ResourceRecordSet) dnsprovider.ResourceRecordChangeset { - c.changeset = append(c.changeset, ChangeSet{cstype: UPSERT, rrset: rrset}) - return c -} - -func (c *ResourceRecordChangeset) Apply(ctx context.Context) error { - // Empty changesets should be a relatively quick no-op - if c.IsEmpty() { - return nil - } - - etcdPathPrefix := c.zone.zones.intf.etcdPathPrefix - getOpts := &etcdc.GetOptions{} - setOpts := &etcdc.SetOptions{} - deleteOpts := &etcdc.DeleteOptions{ - Recursive: true, - } - - for _, changeset := range c.changeset { - switch changeset.cstype { - case ADDITION, UPSERT: - checkNotExists := changeset.cstype == ADDITION - - // TODO: I think the semantics of the other providers are different; they operate at the record level, not the individual rrdata level - // In other words: we should insert/replace all the records for the key - for _, rrdata := range changeset.rrset.Rrdatas() { - b, err := json.Marshal(&dnsmsg.Service{Host: rrdata, TTL: uint32(changeset.rrset.Ttl()), Group: changeset.rrset.Name()}) - if err != nil { - return err - } - recordValue := string(b) - recordLabel := getHash(rrdata) - recordKey := buildDNSNameString(changeset.rrset.Name(), recordLabel) - - if checkNotExists { - response, err := c.zone.zones.intf.etcdKeysAPI.Get(ctx, dnsmsg.Path(recordKey, etcdPathPrefix), getOpts) - if err == nil && response != nil { - return fmt.Errorf("key already exist, key: %v", recordKey) - } - } - - _, err = c.zone.zones.intf.etcdKeysAPI.Set(ctx, dnsmsg.Path(recordKey, etcdPathPrefix), recordValue, setOpts) - if err != nil { - return err - } - } - - case DELETION: - // TODO: I think the semantics of the other providers are different; they operate at the record level, not the individual rrdata level - // In other words: we should delete all the records for the key, only if it matches exactly - for _, rrdata := range changeset.rrset.Rrdatas() { - recordLabel := getHash(rrdata) - recordKey := buildDNSNameString(changeset.rrset.Name(), recordLabel) - _, err := c.zone.zones.intf.etcdKeysAPI.Delete(ctx, dnsmsg.Path(recordKey, etcdPathPrefix), deleteOpts) - if err != nil { - return err - } - } - // TODO: We need to cleanup empty dirs in etcd - } - } - return nil -} - -// ResourceRecordSets returns the parent ResourceRecordSets -func (c *ResourceRecordChangeset) ResourceRecordSets() dnsprovider.ResourceRecordSets { - return c.rrsets -} - -func getHash(text string) string { - h := fnv.New32a() - h.Write([]byte(text)) - return fmt.Sprintf("%x", h.Sum32()) -} - -func buildDNSNameString(labels ...string) string { - var res string - for _, label := range labels { - if res == "" { - res = label - } else { - res = fmt.Sprintf("%s.%s", label, res) - } - } - return res -} diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/rrset.go b/dnsprovider/pkg/dnsprovider/providers/coredns/rrset.go deleted file mode 100644 index 62bf2567fecb1..0000000000000 --- a/dnsprovider/pkg/dnsprovider/providers/coredns/rrset.go +++ /dev/null @@ -1,49 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package coredns - -import ( - "k8s.io/kops/dnsprovider/pkg/dnsprovider" - "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" -) - -// Compile time check for interface adherence -var _ dnsprovider.ResourceRecordSet = ResourceRecordSet{} - -type ResourceRecordSet struct { - name string - rrdatas []string - ttl int64 - rrsType rrstype.RrsType - rrsets *ResourceRecordSets -} - -func (rrset ResourceRecordSet) Name() string { - return rrset.name -} - -func (rrset ResourceRecordSet) Rrdatas() []string { - return rrset.rrdatas -} - -func (rrset ResourceRecordSet) Ttl() int64 { - return rrset.ttl -} - -func (rrset ResourceRecordSet) Type() rrstype.RrsType { - return rrset.rrsType -} diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/rrsets.go b/dnsprovider/pkg/dnsprovider/providers/coredns/rrsets.go deleted file mode 100644 index c30510ab832a5..0000000000000 --- a/dnsprovider/pkg/dnsprovider/providers/coredns/rrsets.go +++ /dev/null @@ -1,115 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package coredns - -import ( - "context" - "encoding/json" - "fmt" - "net" - - dnsmsg "github.com/miekg/coredns/middleware/etcd/msg" - etcdc "go.etcd.io/etcd/client" - "k8s.io/klog/v2" - "k8s.io/kops/dnsprovider/pkg/dnsprovider" - "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" -) - -// Compile time check for interface adherence -var _ dnsprovider.ResourceRecordSets = ResourceRecordSets{} - -type ResourceRecordSets struct { - zone *Zone -} - -func (rrsets ResourceRecordSets) List() ([]dnsprovider.ResourceRecordSet, error) { - var list []dnsprovider.ResourceRecordSet - return list, fmt.Errorf("OperationNotSupported") -} - -func (rrsets ResourceRecordSets) Get(name string) ([]dnsprovider.ResourceRecordSet, error) { - getOpts := &etcdc.GetOptions{ - Recursive: true, - } - etcdPathPrefix := rrsets.zone.zones.intf.etcdPathPrefix - response, err := rrsets.zone.zones.intf.etcdKeysAPI.Get(context.Background(), dnsmsg.Path(name, etcdPathPrefix), getOpts) - if err != nil { - if etcdc.IsKeyNotFound(err) { - klog.V(2).Infof("Subdomain %q does not exist", name) - return nil, nil - } - return nil, fmt.Errorf("failed to get service from etcd, err: %v", err) - } - if emptyResponse(response) { - klog.V(2).Infof("Subdomain %q does not exist in etcd", name) - return nil, nil - } - - var list []dnsprovider.ResourceRecordSet - - for _, node := range response.Node.Nodes { - service := dnsmsg.Service{} - err = json.Unmarshal([]byte(node.Value), &service) - if err != nil { - return nil, fmt.Errorf("failed to unmarshall json data, err: %v", err) - } - - rrset := ResourceRecordSet{name: name, rrdatas: []string{}, rrsets: &rrsets} - ip := net.ParseIP(service.Host) - switch { - case ip == nil: - rrset.rrsType = rrstype.CNAME - case ip.To4() != nil: - rrset.rrsType = rrstype.A - case ip.To16() != nil: - rrset.rrsType = rrstype.AAAA - default: - // Cannot occur - } - rrset.rrdatas = append(rrset.rrdatas, service.Host) - rrset.ttl = int64(service.TTL) - list = append(list, rrset) - } - - return list, nil -} - -func (rrsets ResourceRecordSets) StartChangeset() dnsprovider.ResourceRecordChangeset { - return &ResourceRecordChangeset{ - zone: rrsets.zone, - rrsets: &rrsets, - } -} - -func (rrsets ResourceRecordSets) New(name string, rrdatas []string, ttl int64, rrsType rrstype.RrsType) dnsprovider.ResourceRecordSet { - return ResourceRecordSet{ - name: name, - rrdatas: rrdatas, - ttl: ttl, - rrsType: rrsType, - rrsets: &rrsets, - } -} - -// Zone returns the parent zone -func (rrset ResourceRecordSets) Zone() dnsprovider.Zone { - return rrset.zone -} - -func emptyResponse(resp *etcdc.Response) bool { - return resp == nil || resp.Node == nil || (len(resp.Node.Value) == 0 && len(resp.Node.Nodes) == 0) -} diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/stubs/BUILD.bazel b/dnsprovider/pkg/dnsprovider/providers/coredns/stubs/BUILD.bazel deleted file mode 100644 index 2c9c512973c5c..0000000000000 --- a/dnsprovider/pkg/dnsprovider/providers/coredns/stubs/BUILD.bazel +++ /dev/null @@ -1,9 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["corednsapi.go"], - importpath = "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/coredns/stubs", - visibility = ["//visibility:public"], - deps = ["//vendor/go.etcd.io/etcd/client:go_default_library"], -) diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/stubs/corednsapi.go b/dnsprovider/pkg/dnsprovider/providers/coredns/stubs/corednsapi.go deleted file mode 100644 index 5f91f8c88b0a5..0000000000000 --- a/dnsprovider/pkg/dnsprovider/providers/coredns/stubs/corednsapi.go +++ /dev/null @@ -1,85 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package stubs implements a stub for the EtcdKeysAPI, used primarily for unit testing purposes -package stubs - -import ( - "context" - "strings" - - etcd "go.etcd.io/etcd/client" -) - -// Compile time check for interface conformance -var _ EtcdKeysAPI = &EtcdKeysAPIStub{} - -type EtcdKeysAPI interface { - Set(context context.Context, key, value string, options *etcd.SetOptions) (*etcd.Response, error) - Get(context context.Context, key string, options *etcd.GetOptions) (*etcd.Response, error) - Delete(context context.Context, key string, options *etcd.DeleteOptions) (*etcd.Response, error) -} - -type EtcdKeysAPIStub struct { - writes map[string]string -} - -// NewEtcdKeysAPIStub returns an initialized EtcdKeysAPIStub -func NewEtcdKeysAPIStub() *EtcdKeysAPIStub { - return &EtcdKeysAPIStub{make(map[string]string)} -} - -func (ec *EtcdKeysAPIStub) Set(context context.Context, key, value string, options *etcd.SetOptions) (*etcd.Response, error) { - ec.writes[key] = value - return nil, nil -} - -func (ec *EtcdKeysAPIStub) Delete(context context.Context, key string, options *etcd.DeleteOptions) (*etcd.Response, error) { - for p := range ec.writes { - if (options.Recursive && strings.HasPrefix(p, key)) || (!options.Recursive && p == key) { - delete(ec.writes, p) - } - } - return nil, nil -} - -func (ec *EtcdKeysAPIStub) Get(context context.Context, key string, options *etcd.GetOptions) (*etcd.Response, error) { - nodes := ec.GetAll(key) - if len(nodes) == 0 { - return nil, nil - } - if len(nodes) == 1 && nodes[key] != "" { - return &etcd.Response{Node: &etcd.Node{Key: key, Value: nodes[key], Dir: false}}, nil - } - - node := &etcd.Node{Key: key, Dir: true, Nodes: etcd.Nodes{}} - for k, v := range nodes { - n := &etcd.Node{Key: k, Value: v} - node.Nodes = append(node.Nodes, n) - } - return &etcd.Response{Node: node}, nil -} - -func (ec *EtcdKeysAPIStub) GetAll(key string) map[string]string { - nodes := make(map[string]string) - key = strings.ToLower(key) - for path := range ec.writes { - if strings.HasPrefix(path, key) { - nodes[path] = ec.writes[path] - } - } - return nodes -} diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/zone.go b/dnsprovider/pkg/dnsprovider/providers/coredns/zone.go deleted file mode 100644 index 186c1f6928a83..0000000000000 --- a/dnsprovider/pkg/dnsprovider/providers/coredns/zone.go +++ /dev/null @@ -1,42 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package coredns - -import ( - "k8s.io/kops/dnsprovider/pkg/dnsprovider" -) - -// Compile time check for interface adherence -var _ dnsprovider.Zone = Zone{} - -type Zone struct { - domain string - id string - zones *Zones -} - -func (zone Zone) Name() string { - return zone.domain -} - -func (zone Zone) ID() string { - return zone.id -} - -func (zone Zone) ResourceRecordSets() (dnsprovider.ResourceRecordSets, bool) { - return &ResourceRecordSets{zone: &zone}, true -} diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/zones.go b/dnsprovider/pkg/dnsprovider/providers/coredns/zones.go deleted file mode 100644 index 48c3190a007f6..0000000000000 --- a/dnsprovider/pkg/dnsprovider/providers/coredns/zones.go +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package coredns - -import ( - "fmt" - - "k8s.io/kops/dnsprovider/pkg/dnsprovider" -) - -// Compile time check for interface adherence -var _ dnsprovider.Zones = Zones{} - -type Zones struct { - intf *Interface - zoneList []Zone -} - -func (zones Zones) List() ([]dnsprovider.Zone, error) { - var zoneList []dnsprovider.Zone - for _, zone := range zones.zoneList { - zoneList = append(zoneList, zone) - } - return zoneList, nil -} - -func (zones Zones) Add(zone dnsprovider.Zone) (dnsprovider.Zone, error) { - return &Zone{}, fmt.Errorf("OperationNotSupported") -} - -func (zones Zones) Remove(zone dnsprovider.Zone) error { - return fmt.Errorf("OperationNotSupported") -} -func (zones Zones) New(name string) (dnsprovider.Zone, error) { - return &Zone{}, fmt.Errorf("OperationNotSupported") -} diff --git a/go.mod b/go.mod index 49f0ae2bc1e40..4fb71e06cd18d 100644 --- a/go.mod +++ b/go.mod @@ -76,7 +76,6 @@ require ( github.com/hashicorp/hcl/v2 v2.7.0 github.com/hashicorp/vault/api v1.0.4 github.com/jacksontj/memberlistmesh v0.0.0-20190905163944-93462b9d2bb7 - github.com/miekg/coredns v0.0.0-20161111164017-20e25559d5ea github.com/mitchellh/mapstructure v1.1.2 github.com/pelletier/go-toml v1.8.1 github.com/pkg/sftp v1.12.0 @@ -89,7 +88,6 @@ require ( github.com/stretchr/testify v1.6.1 github.com/weaveworks/mesh v0.0.0-20170419100114-1f158d31de55 github.com/zclconf/go-cty v1.3.1 - go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489 golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9 golang.org/x/mod v0.4.0 // indirect golang.org/x/net v0.0.0-20201110031124-69a78807bb2b diff --git a/go.sum b/go.sum index 4df0a77b28741..f3d93034e1e34 100644 --- a/go.sum +++ b/go.sum @@ -704,8 +704,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mholt/certmagic v0.6.2-0.20190624175158-6a42ef9fe8c2/go.mod h1:g4cOPxcjV0oFq3qwpjSA30LReKD8AoIfwAY9VvG35NY= -github.com/miekg/coredns v0.0.0-20161111164017-20e25559d5ea h1:ClxQqQsf07a0/3NsMYizr/dMxQoeSpNWDge0v3iHEcU= -github.com/miekg/coredns v0.0.0-20161111164017-20e25559d5ea/go.mod h1:ulj34RFTnjlzXt4MMq5AcKBIiXNiru0D2fe3enowwU4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.3/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.4 h1:rCMZsU2ScVSYcAsOXgmC6+AKOK+6pmQTOcw03nfwYV0= diff --git a/hack/.staticcheck_failures b/hack/.staticcheck_failures index a9a8cc68d68f2..e69de29bb2d1d 100644 --- a/hack/.staticcheck_failures +++ b/hack/.staticcheck_failures @@ -1 +0,0 @@ -dns-controller/pkg/dns diff --git a/protokube/cmd/protokube/BUILD.bazel b/protokube/cmd/protokube/BUILD.bazel index 317c12793f9f6..4a7d5af25a6cb 100644 --- a/protokube/cmd/protokube/BUILD.bazel +++ b/protokube/cmd/protokube/BUILD.bazel @@ -14,7 +14,6 @@ go_library( "//dns-controller/pkg/dns:go_default_library", "//dnsprovider/pkg/dnsprovider:go_default_library", "//dnsprovider/pkg/dnsprovider/providers/aws/route53:go_default_library", - "//dnsprovider/pkg/dnsprovider/providers/coredns:go_default_library", "//dnsprovider/pkg/dnsprovider/providers/google/clouddns:go_default_library", "//pkg/wellknownports:go_default_library", "//protokube/pkg/gossip:go_default_library", diff --git a/protokube/cmd/protokube/main.go b/protokube/cmd/protokube/main.go index 33ea2b5d57656..e27a7b6d65e10 100644 --- a/protokube/cmd/protokube/main.go +++ b/protokube/cmd/protokube/main.go @@ -17,7 +17,6 @@ limitations under the License. package main import ( - "bytes" "flag" "fmt" "io" @@ -39,7 +38,6 @@ import ( // Load DNS plugins _ "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/aws/route53" - k8scoredns "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/coredns" _ "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns" ) @@ -94,7 +92,7 @@ func run() error { flag.StringVar(&tlsCert, "tls-cert", tlsCert, "Path to a file containing the certificate for etcd server") flag.StringVar(&tlsKey, "tls-key", tlsKey, "Path to a file containing the private key for etcd server") flags.StringSliceVarP(&zones, "zone", "z", []string{}, "Configure permitted zones and their mappings") - flags.StringVar(&dnsProviderID, "dns", "aws-route53", "DNS provider we should use (aws-route53, google-clouddns, coredns, digitalocean)") + flags.StringVar(&dnsProviderID, "dns", "aws-route53", "DNS provider we should use (aws-route53, google-clouddns, digitalocean)") flags.StringVar(&etcdBackupImage, "etcd-backup-image", "", "Set to override the image for (experimental) etcd backups") flags.StringVar(&etcdBackupStore, "etcd-backup-store", "", "Set to enable (experimental) etcd backups") flags.StringVar(&etcdImageSource, "etcd-image", "k8s.gcr.io/etcd:2.2.1", "Etcd Source Container Registry") @@ -360,13 +358,6 @@ func run() error { var dnsController *dns.DNSController { var file io.Reader - if dnsProviderID == k8scoredns.ProviderName { - var lines []string - lines = append(lines, "etcd-endpoints = "+dnsServer) - lines = append(lines, "zones = "+zones[0]) - config := "[global]\n" + strings.Join(lines, "\n") + "\n" - file = bytes.NewReader([]byte(config)) - } dnsProvider, err := dnsprovider.GetDnsProvider(dnsProviderID, file) if err != nil { diff --git a/vendor/github.com/coreos/go-semver/LICENSE b/vendor/github.com/coreos/go-semver/LICENSE deleted file mode 100644 index d645695673349..0000000000000 --- a/vendor/github.com/coreos/go-semver/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/coreos/go-semver/NOTICE b/vendor/github.com/coreos/go-semver/NOTICE deleted file mode 100644 index 23a0ada2fbb56..0000000000000 --- a/vendor/github.com/coreos/go-semver/NOTICE +++ /dev/null @@ -1,5 +0,0 @@ -CoreOS Project -Copyright 2018 CoreOS, Inc - -This product includes software developed at CoreOS, Inc. -(http://www.coreos.com/). diff --git a/vendor/github.com/coreos/go-semver/semver/BUILD.bazel b/vendor/github.com/coreos/go-semver/semver/BUILD.bazel deleted file mode 100644 index 70ba14e13f927..0000000000000 --- a/vendor/github.com/coreos/go-semver/semver/BUILD.bazel +++ /dev/null @@ -1,12 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = [ - "semver.go", - "sort.go", - ], - importmap = "k8s.io/kops/vendor/github.com/coreos/go-semver/semver", - importpath = "github.com/coreos/go-semver/semver", - visibility = ["//visibility:public"], -) diff --git a/vendor/github.com/coreos/go-semver/semver/semver.go b/vendor/github.com/coreos/go-semver/semver/semver.go deleted file mode 100644 index 76cf4852c769e..0000000000000 --- a/vendor/github.com/coreos/go-semver/semver/semver.go +++ /dev/null @@ -1,296 +0,0 @@ -// Copyright 2013-2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Semantic Versions http://semver.org -package semver - -import ( - "bytes" - "errors" - "fmt" - "regexp" - "strconv" - "strings" -) - -type Version struct { - Major int64 - Minor int64 - Patch int64 - PreRelease PreRelease - Metadata string -} - -type PreRelease string - -func splitOff(input *string, delim string) (val string) { - parts := strings.SplitN(*input, delim, 2) - - if len(parts) == 2 { - *input = parts[0] - val = parts[1] - } - - return val -} - -func New(version string) *Version { - return Must(NewVersion(version)) -} - -func NewVersion(version string) (*Version, error) { - v := Version{} - - if err := v.Set(version); err != nil { - return nil, err - } - - return &v, nil -} - -// Must is a helper for wrapping NewVersion and will panic if err is not nil. -func Must(v *Version, err error) *Version { - if err != nil { - panic(err) - } - return v -} - -// Set parses and updates v from the given version string. Implements flag.Value -func (v *Version) Set(version string) error { - metadata := splitOff(&version, "+") - preRelease := PreRelease(splitOff(&version, "-")) - dotParts := strings.SplitN(version, ".", 3) - - if len(dotParts) != 3 { - return fmt.Errorf("%s is not in dotted-tri format", version) - } - - if err := validateIdentifier(string(preRelease)); err != nil { - return fmt.Errorf("failed to validate pre-release: %v", err) - } - - if err := validateIdentifier(metadata); err != nil { - return fmt.Errorf("failed to validate metadata: %v", err) - } - - parsed := make([]int64, 3, 3) - - for i, v := range dotParts[:3] { - val, err := strconv.ParseInt(v, 10, 64) - parsed[i] = val - if err != nil { - return err - } - } - - v.Metadata = metadata - v.PreRelease = preRelease - v.Major = parsed[0] - v.Minor = parsed[1] - v.Patch = parsed[2] - return nil -} - -func (v Version) String() string { - var buffer bytes.Buffer - - fmt.Fprintf(&buffer, "%d.%d.%d", v.Major, v.Minor, v.Patch) - - if v.PreRelease != "" { - fmt.Fprintf(&buffer, "-%s", v.PreRelease) - } - - if v.Metadata != "" { - fmt.Fprintf(&buffer, "+%s", v.Metadata) - } - - return buffer.String() -} - -func (v *Version) UnmarshalYAML(unmarshal func(interface{}) error) error { - var data string - if err := unmarshal(&data); err != nil { - return err - } - return v.Set(data) -} - -func (v Version) MarshalJSON() ([]byte, error) { - return []byte(`"` + v.String() + `"`), nil -} - -func (v *Version) UnmarshalJSON(data []byte) error { - l := len(data) - if l == 0 || string(data) == `""` { - return nil - } - if l < 2 || data[0] != '"' || data[l-1] != '"' { - return errors.New("invalid semver string") - } - return v.Set(string(data[1 : l-1])) -} - -// Compare tests if v is less than, equal to, or greater than versionB, -// returning -1, 0, or +1 respectively. -func (v Version) Compare(versionB Version) int { - if cmp := recursiveCompare(v.Slice(), versionB.Slice()); cmp != 0 { - return cmp - } - return preReleaseCompare(v, versionB) -} - -// Equal tests if v is equal to versionB. -func (v Version) Equal(versionB Version) bool { - return v.Compare(versionB) == 0 -} - -// LessThan tests if v is less than versionB. -func (v Version) LessThan(versionB Version) bool { - return v.Compare(versionB) < 0 -} - -// Slice converts the comparable parts of the semver into a slice of integers. -func (v Version) Slice() []int64 { - return []int64{v.Major, v.Minor, v.Patch} -} - -func (p PreRelease) Slice() []string { - preRelease := string(p) - return strings.Split(preRelease, ".") -} - -func preReleaseCompare(versionA Version, versionB Version) int { - a := versionA.PreRelease - b := versionB.PreRelease - - /* Handle the case where if two versions are otherwise equal it is the - * one without a PreRelease that is greater */ - if len(a) == 0 && (len(b) > 0) { - return 1 - } else if len(b) == 0 && (len(a) > 0) { - return -1 - } - - // If there is a prerelease, check and compare each part. - return recursivePreReleaseCompare(a.Slice(), b.Slice()) -} - -func recursiveCompare(versionA []int64, versionB []int64) int { - if len(versionA) == 0 { - return 0 - } - - a := versionA[0] - b := versionB[0] - - if a > b { - return 1 - } else if a < b { - return -1 - } - - return recursiveCompare(versionA[1:], versionB[1:]) -} - -func recursivePreReleaseCompare(versionA []string, versionB []string) int { - // A larger set of pre-release fields has a higher precedence than a smaller set, - // if all of the preceding identifiers are equal. - if len(versionA) == 0 { - if len(versionB) > 0 { - return -1 - } - return 0 - } else if len(versionB) == 0 { - // We're longer than versionB so return 1. - return 1 - } - - a := versionA[0] - b := versionB[0] - - aInt := false - bInt := false - - aI, err := strconv.Atoi(versionA[0]) - if err == nil { - aInt = true - } - - bI, err := strconv.Atoi(versionB[0]) - if err == nil { - bInt = true - } - - // Numeric identifiers always have lower precedence than non-numeric identifiers. - if aInt && !bInt { - return -1 - } else if !aInt && bInt { - return 1 - } - - // Handle Integer Comparison - if aInt && bInt { - if aI > bI { - return 1 - } else if aI < bI { - return -1 - } - } - - // Handle String Comparison - if a > b { - return 1 - } else if a < b { - return -1 - } - - return recursivePreReleaseCompare(versionA[1:], versionB[1:]) -} - -// BumpMajor increments the Major field by 1 and resets all other fields to their default values -func (v *Version) BumpMajor() { - v.Major += 1 - v.Minor = 0 - v.Patch = 0 - v.PreRelease = PreRelease("") - v.Metadata = "" -} - -// BumpMinor increments the Minor field by 1 and resets all other fields to their default values -func (v *Version) BumpMinor() { - v.Minor += 1 - v.Patch = 0 - v.PreRelease = PreRelease("") - v.Metadata = "" -} - -// BumpPatch increments the Patch field by 1 and resets all other fields to their default values -func (v *Version) BumpPatch() { - v.Patch += 1 - v.PreRelease = PreRelease("") - v.Metadata = "" -} - -// validateIdentifier makes sure the provided identifier satisfies semver spec -func validateIdentifier(id string) error { - if id != "" && !reIdentifier.MatchString(id) { - return fmt.Errorf("%s is not a valid semver identifier", id) - } - return nil -} - -// reIdentifier is a regular expression used to check that pre-release and metadata -// identifiers satisfy the spec requirements -var reIdentifier = regexp.MustCompile(`^[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*$`) diff --git a/vendor/github.com/coreos/go-semver/semver/sort.go b/vendor/github.com/coreos/go-semver/semver/sort.go deleted file mode 100644 index e256b41a5ddf5..0000000000000 --- a/vendor/github.com/coreos/go-semver/semver/sort.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2013-2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package semver - -import ( - "sort" -) - -type Versions []*Version - -func (s Versions) Len() int { - return len(s) -} - -func (s Versions) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -func (s Versions) Less(i, j int) bool { - return s[i].LessThan(*s[j]) -} - -// Sort sorts the given slice of Version -func Sort(versions []*Version) { - sort.Sort(Versions(versions)) -} diff --git a/vendor/github.com/miekg/coredns/LICENSE b/vendor/github.com/miekg/coredns/LICENSE deleted file mode 100644 index 8dada3edaf50d..0000000000000 --- a/vendor/github.com/miekg/coredns/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/miekg/coredns/middleware/etcd/msg/BUILD.bazel b/vendor/github.com/miekg/coredns/middleware/etcd/msg/BUILD.bazel deleted file mode 100644 index 8e8814e4de0cb..0000000000000 --- a/vendor/github.com/miekg/coredns/middleware/etcd/msg/BUILD.bazel +++ /dev/null @@ -1,13 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = [ - "path.go", - "service.go", - ], - importmap = "k8s.io/kops/vendor/github.com/miekg/coredns/middleware/etcd/msg", - importpath = "github.com/miekg/coredns/middleware/etcd/msg", - visibility = ["//visibility:public"], - deps = ["//vendor/github.com/miekg/dns:go_default_library"], -) diff --git a/vendor/github.com/miekg/coredns/middleware/etcd/msg/path.go b/vendor/github.com/miekg/coredns/middleware/etcd/msg/path.go deleted file mode 100644 index aeb52f665d89b..0000000000000 --- a/vendor/github.com/miekg/coredns/middleware/etcd/msg/path.go +++ /dev/null @@ -1,46 +0,0 @@ -package msg - -import ( - "path" - "strings" - - "github.com/miekg/dns" -) - -// Path converts a domainname to an etcd path. If s looks like service.staging.skydns.local., -// the resulting key will be /skydns/local/skydns/staging/service . -func Path(s, prefix string) string { - l := dns.SplitDomainName(s) - for i, j := 0, len(l)-1; i < j; i, j = i+1, j-1 { - l[i], l[j] = l[j], l[i] - } - return path.Join(append([]string{"/" + prefix + "/"}, l...)...) -} - -// Domain is the opposite of Path. -func Domain(s string) string { - l := strings.Split(s, "/") - // start with 1, to strip /skydns - for i, j := 1, len(l)-1; i < j; i, j = i+1, j-1 { - l[i], l[j] = l[j], l[i] - } - return dns.Fqdn(strings.Join(l[1:len(l)-1], ".")) -} - -// PathWithWildcard ascts as Path, but if a name contains wildcards (* or any), the name will be -// chopped of before the (first) wildcard, and we do a highler evel search and -// later find the matching names. So service.*.skydns.local, will look for all -// services under skydns.local and will later check for names that match -// service.*.skydns.local. If a wildcard is found the returned bool is true. -func PathWithWildcard(s, prefix string) (string, bool) { - l := dns.SplitDomainName(s) - for i, j := 0, len(l)-1; i < j; i, j = i+1, j-1 { - l[i], l[j] = l[j], l[i] - } - for i, k := range l { - if k == "*" || k == "any" { - return path.Join(append([]string{"/" + prefix + "/"}, l[:i]...)...), true - } - } - return path.Join(append([]string{"/" + prefix + "/"}, l...)...), false -} diff --git a/vendor/github.com/miekg/coredns/middleware/etcd/msg/service.go b/vendor/github.com/miekg/coredns/middleware/etcd/msg/service.go deleted file mode 100644 index 9250cb634e5ab..0000000000000 --- a/vendor/github.com/miekg/coredns/middleware/etcd/msg/service.go +++ /dev/null @@ -1,203 +0,0 @@ -// Package msg defines the Service structure which is used for service discovery. -package msg - -import ( - "fmt" - "net" - "strings" - - "github.com/miekg/dns" -) - -// Service defines a discoverable service in etcd. It is the rdata from a SRV -// record, but with a twist. Host (Target in SRV) must be a domain name, but -// if it looks like an IP address (4/6), we will treat it like an IP address. -type Service struct { - Host string `json:"host,omitempty"` - Port int `json:"port,omitempty"` - Priority int `json:"priority,omitempty"` - Weight int `json:"weight,omitempty"` - Text string `json:"text,omitempty"` - Mail bool `json:"mail,omitempty"` // Be an MX record. Priority becomes Preference. - TTL uint32 `json:"ttl,omitempty"` - - // When a SRV record with a "Host: IP-address" is added, we synthesize - // a srv.Target domain name. Normally we convert the full Key where - // the record lives to a DNS name and use this as the srv.Target. When - // TargetStrip > 0 we strip the left most TargetStrip labels from the - // DNS name. - TargetStrip int `json:"targetstrip,omitempty"` - - // Group is used to group (or *not* to group) different services - // together. Services with an identical Group are returned in the same - // answer. - Group string `json:"group,omitempty"` - - // Etcd key where we found this service and ignored from json un-/marshalling - Key string `json:"-"` -} - -// RR returns an RR representation of s. It is in a condensed form to minimize space -// when this is returned in a DNS message. -// The RR will look like: -// 1.rails.production.east.skydns.local. 300 CH TXT "service1.example.com:8080(10,0,,false)[0,]" -// etcd Key Ttl Host:Port < see below > -// between parens: (Priority, Weight, Text (only first 200 bytes!), Mail) -// between blockquotes: [TargetStrip,Group] -// If the record is synthesised by CoreDNS (i.e. no lookup in etcd happened): -// -// TODO(miek): what to put here? -// -func (s *Service) RR() *dns.TXT { - l := len(s.Text) - if l > 200 { - l = 200 - } - t := new(dns.TXT) - t.Hdr.Class = dns.ClassCHAOS - t.Hdr.Ttl = s.TTL - t.Hdr.Rrtype = dns.TypeTXT - t.Hdr.Name = Domain(s.Key) - - t.Txt = make([]string, 1) - t.Txt[0] = fmt.Sprintf("%s:%d(%d,%d,%s,%t)[%d,%s]", - s.Host, s.Port, - s.Priority, s.Weight, s.Text[:l], s.Mail, - s.TargetStrip, s.Group) - return t -} - -// NewSRV returns a new SRV record based on the Service. -func (s *Service) NewSRV(name string, weight uint16) *dns.SRV { - host := targetStrip(dns.Fqdn(s.Host), s.TargetStrip) - - return &dns.SRV{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeSRV, Class: dns.ClassINET, Ttl: s.TTL}, - Priority: uint16(s.Priority), Weight: weight, Port: uint16(s.Port), Target: dns.Fqdn(host)} -} - -// NewMX returns a new MX record based on the Service. -func (s *Service) NewMX(name string) *dns.MX { - host := targetStrip(dns.Fqdn(s.Host), s.TargetStrip) - - return &dns.MX{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: s.TTL}, - Preference: uint16(s.Priority), Mx: host} -} - -// NewA returns a new A record based on the Service. -func (s *Service) NewA(name string, ip net.IP) *dns.A { - return &dns.A{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: s.TTL}, A: ip} -} - -// NewAAAA returns a new AAAA record based on the Service. -func (s *Service) NewAAAA(name string, ip net.IP) *dns.AAAA { - return &dns.AAAA{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: s.TTL}, AAAA: ip} -} - -// NewCNAME returns a new CNAME record based on the Service. -func (s *Service) NewCNAME(name string, target string) *dns.CNAME { - return &dns.CNAME{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeCNAME, Class: dns.ClassINET, Ttl: s.TTL}, Target: dns.Fqdn(target)} -} - -// NewTXT returns a new TXT record based on the Service. -func (s *Service) NewTXT(name string) *dns.TXT { - return &dns.TXT{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: s.TTL}, Txt: split255(s.Text)} -} - -// NewPTR returns a new PTR record based on the Service. -func (s *Service) NewPTR(name string, target string) *dns.PTR { - return &dns.PTR{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypePTR, Class: dns.ClassINET, Ttl: s.TTL}, Ptr: dns.Fqdn(target)} -} - -// NewNS returns a new NS record based on the Service. -func (s *Service) NewNS(name string) *dns.NS { - host := targetStrip(dns.Fqdn(s.Host), s.TargetStrip) - return &dns.NS{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeNS, Class: dns.ClassINET, Ttl: s.TTL}, Ns: host} -} - -// Group checks the services in sx, it looks for a Group attribute on the shortest -// keys. If there are multiple shortest keys *and* the group attribute disagrees (and -// is not empty), we don't consider it a group. -// If a group is found, only services with *that* group (or no group) will be returned. -func Group(sx []Service) []Service { - if len(sx) == 0 { - return sx - } - - // Shortest key with group attribute sets the group for this set. - group := sx[0].Group - slashes := strings.Count(sx[0].Key, "/") - length := make([]int, len(sx)) - for i, s := range sx { - x := strings.Count(s.Key, "/") - length[i] = x - if x < slashes { - if s.Group == "" { - break - } - slashes = x - group = s.Group - } - } - - if group == "" { - return sx - } - - ret := []Service{} // with slice-tricks in sx we can prolly save this allocation (TODO) - - for i, s := range sx { - if s.Group == "" { - ret = append(ret, s) - continue - } - - // Disagreement on the same level - if length[i] == slashes && s.Group != group { - return sx - } - - if s.Group == group { - ret = append(ret, s) - } - } - return ret -} - -// Split255 splits a string into 255 byte chunks. -func split255(s string) []string { - if len(s) < 255 { - return []string{s} - } - sx := []string{} - p, i := 0, 255 - for { - if i <= len(s) { - sx = append(sx, s[p:i]) - } else { - sx = append(sx, s[p:]) - break - - } - p, i = p+255, i+255 - } - - return sx -} - -// targetStrip strips "targetstrip" labels from the left side of the fully qualified name. -func targetStrip(name string, targetStrip int) string { - if targetStrip == 0 { - return name - } - - offset, end := 0, false - for i := 0; i < targetStrip; i++ { - offset, end = dns.NextLabel(name, offset) - } - if end { - // We overshot the name, use the orignal one. - offset = 0 - } - name = name[offset:] - return name -} diff --git a/vendor/go.etcd.io/etcd/LICENSE b/vendor/go.etcd.io/etcd/LICENSE deleted file mode 100644 index d645695673349..0000000000000 --- a/vendor/go.etcd.io/etcd/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/go.etcd.io/etcd/NOTICE b/vendor/go.etcd.io/etcd/NOTICE deleted file mode 100644 index b39ddfa5cbdea..0000000000000 --- a/vendor/go.etcd.io/etcd/NOTICE +++ /dev/null @@ -1,5 +0,0 @@ -CoreOS Project -Copyright 2014 CoreOS, Inc - -This product includes software developed at CoreOS, Inc. -(http://www.coreos.com/). diff --git a/vendor/go.etcd.io/etcd/client/BUILD.bazel b/vendor/go.etcd.io/etcd/client/BUILD.bazel deleted file mode 100644 index 0edc059f8b105..0000000000000 --- a/vendor/go.etcd.io/etcd/client/BUILD.bazel +++ /dev/null @@ -1,30 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = [ - "auth_role.go", - "auth_user.go", - "cancelreq.go", - "client.go", - "cluster_error.go", - "curl.go", - "discover.go", - "doc.go", - "json.go", - "keys.go", - "members.go", - "util.go", - ], - importmap = "k8s.io/kops/vendor/go.etcd.io/etcd/client", - importpath = "go.etcd.io/etcd/client", - visibility = ["//visibility:public"], - deps = [ - "//vendor/github.com/json-iterator/go:go_default_library", - "//vendor/github.com/modern-go/reflect2:go_default_library", - "//vendor/go.etcd.io/etcd/pkg/pathutil:go_default_library", - "//vendor/go.etcd.io/etcd/pkg/srv:go_default_library", - "//vendor/go.etcd.io/etcd/pkg/types:go_default_library", - "//vendor/go.etcd.io/etcd/version:go_default_library", - ], -) diff --git a/vendor/go.etcd.io/etcd/client/README.md b/vendor/go.etcd.io/etcd/client/README.md deleted file mode 100644 index 521d6c0120771..0000000000000 --- a/vendor/go.etcd.io/etcd/client/README.md +++ /dev/null @@ -1,112 +0,0 @@ -# etcd/client - -etcd/client is the Go client library for etcd. - -[![GoDoc](https://godoc.org/go.etcd.io/etcd/client?status.png)](https://godoc.org/go.etcd.io/etcd/client) - -For full compatibility, it is recommended to vendor builds using etcd's vendored packages, using tools like `golang/dep`, as in [vendor directories](https://golang.org/cmd/go/#hdr-Vendor_Directories). - -## Install - -```bash -go get go.etcd.io/etcd/client -``` - -## Usage - -```go -package main - -import ( - "log" - "time" - "context" - - "go.etcd.io/etcd/client" -) - -func main() { - cfg := client.Config{ - Endpoints: []string{"http://127.0.0.1:2379"}, - Transport: client.DefaultTransport, - // set timeout per request to fail fast when the target endpoint is unavailable - HeaderTimeoutPerRequest: time.Second, - } - c, err := client.New(cfg) - if err != nil { - log.Fatal(err) - } - kapi := client.NewKeysAPI(c) - // set "/foo" key with "bar" value - log.Print("Setting '/foo' key with 'bar' value") - resp, err := kapi.Set(context.Background(), "/foo", "bar", nil) - if err != nil { - log.Fatal(err) - } else { - // print common key info - log.Printf("Set is done. Metadata is %q\n", resp) - } - // get "/foo" key's value - log.Print("Getting '/foo' key value") - resp, err = kapi.Get(context.Background(), "/foo", nil) - if err != nil { - log.Fatal(err) - } else { - // print common key info - log.Printf("Get is done. Metadata is %q\n", resp) - // print value - log.Printf("%q key has %q value\n", resp.Node.Key, resp.Node.Value) - } -} -``` - -## Error Handling - -etcd client might return three types of errors. - -- context error - -Each API call has its first parameter as `context`. A context can be canceled or have an attached deadline. If the context is canceled or reaches its deadline, the responding context error will be returned no matter what internal errors the API call has already encountered. - -- cluster error - -Each API call tries to send request to the cluster endpoints one by one until it successfully gets a response. If a requests to an endpoint fails, due to exceeding per request timeout or connection issues, the error will be added into a list of errors. If all possible endpoints fail, a cluster error that includes all encountered errors will be returned. - -- response error - -If the response gets from the cluster is invalid, a plain string error will be returned. For example, it might be a invalid JSON error. - -Here is the example code to handle client errors: - -```go -cfg := client.Config{Endpoints: []string{"http://etcd1:2379","http://etcd2:2379","http://etcd3:2379"}} -c, err := client.New(cfg) -if err != nil { - log.Fatal(err) -} - -kapi := client.NewKeysAPI(c) -resp, err := kapi.Set(ctx, "test", "bar", nil) -if err != nil { - if err == context.Canceled { - // ctx is canceled by another routine - } else if err == context.DeadlineExceeded { - // ctx is attached with a deadline and it exceeded - } else if cerr, ok := err.(*client.ClusterError); ok { - // process (cerr.Errors) - } else { - // bad cluster endpoints, which are not etcd servers - } -} -``` - - -## Caveat - -1. etcd/client prefers to use the same endpoint as long as the endpoint continues to work well. This saves socket resources, and improves efficiency for both client and server side. This preference doesn't remove consistency from the data consumed by the client because data replicated to each etcd member has already passed through the consensus process. - -2. etcd/client does round-robin rotation on other available endpoints if the preferred endpoint isn't functioning properly. For example, if the member that etcd/client connects to is hard killed, etcd/client will fail on the first attempt with the killed member, and succeed on the second attempt with another member. If it fails to talk to all available endpoints, it will return all errors happened. - -3. Default etcd/client cannot handle the case that the remote server is SIGSTOPed now. TCP keepalive mechanism doesn't help in this scenario because operating system may still send TCP keep-alive packets. Over time we'd like to improve this functionality, but solving this issue isn't high priority because a real-life case in which a server is stopped, but the connection is kept alive, hasn't been brought to our attention. - -4. etcd/client cannot detect whether a member is healthy with watches and non-quorum read requests. If the member is isolated from the cluster, etcd/client may retrieve outdated data. Instead, users can either issue quorum read requests or monitor the /health endpoint for member health information. diff --git a/vendor/go.etcd.io/etcd/client/auth_role.go b/vendor/go.etcd.io/etcd/client/auth_role.go deleted file mode 100644 index b6ba7e150dc61..0000000000000 --- a/vendor/go.etcd.io/etcd/client/auth_role.go +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright 2015 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package client - -import ( - "bytes" - "context" - "encoding/json" - "net/http" - "net/url" -) - -type Role struct { - Role string `json:"role"` - Permissions Permissions `json:"permissions"` - Grant *Permissions `json:"grant,omitempty"` - Revoke *Permissions `json:"revoke,omitempty"` -} - -type Permissions struct { - KV rwPermission `json:"kv"` -} - -type rwPermission struct { - Read []string `json:"read"` - Write []string `json:"write"` -} - -type PermissionType int - -const ( - ReadPermission PermissionType = iota - WritePermission - ReadWritePermission -) - -// NewAuthRoleAPI constructs a new AuthRoleAPI that uses HTTP to -// interact with etcd's role creation and modification features. -func NewAuthRoleAPI(c Client) AuthRoleAPI { - return &httpAuthRoleAPI{ - client: c, - } -} - -type AuthRoleAPI interface { - // AddRole adds a role. - AddRole(ctx context.Context, role string) error - - // RemoveRole removes a role. - RemoveRole(ctx context.Context, role string) error - - // GetRole retrieves role details. - GetRole(ctx context.Context, role string) (*Role, error) - - // GrantRoleKV grants a role some permission prefixes for the KV store. - GrantRoleKV(ctx context.Context, role string, prefixes []string, permType PermissionType) (*Role, error) - - // RevokeRoleKV revokes some permission prefixes for a role on the KV store. - RevokeRoleKV(ctx context.Context, role string, prefixes []string, permType PermissionType) (*Role, error) - - // ListRoles lists roles. - ListRoles(ctx context.Context) ([]string, error) -} - -type httpAuthRoleAPI struct { - client httpClient -} - -type authRoleAPIAction struct { - verb string - name string - role *Role -} - -type authRoleAPIList struct{} - -func (list *authRoleAPIList) HTTPRequest(ep url.URL) *http.Request { - u := v2AuthURL(ep, "roles", "") - req, _ := http.NewRequest("GET", u.String(), nil) - req.Header.Set("Content-Type", "application/json") - return req -} - -func (l *authRoleAPIAction) HTTPRequest(ep url.URL) *http.Request { - u := v2AuthURL(ep, "roles", l.name) - if l.role == nil { - req, _ := http.NewRequest(l.verb, u.String(), nil) - return req - } - b, err := json.Marshal(l.role) - if err != nil { - panic(err) - } - body := bytes.NewReader(b) - req, _ := http.NewRequest(l.verb, u.String(), body) - req.Header.Set("Content-Type", "application/json") - return req -} - -func (r *httpAuthRoleAPI) ListRoles(ctx context.Context) ([]string, error) { - resp, body, err := r.client.Do(ctx, &authRoleAPIList{}) - if err != nil { - return nil, err - } - if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { - return nil, err - } - var roleList struct { - Roles []Role `json:"roles"` - } - if err = json.Unmarshal(body, &roleList); err != nil { - return nil, err - } - ret := make([]string, 0, len(roleList.Roles)) - for _, r := range roleList.Roles { - ret = append(ret, r.Role) - } - return ret, nil -} - -func (r *httpAuthRoleAPI) AddRole(ctx context.Context, rolename string) error { - role := &Role{ - Role: rolename, - } - return r.addRemoveRole(ctx, &authRoleAPIAction{ - verb: "PUT", - name: rolename, - role: role, - }) -} - -func (r *httpAuthRoleAPI) RemoveRole(ctx context.Context, rolename string) error { - return r.addRemoveRole(ctx, &authRoleAPIAction{ - verb: "DELETE", - name: rolename, - }) -} - -func (r *httpAuthRoleAPI) addRemoveRole(ctx context.Context, req *authRoleAPIAction) error { - resp, body, err := r.client.Do(ctx, req) - if err != nil { - return err - } - if err := assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil { - var sec authError - err := json.Unmarshal(body, &sec) - if err != nil { - return err - } - return sec - } - return nil -} - -func (r *httpAuthRoleAPI) GetRole(ctx context.Context, rolename string) (*Role, error) { - return r.modRole(ctx, &authRoleAPIAction{ - verb: "GET", - name: rolename, - }) -} - -func buildRWPermission(prefixes []string, permType PermissionType) rwPermission { - var out rwPermission - switch permType { - case ReadPermission: - out.Read = prefixes - case WritePermission: - out.Write = prefixes - case ReadWritePermission: - out.Read = prefixes - out.Write = prefixes - } - return out -} - -func (r *httpAuthRoleAPI) GrantRoleKV(ctx context.Context, rolename string, prefixes []string, permType PermissionType) (*Role, error) { - rwp := buildRWPermission(prefixes, permType) - role := &Role{ - Role: rolename, - Grant: &Permissions{ - KV: rwp, - }, - } - return r.modRole(ctx, &authRoleAPIAction{ - verb: "PUT", - name: rolename, - role: role, - }) -} - -func (r *httpAuthRoleAPI) RevokeRoleKV(ctx context.Context, rolename string, prefixes []string, permType PermissionType) (*Role, error) { - rwp := buildRWPermission(prefixes, permType) - role := &Role{ - Role: rolename, - Revoke: &Permissions{ - KV: rwp, - }, - } - return r.modRole(ctx, &authRoleAPIAction{ - verb: "PUT", - name: rolename, - role: role, - }) -} - -func (r *httpAuthRoleAPI) modRole(ctx context.Context, req *authRoleAPIAction) (*Role, error) { - resp, body, err := r.client.Do(ctx, req) - if err != nil { - return nil, err - } - if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { - var sec authError - err = json.Unmarshal(body, &sec) - if err != nil { - return nil, err - } - return nil, sec - } - var role Role - if err = json.Unmarshal(body, &role); err != nil { - return nil, err - } - return &role, nil -} diff --git a/vendor/go.etcd.io/etcd/client/auth_user.go b/vendor/go.etcd.io/etcd/client/auth_user.go deleted file mode 100644 index 8e7e2efe83334..0000000000000 --- a/vendor/go.etcd.io/etcd/client/auth_user.go +++ /dev/null @@ -1,319 +0,0 @@ -// Copyright 2015 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package client - -import ( - "bytes" - "context" - "encoding/json" - "net/http" - "net/url" - "path" -) - -var ( - defaultV2AuthPrefix = "/v2/auth" -) - -type User struct { - User string `json:"user"` - Password string `json:"password,omitempty"` - Roles []string `json:"roles"` - Grant []string `json:"grant,omitempty"` - Revoke []string `json:"revoke,omitempty"` -} - -// userListEntry is the user representation given by the server for ListUsers -type userListEntry struct { - User string `json:"user"` - Roles []Role `json:"roles"` -} - -type UserRoles struct { - User string `json:"user"` - Roles []Role `json:"roles"` -} - -func v2AuthURL(ep url.URL, action string, name string) *url.URL { - if name != "" { - ep.Path = path.Join(ep.Path, defaultV2AuthPrefix, action, name) - return &ep - } - ep.Path = path.Join(ep.Path, defaultV2AuthPrefix, action) - return &ep -} - -// NewAuthAPI constructs a new AuthAPI that uses HTTP to -// interact with etcd's general auth features. -func NewAuthAPI(c Client) AuthAPI { - return &httpAuthAPI{ - client: c, - } -} - -type AuthAPI interface { - // Enable auth. - Enable(ctx context.Context) error - - // Disable auth. - Disable(ctx context.Context) error -} - -type httpAuthAPI struct { - client httpClient -} - -func (s *httpAuthAPI) Enable(ctx context.Context) error { - return s.enableDisable(ctx, &authAPIAction{"PUT"}) -} - -func (s *httpAuthAPI) Disable(ctx context.Context) error { - return s.enableDisable(ctx, &authAPIAction{"DELETE"}) -} - -func (s *httpAuthAPI) enableDisable(ctx context.Context, req httpAction) error { - resp, body, err := s.client.Do(ctx, req) - if err != nil { - return err - } - if err = assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil { - var sec authError - err = json.Unmarshal(body, &sec) - if err != nil { - return err - } - return sec - } - return nil -} - -type authAPIAction struct { - verb string -} - -func (l *authAPIAction) HTTPRequest(ep url.URL) *http.Request { - u := v2AuthURL(ep, "enable", "") - req, _ := http.NewRequest(l.verb, u.String(), nil) - return req -} - -type authError struct { - Message string `json:"message"` - Code int `json:"-"` -} - -func (e authError) Error() string { - return e.Message -} - -// NewAuthUserAPI constructs a new AuthUserAPI that uses HTTP to -// interact with etcd's user creation and modification features. -func NewAuthUserAPI(c Client) AuthUserAPI { - return &httpAuthUserAPI{ - client: c, - } -} - -type AuthUserAPI interface { - // AddUser adds a user. - AddUser(ctx context.Context, username string, password string) error - - // RemoveUser removes a user. - RemoveUser(ctx context.Context, username string) error - - // GetUser retrieves user details. - GetUser(ctx context.Context, username string) (*User, error) - - // GrantUser grants a user some permission roles. - GrantUser(ctx context.Context, username string, roles []string) (*User, error) - - // RevokeUser revokes some permission roles from a user. - RevokeUser(ctx context.Context, username string, roles []string) (*User, error) - - // ChangePassword changes the user's password. - ChangePassword(ctx context.Context, username string, password string) (*User, error) - - // ListUsers lists the users. - ListUsers(ctx context.Context) ([]string, error) -} - -type httpAuthUserAPI struct { - client httpClient -} - -type authUserAPIAction struct { - verb string - username string - user *User -} - -type authUserAPIList struct{} - -func (list *authUserAPIList) HTTPRequest(ep url.URL) *http.Request { - u := v2AuthURL(ep, "users", "") - req, _ := http.NewRequest("GET", u.String(), nil) - req.Header.Set("Content-Type", "application/json") - return req -} - -func (l *authUserAPIAction) HTTPRequest(ep url.URL) *http.Request { - u := v2AuthURL(ep, "users", l.username) - if l.user == nil { - req, _ := http.NewRequest(l.verb, u.String(), nil) - return req - } - b, err := json.Marshal(l.user) - if err != nil { - panic(err) - } - body := bytes.NewReader(b) - req, _ := http.NewRequest(l.verb, u.String(), body) - req.Header.Set("Content-Type", "application/json") - return req -} - -func (u *httpAuthUserAPI) ListUsers(ctx context.Context) ([]string, error) { - resp, body, err := u.client.Do(ctx, &authUserAPIList{}) - if err != nil { - return nil, err - } - if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { - var sec authError - err = json.Unmarshal(body, &sec) - if err != nil { - return nil, err - } - return nil, sec - } - - var userList struct { - Users []userListEntry `json:"users"` - } - - if err = json.Unmarshal(body, &userList); err != nil { - return nil, err - } - - ret := make([]string, 0, len(userList.Users)) - for _, u := range userList.Users { - ret = append(ret, u.User) - } - return ret, nil -} - -func (u *httpAuthUserAPI) AddUser(ctx context.Context, username string, password string) error { - user := &User{ - User: username, - Password: password, - } - return u.addRemoveUser(ctx, &authUserAPIAction{ - verb: "PUT", - username: username, - user: user, - }) -} - -func (u *httpAuthUserAPI) RemoveUser(ctx context.Context, username string) error { - return u.addRemoveUser(ctx, &authUserAPIAction{ - verb: "DELETE", - username: username, - }) -} - -func (u *httpAuthUserAPI) addRemoveUser(ctx context.Context, req *authUserAPIAction) error { - resp, body, err := u.client.Do(ctx, req) - if err != nil { - return err - } - if err = assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil { - var sec authError - err = json.Unmarshal(body, &sec) - if err != nil { - return err - } - return sec - } - return nil -} - -func (u *httpAuthUserAPI) GetUser(ctx context.Context, username string) (*User, error) { - return u.modUser(ctx, &authUserAPIAction{ - verb: "GET", - username: username, - }) -} - -func (u *httpAuthUserAPI) GrantUser(ctx context.Context, username string, roles []string) (*User, error) { - user := &User{ - User: username, - Grant: roles, - } - return u.modUser(ctx, &authUserAPIAction{ - verb: "PUT", - username: username, - user: user, - }) -} - -func (u *httpAuthUserAPI) RevokeUser(ctx context.Context, username string, roles []string) (*User, error) { - user := &User{ - User: username, - Revoke: roles, - } - return u.modUser(ctx, &authUserAPIAction{ - verb: "PUT", - username: username, - user: user, - }) -} - -func (u *httpAuthUserAPI) ChangePassword(ctx context.Context, username string, password string) (*User, error) { - user := &User{ - User: username, - Password: password, - } - return u.modUser(ctx, &authUserAPIAction{ - verb: "PUT", - username: username, - user: user, - }) -} - -func (u *httpAuthUserAPI) modUser(ctx context.Context, req *authUserAPIAction) (*User, error) { - resp, body, err := u.client.Do(ctx, req) - if err != nil { - return nil, err - } - if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { - var sec authError - err = json.Unmarshal(body, &sec) - if err != nil { - return nil, err - } - return nil, sec - } - var user User - if err = json.Unmarshal(body, &user); err != nil { - var userR UserRoles - if urerr := json.Unmarshal(body, &userR); urerr != nil { - return nil, err - } - user.User = userR.User - for _, r := range userR.Roles { - user.Roles = append(user.Roles, r.Role) - } - } - return &user, nil -} diff --git a/vendor/go.etcd.io/etcd/client/cancelreq.go b/vendor/go.etcd.io/etcd/client/cancelreq.go deleted file mode 100644 index 76d1f040198bc..0000000000000 --- a/vendor/go.etcd.io/etcd/client/cancelreq.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// borrowed from golang/net/context/ctxhttp/cancelreq.go - -package client - -import "net/http" - -func requestCanceler(tr CancelableTransport, req *http.Request) func() { - ch := make(chan struct{}) - req.Cancel = ch - - return func() { - close(ch) - } -} diff --git a/vendor/go.etcd.io/etcd/client/client.go b/vendor/go.etcd.io/etcd/client/client.go deleted file mode 100644 index de9ab798e4871..0000000000000 --- a/vendor/go.etcd.io/etcd/client/client.go +++ /dev/null @@ -1,710 +0,0 @@ -// Copyright 2015 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package client - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "io/ioutil" - "math/rand" - "net" - "net/http" - "net/url" - "sort" - "strconv" - "sync" - "time" - - "go.etcd.io/etcd/version" -) - -var ( - ErrNoEndpoints = errors.New("client: no endpoints available") - ErrTooManyRedirects = errors.New("client: too many redirects") - ErrClusterUnavailable = errors.New("client: etcd cluster is unavailable or misconfigured") - ErrNoLeaderEndpoint = errors.New("client: no leader endpoint available") - errTooManyRedirectChecks = errors.New("client: too many redirect checks") - - // oneShotCtxValue is set on a context using WithValue(&oneShotValue) so - // that Do() will not retry a request - oneShotCtxValue interface{} -) - -var DefaultRequestTimeout = 5 * time.Second - -var DefaultTransport CancelableTransport = &http.Transport{ - Proxy: http.ProxyFromEnvironment, - Dial: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).Dial, - TLSHandshakeTimeout: 10 * time.Second, -} - -type EndpointSelectionMode int - -const ( - // EndpointSelectionRandom is the default value of the 'SelectionMode'. - // As the name implies, the client object will pick a node from the members - // of the cluster in a random fashion. If the cluster has three members, A, B, - // and C, the client picks any node from its three members as its request - // destination. - EndpointSelectionRandom EndpointSelectionMode = iota - - // If 'SelectionMode' is set to 'EndpointSelectionPrioritizeLeader', - // requests are sent directly to the cluster leader. This reduces - // forwarding roundtrips compared to making requests to etcd followers - // who then forward them to the cluster leader. In the event of a leader - // failure, however, clients configured this way cannot prioritize among - // the remaining etcd followers. Therefore, when a client sets 'SelectionMode' - // to 'EndpointSelectionPrioritizeLeader', it must use 'client.AutoSync()' to - // maintain its knowledge of current cluster state. - // - // This mode should be used with Client.AutoSync(). - EndpointSelectionPrioritizeLeader -) - -type Config struct { - // Endpoints defines a set of URLs (schemes, hosts and ports only) - // that can be used to communicate with a logical etcd cluster. For - // example, a three-node cluster could be provided like so: - // - // Endpoints: []string{ - // "http://node1.example.com:2379", - // "http://node2.example.com:2379", - // "http://node3.example.com:2379", - // } - // - // If multiple endpoints are provided, the Client will attempt to - // use them all in the event that one or more of them are unusable. - // - // If Client.Sync is ever called, the Client may cache an alternate - // set of endpoints to continue operation. - Endpoints []string - - // Transport is used by the Client to drive HTTP requests. If not - // provided, DefaultTransport will be used. - Transport CancelableTransport - - // CheckRedirect specifies the policy for handling HTTP redirects. - // If CheckRedirect is not nil, the Client calls it before - // following an HTTP redirect. The sole argument is the number of - // requests that have already been made. If CheckRedirect returns - // an error, Client.Do will not make any further requests and return - // the error back it to the caller. - // - // If CheckRedirect is nil, the Client uses its default policy, - // which is to stop after 10 consecutive requests. - CheckRedirect CheckRedirectFunc - - // Username specifies the user credential to add as an authorization header - Username string - - // Password is the password for the specified user to add as an authorization header - // to the request. - Password string - - // HeaderTimeoutPerRequest specifies the time limit to wait for response - // header in a single request made by the Client. The timeout includes - // connection time, any redirects, and header wait time. - // - // For non-watch GET request, server returns the response body immediately. - // For PUT/POST/DELETE request, server will attempt to commit request - // before responding, which is expected to take `100ms + 2 * RTT`. - // For watch request, server returns the header immediately to notify Client - // watch start. But if server is behind some kind of proxy, the response - // header may be cached at proxy, and Client cannot rely on this behavior. - // - // Especially, wait request will ignore this timeout. - // - // One API call may send multiple requests to different etcd servers until it - // succeeds. Use context of the API to specify the overall timeout. - // - // A HeaderTimeoutPerRequest of zero means no timeout. - HeaderTimeoutPerRequest time.Duration - - // SelectionMode is an EndpointSelectionMode enum that specifies the - // policy for choosing the etcd cluster node to which requests are sent. - SelectionMode EndpointSelectionMode -} - -func (cfg *Config) transport() CancelableTransport { - if cfg.Transport == nil { - return DefaultTransport - } - return cfg.Transport -} - -func (cfg *Config) checkRedirect() CheckRedirectFunc { - if cfg.CheckRedirect == nil { - return DefaultCheckRedirect - } - return cfg.CheckRedirect -} - -// CancelableTransport mimics net/http.Transport, but requires that -// the object also support request cancellation. -type CancelableTransport interface { - http.RoundTripper - CancelRequest(req *http.Request) -} - -type CheckRedirectFunc func(via int) error - -// DefaultCheckRedirect follows up to 10 redirects, but no more. -var DefaultCheckRedirect CheckRedirectFunc = func(via int) error { - if via > 10 { - return ErrTooManyRedirects - } - return nil -} - -type Client interface { - // Sync updates the internal cache of the etcd cluster's membership. - Sync(context.Context) error - - // AutoSync periodically calls Sync() every given interval. - // The recommended sync interval is 10 seconds to 1 minute, which does - // not bring too much overhead to server and makes client catch up the - // cluster change in time. - // - // The example to use it: - // - // for { - // err := client.AutoSync(ctx, 10*time.Second) - // if err == context.DeadlineExceeded || err == context.Canceled { - // break - // } - // log.Print(err) - // } - AutoSync(context.Context, time.Duration) error - - // Endpoints returns a copy of the current set of API endpoints used - // by Client to resolve HTTP requests. If Sync has ever been called, - // this may differ from the initial Endpoints provided in the Config. - Endpoints() []string - - // SetEndpoints sets the set of API endpoints used by Client to resolve - // HTTP requests. If the given endpoints are not valid, an error will be - // returned - SetEndpoints(eps []string) error - - // GetVersion retrieves the current etcd server and cluster version - GetVersion(ctx context.Context) (*version.Versions, error) - - httpClient -} - -func New(cfg Config) (Client, error) { - c := &httpClusterClient{ - clientFactory: newHTTPClientFactory(cfg.transport(), cfg.checkRedirect(), cfg.HeaderTimeoutPerRequest), - rand: rand.New(rand.NewSource(int64(time.Now().Nanosecond()))), - selectionMode: cfg.SelectionMode, - } - if cfg.Username != "" { - c.credentials = &credentials{ - username: cfg.Username, - password: cfg.Password, - } - } - if err := c.SetEndpoints(cfg.Endpoints); err != nil { - return nil, err - } - return c, nil -} - -type httpClient interface { - Do(context.Context, httpAction) (*http.Response, []byte, error) -} - -func newHTTPClientFactory(tr CancelableTransport, cr CheckRedirectFunc, headerTimeout time.Duration) httpClientFactory { - return func(ep url.URL) httpClient { - return &redirectFollowingHTTPClient{ - checkRedirect: cr, - client: &simpleHTTPClient{ - transport: tr, - endpoint: ep, - headerTimeout: headerTimeout, - }, - } - } -} - -type credentials struct { - username string - password string -} - -type httpClientFactory func(url.URL) httpClient - -type httpAction interface { - HTTPRequest(url.URL) *http.Request -} - -type httpClusterClient struct { - clientFactory httpClientFactory - endpoints []url.URL - pinned int - credentials *credentials - sync.RWMutex - rand *rand.Rand - selectionMode EndpointSelectionMode -} - -func (c *httpClusterClient) getLeaderEndpoint(ctx context.Context, eps []url.URL) (string, error) { - ceps := make([]url.URL, len(eps)) - copy(ceps, eps) - - // To perform a lookup on the new endpoint list without using the current - // client, we'll copy it - clientCopy := &httpClusterClient{ - clientFactory: c.clientFactory, - credentials: c.credentials, - rand: c.rand, - - pinned: 0, - endpoints: ceps, - } - - mAPI := NewMembersAPI(clientCopy) - leader, err := mAPI.Leader(ctx) - if err != nil { - return "", err - } - if len(leader.ClientURLs) == 0 { - return "", ErrNoLeaderEndpoint - } - - return leader.ClientURLs[0], nil // TODO: how to handle multiple client URLs? -} - -func (c *httpClusterClient) parseEndpoints(eps []string) ([]url.URL, error) { - if len(eps) == 0 { - return []url.URL{}, ErrNoEndpoints - } - - neps := make([]url.URL, len(eps)) - for i, ep := range eps { - u, err := url.Parse(ep) - if err != nil { - return []url.URL{}, err - } - neps[i] = *u - } - return neps, nil -} - -func (c *httpClusterClient) SetEndpoints(eps []string) error { - neps, err := c.parseEndpoints(eps) - if err != nil { - return err - } - - c.Lock() - defer c.Unlock() - - c.endpoints = shuffleEndpoints(c.rand, neps) - // We're not doing anything for PrioritizeLeader here. This is - // due to not having a context meaning we can't call getLeaderEndpoint - // However, if you're using PrioritizeLeader, you've already been told - // to regularly call sync, where we do have a ctx, and can figure the - // leader. PrioritizeLeader is also quite a loose guarantee, so deal - // with it - c.pinned = 0 - - return nil -} - -func (c *httpClusterClient) Do(ctx context.Context, act httpAction) (*http.Response, []byte, error) { - action := act - c.RLock() - leps := len(c.endpoints) - eps := make([]url.URL, leps) - n := copy(eps, c.endpoints) - pinned := c.pinned - - if c.credentials != nil { - action = &authedAction{ - act: act, - credentials: *c.credentials, - } - } - c.RUnlock() - - if leps == 0 { - return nil, nil, ErrNoEndpoints - } - - if leps != n { - return nil, nil, errors.New("unable to pick endpoint: copy failed") - } - - var resp *http.Response - var body []byte - var err error - cerr := &ClusterError{} - isOneShot := ctx.Value(&oneShotCtxValue) != nil - - for i := pinned; i < leps+pinned; i++ { - k := i % leps - hc := c.clientFactory(eps[k]) - resp, body, err = hc.Do(ctx, action) - if err != nil { - cerr.Errors = append(cerr.Errors, err) - if err == ctx.Err() { - return nil, nil, ctx.Err() - } - if err == context.Canceled || err == context.DeadlineExceeded { - return nil, nil, err - } - } else if resp.StatusCode/100 == 5 { - switch resp.StatusCode { - case http.StatusInternalServerError, http.StatusServiceUnavailable: - // TODO: make sure this is a no leader response - cerr.Errors = append(cerr.Errors, fmt.Errorf("client: etcd member %s has no leader", eps[k].String())) - default: - cerr.Errors = append(cerr.Errors, fmt.Errorf("client: etcd member %s returns server error [%s]", eps[k].String(), http.StatusText(resp.StatusCode))) - } - err = cerr.Errors[0] - } - if err != nil { - if !isOneShot { - continue - } - c.Lock() - c.pinned = (k + 1) % leps - c.Unlock() - return nil, nil, err - } - if k != pinned { - c.Lock() - c.pinned = k - c.Unlock() - } - return resp, body, nil - } - - return nil, nil, cerr -} - -func (c *httpClusterClient) Endpoints() []string { - c.RLock() - defer c.RUnlock() - - eps := make([]string, len(c.endpoints)) - for i, ep := range c.endpoints { - eps[i] = ep.String() - } - - return eps -} - -func (c *httpClusterClient) Sync(ctx context.Context) error { - mAPI := NewMembersAPI(c) - ms, err := mAPI.List(ctx) - if err != nil { - return err - } - - var eps []string - for _, m := range ms { - eps = append(eps, m.ClientURLs...) - } - - neps, err := c.parseEndpoints(eps) - if err != nil { - return err - } - - npin := 0 - - switch c.selectionMode { - case EndpointSelectionRandom: - c.RLock() - eq := endpointsEqual(c.endpoints, neps) - c.RUnlock() - - if eq { - return nil - } - // When items in the endpoint list changes, we choose a new pin - neps = shuffleEndpoints(c.rand, neps) - case EndpointSelectionPrioritizeLeader: - nle, err := c.getLeaderEndpoint(ctx, neps) - if err != nil { - return ErrNoLeaderEndpoint - } - - for i, n := range neps { - if n.String() == nle { - npin = i - break - } - } - default: - return fmt.Errorf("invalid endpoint selection mode: %d", c.selectionMode) - } - - c.Lock() - defer c.Unlock() - c.endpoints = neps - c.pinned = npin - - return nil -} - -func (c *httpClusterClient) AutoSync(ctx context.Context, interval time.Duration) error { - ticker := time.NewTicker(interval) - defer ticker.Stop() - for { - err := c.Sync(ctx) - if err != nil { - return err - } - select { - case <-ctx.Done(): - return ctx.Err() - case <-ticker.C: - } - } -} - -func (c *httpClusterClient) GetVersion(ctx context.Context) (*version.Versions, error) { - act := &getAction{Prefix: "/version"} - - resp, body, err := c.Do(ctx, act) - if err != nil { - return nil, err - } - - switch resp.StatusCode { - case http.StatusOK: - if len(body) == 0 { - return nil, ErrEmptyBody - } - var vresp version.Versions - if err := json.Unmarshal(body, &vresp); err != nil { - return nil, ErrInvalidJSON - } - return &vresp, nil - default: - var etcdErr Error - if err := json.Unmarshal(body, &etcdErr); err != nil { - return nil, ErrInvalidJSON - } - return nil, etcdErr - } -} - -type roundTripResponse struct { - resp *http.Response - err error -} - -type simpleHTTPClient struct { - transport CancelableTransport - endpoint url.URL - headerTimeout time.Duration -} - -func (c *simpleHTTPClient) Do(ctx context.Context, act httpAction) (*http.Response, []byte, error) { - req := act.HTTPRequest(c.endpoint) - - if err := printcURL(req); err != nil { - return nil, nil, err - } - - isWait := false - if req != nil && req.URL != nil { - ws := req.URL.Query().Get("wait") - if len(ws) != 0 { - var err error - isWait, err = strconv.ParseBool(ws) - if err != nil { - return nil, nil, fmt.Errorf("wrong wait value %s (%v for %+v)", ws, err, req) - } - } - } - - var hctx context.Context - var hcancel context.CancelFunc - if !isWait && c.headerTimeout > 0 { - hctx, hcancel = context.WithTimeout(ctx, c.headerTimeout) - } else { - hctx, hcancel = context.WithCancel(ctx) - } - defer hcancel() - - reqcancel := requestCanceler(c.transport, req) - - rtchan := make(chan roundTripResponse, 1) - go func() { - resp, err := c.transport.RoundTrip(req) - rtchan <- roundTripResponse{resp: resp, err: err} - close(rtchan) - }() - - var resp *http.Response - var err error - - select { - case rtresp := <-rtchan: - resp, err = rtresp.resp, rtresp.err - case <-hctx.Done(): - // cancel and wait for request to actually exit before continuing - reqcancel() - rtresp := <-rtchan - resp = rtresp.resp - switch { - case ctx.Err() != nil: - err = ctx.Err() - case hctx.Err() != nil: - err = fmt.Errorf("client: endpoint %s exceeded header timeout", c.endpoint.String()) - default: - panic("failed to get error from context") - } - } - - // always check for resp nil-ness to deal with possible - // race conditions between channels above - defer func() { - if resp != nil { - resp.Body.Close() - } - }() - - if err != nil { - return nil, nil, err - } - - var body []byte - done := make(chan struct{}) - go func() { - body, err = ioutil.ReadAll(resp.Body) - done <- struct{}{} - }() - - select { - case <-ctx.Done(): - resp.Body.Close() - <-done - return nil, nil, ctx.Err() - case <-done: - } - - return resp, body, err -} - -type authedAction struct { - act httpAction - credentials credentials -} - -func (a *authedAction) HTTPRequest(url url.URL) *http.Request { - r := a.act.HTTPRequest(url) - r.SetBasicAuth(a.credentials.username, a.credentials.password) - return r -} - -type redirectFollowingHTTPClient struct { - client httpClient - checkRedirect CheckRedirectFunc -} - -func (r *redirectFollowingHTTPClient) Do(ctx context.Context, act httpAction) (*http.Response, []byte, error) { - next := act - for i := 0; i < 100; i++ { - if i > 0 { - if err := r.checkRedirect(i); err != nil { - return nil, nil, err - } - } - resp, body, err := r.client.Do(ctx, next) - if err != nil { - return nil, nil, err - } - if resp.StatusCode/100 == 3 { - hdr := resp.Header.Get("Location") - if hdr == "" { - return nil, nil, fmt.Errorf("location header not set") - } - loc, err := url.Parse(hdr) - if err != nil { - return nil, nil, fmt.Errorf("location header not valid URL: %s", hdr) - } - next = &redirectedHTTPAction{ - action: act, - location: *loc, - } - continue - } - return resp, body, nil - } - - return nil, nil, errTooManyRedirectChecks -} - -type redirectedHTTPAction struct { - action httpAction - location url.URL -} - -func (r *redirectedHTTPAction) HTTPRequest(ep url.URL) *http.Request { - orig := r.action.HTTPRequest(ep) - orig.URL = &r.location - return orig -} - -func shuffleEndpoints(r *rand.Rand, eps []url.URL) []url.URL { - // copied from Go 1.9<= rand.Rand.Perm - n := len(eps) - p := make([]int, n) - for i := 0; i < n; i++ { - j := r.Intn(i + 1) - p[i] = p[j] - p[j] = i - } - neps := make([]url.URL, n) - for i, k := range p { - neps[i] = eps[k] - } - return neps -} - -func endpointsEqual(left, right []url.URL) bool { - if len(left) != len(right) { - return false - } - - sLeft := make([]string, len(left)) - sRight := make([]string, len(right)) - for i, l := range left { - sLeft[i] = l.String() - } - for i, r := range right { - sRight[i] = r.String() - } - - sort.Strings(sLeft) - sort.Strings(sRight) - for i := range sLeft { - if sLeft[i] != sRight[i] { - return false - } - } - return true -} diff --git a/vendor/go.etcd.io/etcd/client/cluster_error.go b/vendor/go.etcd.io/etcd/client/cluster_error.go deleted file mode 100644 index 34618cdbd9e60..0000000000000 --- a/vendor/go.etcd.io/etcd/client/cluster_error.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2015 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package client - -import "fmt" - -type ClusterError struct { - Errors []error -} - -func (ce *ClusterError) Error() string { - s := ErrClusterUnavailable.Error() - for i, e := range ce.Errors { - s += fmt.Sprintf("; error #%d: %s\n", i, e) - } - return s -} - -func (ce *ClusterError) Detail() string { - s := "" - for i, e := range ce.Errors { - s += fmt.Sprintf("error #%d: %s\n", i, e) - } - return s -} diff --git a/vendor/go.etcd.io/etcd/client/curl.go b/vendor/go.etcd.io/etcd/client/curl.go deleted file mode 100644 index c8bc9fba20ecc..0000000000000 --- a/vendor/go.etcd.io/etcd/client/curl.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2015 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package client - -import ( - "bytes" - "fmt" - "io/ioutil" - "net/http" - "os" -) - -var ( - cURLDebug = false -) - -func EnablecURLDebug() { - cURLDebug = true -} - -func DisablecURLDebug() { - cURLDebug = false -} - -// printcURL prints the cURL equivalent request to stderr. -// It returns an error if the body of the request cannot -// be read. -// The caller MUST cancel the request if there is an error. -func printcURL(req *http.Request) error { - if !cURLDebug { - return nil - } - var ( - command string - b []byte - err error - ) - - if req.URL != nil { - command = fmt.Sprintf("curl -X %s %s", req.Method, req.URL.String()) - } - - if req.Body != nil { - b, err = ioutil.ReadAll(req.Body) - if err != nil { - return err - } - command += fmt.Sprintf(" -d %q", string(b)) - } - - fmt.Fprintf(os.Stderr, "cURL Command: %s\n", command) - - // reset body - body := bytes.NewBuffer(b) - req.Body = ioutil.NopCloser(body) - - return nil -} diff --git a/vendor/go.etcd.io/etcd/client/discover.go b/vendor/go.etcd.io/etcd/client/discover.go deleted file mode 100644 index 580c25626c982..0000000000000 --- a/vendor/go.etcd.io/etcd/client/discover.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2015 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package client - -import ( - "go.etcd.io/etcd/pkg/srv" -) - -// Discoverer is an interface that wraps the Discover method. -type Discoverer interface { - // Discover looks up the etcd servers for the domain. - Discover(domain string, serviceName string) ([]string, error) -} - -type srvDiscover struct{} - -// NewSRVDiscover constructs a new Discoverer that uses the stdlib to lookup SRV records. -func NewSRVDiscover() Discoverer { - return &srvDiscover{} -} - -func (d *srvDiscover) Discover(domain string, serviceName string) ([]string, error) { - srvs, err := srv.GetClient("etcd-client", domain, serviceName) - if err != nil { - return nil, err - } - return srvs.Endpoints, nil -} diff --git a/vendor/go.etcd.io/etcd/client/doc.go b/vendor/go.etcd.io/etcd/client/doc.go deleted file mode 100644 index abe5199c319ca..0000000000000 --- a/vendor/go.etcd.io/etcd/client/doc.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2015 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/* -Package client provides bindings for the etcd APIs. - -Create a Config and exchange it for a Client: - - import ( - "net/http" - "context" - - "go.etcd.io/etcd/client" - ) - - cfg := client.Config{ - Endpoints: []string{"http://127.0.0.1:2379"}, - Transport: DefaultTransport, - } - - c, err := client.New(cfg) - if err != nil { - // handle error - } - -Clients are safe for concurrent use by multiple goroutines. - -Create a KeysAPI using the Client, then use it to interact with etcd: - - kAPI := client.NewKeysAPI(c) - - // create a new key /foo with the value "bar" - _, err = kAPI.Create(context.Background(), "/foo", "bar") - if err != nil { - // handle error - } - - // delete the newly created key only if the value is still "bar" - _, err = kAPI.Delete(context.Background(), "/foo", &DeleteOptions{PrevValue: "bar"}) - if err != nil { - // handle error - } - -Use a custom context to set timeouts on your operations: - - import "time" - - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - // set a new key, ignoring its previous state - _, err := kAPI.Set(ctx, "/ping", "pong", nil) - if err != nil { - if err == context.DeadlineExceeded { - // request took longer than 5s - } else { - // handle error - } - } - -*/ -package client diff --git a/vendor/go.etcd.io/etcd/client/json.go b/vendor/go.etcd.io/etcd/client/json.go deleted file mode 100644 index 97cdbcd7cfa57..0000000000000 --- a/vendor/go.etcd.io/etcd/client/json.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2019 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package client - -import ( - "github.com/json-iterator/go" - "github.com/modern-go/reflect2" - "strconv" - "unsafe" -) - -type customNumberExtension struct { - jsoniter.DummyExtension -} - -func (cne *customNumberExtension) CreateDecoder(typ reflect2.Type) jsoniter.ValDecoder { - if typ.String() == "interface {}" { - return customNumberDecoder{} - } - return nil -} - -type customNumberDecoder struct { -} - -func (customNumberDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { - switch iter.WhatIsNext() { - case jsoniter.NumberValue: - var number jsoniter.Number - iter.ReadVal(&number) - i64, err := strconv.ParseInt(string(number), 10, 64) - if err == nil { - *(*interface{})(ptr) = i64 - return - } - f64, err := strconv.ParseFloat(string(number), 64) - if err == nil { - *(*interface{})(ptr) = f64 - return - } - iter.ReportError("DecodeNumber", err.Error()) - default: - *(*interface{})(ptr) = iter.Read() - } -} - -// caseSensitiveJsonIterator returns a jsoniterator API that's configured to be -// case-sensitive when unmarshalling, and otherwise compatible with -// the encoding/json standard library. -func caseSensitiveJsonIterator() jsoniter.API { - config := jsoniter.Config{ - EscapeHTML: true, - SortMapKeys: true, - ValidateJsonRawMessage: true, - CaseSensitive: true, - }.Froze() - // Force jsoniter to decode number to interface{} via int64/float64, if possible. - config.RegisterExtension(&customNumberExtension{}) - return config -} diff --git a/vendor/go.etcd.io/etcd/client/keys.go b/vendor/go.etcd.io/etcd/client/keys.go deleted file mode 100644 index ec53830c7f0a1..0000000000000 --- a/vendor/go.etcd.io/etcd/client/keys.go +++ /dev/null @@ -1,679 +0,0 @@ -// Copyright 2015 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package client - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "go.etcd.io/etcd/pkg/pathutil" - "net/http" - "net/url" - "strconv" - "strings" - "time" -) - -const ( - ErrorCodeKeyNotFound = 100 - ErrorCodeTestFailed = 101 - ErrorCodeNotFile = 102 - ErrorCodeNotDir = 104 - ErrorCodeNodeExist = 105 - ErrorCodeRootROnly = 107 - ErrorCodeDirNotEmpty = 108 - ErrorCodeUnauthorized = 110 - - ErrorCodePrevValueRequired = 201 - ErrorCodeTTLNaN = 202 - ErrorCodeIndexNaN = 203 - ErrorCodeInvalidField = 209 - ErrorCodeInvalidForm = 210 - - ErrorCodeRaftInternal = 300 - ErrorCodeLeaderElect = 301 - - ErrorCodeWatcherCleared = 400 - ErrorCodeEventIndexCleared = 401 -) - -type Error struct { - Code int `json:"errorCode"` - Message string `json:"message"` - Cause string `json:"cause"` - Index uint64 `json:"index"` -} - -func (e Error) Error() string { - return fmt.Sprintf("%v: %v (%v) [%v]", e.Code, e.Message, e.Cause, e.Index) -} - -var ( - ErrInvalidJSON = errors.New("client: response is invalid json. The endpoint is probably not valid etcd cluster endpoint") - ErrEmptyBody = errors.New("client: response body is empty") -) - -// PrevExistType is used to define an existence condition when setting -// or deleting Nodes. -type PrevExistType string - -const ( - PrevIgnore = PrevExistType("") - PrevExist = PrevExistType("true") - PrevNoExist = PrevExistType("false") -) - -var ( - defaultV2KeysPrefix = "/v2/keys" -) - -// NewKeysAPI builds a KeysAPI that interacts with etcd's key-value -// API over HTTP. -func NewKeysAPI(c Client) KeysAPI { - return NewKeysAPIWithPrefix(c, defaultV2KeysPrefix) -} - -// NewKeysAPIWithPrefix acts like NewKeysAPI, but allows the caller -// to provide a custom base URL path. This should only be used in -// very rare cases. -func NewKeysAPIWithPrefix(c Client, p string) KeysAPI { - return &httpKeysAPI{ - client: c, - prefix: p, - } -} - -type KeysAPI interface { - // Get retrieves a set of Nodes from etcd - Get(ctx context.Context, key string, opts *GetOptions) (*Response, error) - - // Set assigns a new value to a Node identified by a given key. The caller - // may define a set of conditions in the SetOptions. If SetOptions.Dir=true - // then value is ignored. - Set(ctx context.Context, key, value string, opts *SetOptions) (*Response, error) - - // Delete removes a Node identified by the given key, optionally destroying - // all of its children as well. The caller may define a set of required - // conditions in an DeleteOptions object. - Delete(ctx context.Context, key string, opts *DeleteOptions) (*Response, error) - - // Create is an alias for Set w/ PrevExist=false - Create(ctx context.Context, key, value string) (*Response, error) - - // CreateInOrder is used to atomically create in-order keys within the given directory. - CreateInOrder(ctx context.Context, dir, value string, opts *CreateInOrderOptions) (*Response, error) - - // Update is an alias for Set w/ PrevExist=true - Update(ctx context.Context, key, value string) (*Response, error) - - // Watcher builds a new Watcher targeted at a specific Node identified - // by the given key. The Watcher may be configured at creation time - // through a WatcherOptions object. The returned Watcher is designed - // to emit events that happen to a Node, and optionally to its children. - Watcher(key string, opts *WatcherOptions) Watcher -} - -type WatcherOptions struct { - // AfterIndex defines the index after-which the Watcher should - // start emitting events. For example, if a value of 5 is - // provided, the first event will have an index >= 6. - // - // Setting AfterIndex to 0 (default) means that the Watcher - // should start watching for events starting at the current - // index, whatever that may be. - AfterIndex uint64 - - // Recursive specifies whether or not the Watcher should emit - // events that occur in children of the given keyspace. If set - // to false (default), events will be limited to those that - // occur for the exact key. - Recursive bool -} - -type CreateInOrderOptions struct { - // TTL defines a period of time after-which the Node should - // expire and no longer exist. Values <= 0 are ignored. Given - // that the zero-value is ignored, TTL cannot be used to set - // a TTL of 0. - TTL time.Duration -} - -type SetOptions struct { - // PrevValue specifies what the current value of the Node must - // be in order for the Set operation to succeed. - // - // Leaving this field empty means that the caller wishes to - // ignore the current value of the Node. This cannot be used - // to compare the Node's current value to an empty string. - // - // PrevValue is ignored if Dir=true - PrevValue string - - // PrevIndex indicates what the current ModifiedIndex of the - // Node must be in order for the Set operation to succeed. - // - // If PrevIndex is set to 0 (default), no comparison is made. - PrevIndex uint64 - - // PrevExist specifies whether the Node must currently exist - // (PrevExist) or not (PrevNoExist). If the caller does not - // care about existence, set PrevExist to PrevIgnore, or simply - // leave it unset. - PrevExist PrevExistType - - // TTL defines a period of time after-which the Node should - // expire and no longer exist. Values <= 0 are ignored. Given - // that the zero-value is ignored, TTL cannot be used to set - // a TTL of 0. - TTL time.Duration - - // Refresh set to true means a TTL value can be updated - // without firing a watch or changing the node value. A - // value must not be provided when refreshing a key. - Refresh bool - - // Dir specifies whether or not this Node should be created as a directory. - Dir bool - - // NoValueOnSuccess specifies whether the response contains the current value of the Node. - // If set, the response will only contain the current value when the request fails. - NoValueOnSuccess bool -} - -type GetOptions struct { - // Recursive defines whether or not all children of the Node - // should be returned. - Recursive bool - - // Sort instructs the server whether or not to sort the Nodes. - // If true, the Nodes are sorted alphabetically by key in - // ascending order (A to z). If false (default), the Nodes will - // not be sorted and the ordering used should not be considered - // predictable. - Sort bool - - // Quorum specifies whether it gets the latest committed value that - // has been applied in quorum of members, which ensures external - // consistency (or linearizability). - Quorum bool -} - -type DeleteOptions struct { - // PrevValue specifies what the current value of the Node must - // be in order for the Delete operation to succeed. - // - // Leaving this field empty means that the caller wishes to - // ignore the current value of the Node. This cannot be used - // to compare the Node's current value to an empty string. - PrevValue string - - // PrevIndex indicates what the current ModifiedIndex of the - // Node must be in order for the Delete operation to succeed. - // - // If PrevIndex is set to 0 (default), no comparison is made. - PrevIndex uint64 - - // Recursive defines whether or not all children of the Node - // should be deleted. If set to true, all children of the Node - // identified by the given key will be deleted. If left unset - // or explicitly set to false, only a single Node will be - // deleted. - Recursive bool - - // Dir specifies whether or not this Node should be removed as a directory. - Dir bool -} - -type Watcher interface { - // Next blocks until an etcd event occurs, then returns a Response - // representing that event. The behavior of Next depends on the - // WatcherOptions used to construct the Watcher. Next is designed to - // be called repeatedly, each time blocking until a subsequent event - // is available. - // - // If the provided context is cancelled, Next will return a non-nil - // error. Any other failures encountered while waiting for the next - // event (connection issues, deserialization failures, etc) will - // also result in a non-nil error. - Next(context.Context) (*Response, error) -} - -type Response struct { - // Action is the name of the operation that occurred. Possible values - // include get, set, delete, update, create, compareAndSwap, - // compareAndDelete and expire. - Action string `json:"action"` - - // Node represents the state of the relevant etcd Node. - Node *Node `json:"node"` - - // PrevNode represents the previous state of the Node. PrevNode is non-nil - // only if the Node existed before the action occurred and the action - // caused a change to the Node. - PrevNode *Node `json:"prevNode"` - - // Index holds the cluster-level index at the time the Response was generated. - // This index is not tied to the Node(s) contained in this Response. - Index uint64 `json:"-"` - - // ClusterID holds the cluster-level ID reported by the server. This - // should be different for different etcd clusters. - ClusterID string `json:"-"` -} - -type Node struct { - // Key represents the unique location of this Node (e.g. "/foo/bar"). - Key string `json:"key"` - - // Dir reports whether node describes a directory. - Dir bool `json:"dir,omitempty"` - - // Value is the current data stored on this Node. If this Node - // is a directory, Value will be empty. - Value string `json:"value"` - - // Nodes holds the children of this Node, only if this Node is a directory. - // This slice of will be arbitrarily deep (children, grandchildren, great- - // grandchildren, etc.) if a recursive Get or Watch request were made. - Nodes Nodes `json:"nodes"` - - // CreatedIndex is the etcd index at-which this Node was created. - CreatedIndex uint64 `json:"createdIndex"` - - // ModifiedIndex is the etcd index at-which this Node was last modified. - ModifiedIndex uint64 `json:"modifiedIndex"` - - // Expiration is the server side expiration time of the key. - Expiration *time.Time `json:"expiration,omitempty"` - - // TTL is the time to live of the key in second. - TTL int64 `json:"ttl,omitempty"` -} - -func (n *Node) String() string { - return fmt.Sprintf("{Key: %s, CreatedIndex: %d, ModifiedIndex: %d, TTL: %d}", n.Key, n.CreatedIndex, n.ModifiedIndex, n.TTL) -} - -// TTLDuration returns the Node's TTL as a time.Duration object -func (n *Node) TTLDuration() time.Duration { - return time.Duration(n.TTL) * time.Second -} - -type Nodes []*Node - -// interfaces for sorting - -func (ns Nodes) Len() int { return len(ns) } -func (ns Nodes) Less(i, j int) bool { return ns[i].Key < ns[j].Key } -func (ns Nodes) Swap(i, j int) { ns[i], ns[j] = ns[j], ns[i] } - -type httpKeysAPI struct { - client httpClient - prefix string -} - -func (k *httpKeysAPI) Set(ctx context.Context, key, val string, opts *SetOptions) (*Response, error) { - act := &setAction{ - Prefix: k.prefix, - Key: key, - Value: val, - } - - if opts != nil { - act.PrevValue = opts.PrevValue - act.PrevIndex = opts.PrevIndex - act.PrevExist = opts.PrevExist - act.TTL = opts.TTL - act.Refresh = opts.Refresh - act.Dir = opts.Dir - act.NoValueOnSuccess = opts.NoValueOnSuccess - } - - doCtx := ctx - if act.PrevExist == PrevNoExist { - doCtx = context.WithValue(doCtx, &oneShotCtxValue, &oneShotCtxValue) - } - resp, body, err := k.client.Do(doCtx, act) - if err != nil { - return nil, err - } - - return unmarshalHTTPResponse(resp.StatusCode, resp.Header, body) -} - -func (k *httpKeysAPI) Create(ctx context.Context, key, val string) (*Response, error) { - return k.Set(ctx, key, val, &SetOptions{PrevExist: PrevNoExist}) -} - -func (k *httpKeysAPI) CreateInOrder(ctx context.Context, dir, val string, opts *CreateInOrderOptions) (*Response, error) { - act := &createInOrderAction{ - Prefix: k.prefix, - Dir: dir, - Value: val, - } - - if opts != nil { - act.TTL = opts.TTL - } - - resp, body, err := k.client.Do(ctx, act) - if err != nil { - return nil, err - } - - return unmarshalHTTPResponse(resp.StatusCode, resp.Header, body) -} - -func (k *httpKeysAPI) Update(ctx context.Context, key, val string) (*Response, error) { - return k.Set(ctx, key, val, &SetOptions{PrevExist: PrevExist}) -} - -func (k *httpKeysAPI) Delete(ctx context.Context, key string, opts *DeleteOptions) (*Response, error) { - act := &deleteAction{ - Prefix: k.prefix, - Key: key, - } - - if opts != nil { - act.PrevValue = opts.PrevValue - act.PrevIndex = opts.PrevIndex - act.Dir = opts.Dir - act.Recursive = opts.Recursive - } - - doCtx := context.WithValue(ctx, &oneShotCtxValue, &oneShotCtxValue) - resp, body, err := k.client.Do(doCtx, act) - if err != nil { - return nil, err - } - - return unmarshalHTTPResponse(resp.StatusCode, resp.Header, body) -} - -func (k *httpKeysAPI) Get(ctx context.Context, key string, opts *GetOptions) (*Response, error) { - act := &getAction{ - Prefix: k.prefix, - Key: key, - } - - if opts != nil { - act.Recursive = opts.Recursive - act.Sorted = opts.Sort - act.Quorum = opts.Quorum - } - - resp, body, err := k.client.Do(ctx, act) - if err != nil { - return nil, err - } - - return unmarshalHTTPResponse(resp.StatusCode, resp.Header, body) -} - -func (k *httpKeysAPI) Watcher(key string, opts *WatcherOptions) Watcher { - act := waitAction{ - Prefix: k.prefix, - Key: key, - } - - if opts != nil { - act.Recursive = opts.Recursive - if opts.AfterIndex > 0 { - act.WaitIndex = opts.AfterIndex + 1 - } - } - - return &httpWatcher{ - client: k.client, - nextWait: act, - } -} - -type httpWatcher struct { - client httpClient - nextWait waitAction -} - -func (hw *httpWatcher) Next(ctx context.Context) (*Response, error) { - for { - httpresp, body, err := hw.client.Do(ctx, &hw.nextWait) - if err != nil { - return nil, err - } - - resp, err := unmarshalHTTPResponse(httpresp.StatusCode, httpresp.Header, body) - if err != nil { - if err == ErrEmptyBody { - continue - } - return nil, err - } - - hw.nextWait.WaitIndex = resp.Node.ModifiedIndex + 1 - return resp, nil - } -} - -// v2KeysURL forms a URL representing the location of a key. -// The endpoint argument represents the base URL of an etcd -// server. The prefix is the path needed to route from the -// provided endpoint's path to the root of the keys API -// (typically "/v2/keys"). -func v2KeysURL(ep url.URL, prefix, key string) *url.URL { - // We concatenate all parts together manually. We cannot use - // path.Join because it does not reserve trailing slash. - // We call CanonicalURLPath to further cleanup the path. - if prefix != "" && prefix[0] != '/' { - prefix = "/" + prefix - } - if key != "" && key[0] != '/' { - key = "/" + key - } - ep.Path = pathutil.CanonicalURLPath(ep.Path + prefix + key) - return &ep -} - -type getAction struct { - Prefix string - Key string - Recursive bool - Sorted bool - Quorum bool -} - -func (g *getAction) HTTPRequest(ep url.URL) *http.Request { - u := v2KeysURL(ep, g.Prefix, g.Key) - - params := u.Query() - params.Set("recursive", strconv.FormatBool(g.Recursive)) - params.Set("sorted", strconv.FormatBool(g.Sorted)) - params.Set("quorum", strconv.FormatBool(g.Quorum)) - u.RawQuery = params.Encode() - - req, _ := http.NewRequest("GET", u.String(), nil) - return req -} - -type waitAction struct { - Prefix string - Key string - WaitIndex uint64 - Recursive bool -} - -func (w *waitAction) HTTPRequest(ep url.URL) *http.Request { - u := v2KeysURL(ep, w.Prefix, w.Key) - - params := u.Query() - params.Set("wait", "true") - params.Set("waitIndex", strconv.FormatUint(w.WaitIndex, 10)) - params.Set("recursive", strconv.FormatBool(w.Recursive)) - u.RawQuery = params.Encode() - - req, _ := http.NewRequest("GET", u.String(), nil) - return req -} - -type setAction struct { - Prefix string - Key string - Value string - PrevValue string - PrevIndex uint64 - PrevExist PrevExistType - TTL time.Duration - Refresh bool - Dir bool - NoValueOnSuccess bool -} - -func (a *setAction) HTTPRequest(ep url.URL) *http.Request { - u := v2KeysURL(ep, a.Prefix, a.Key) - - params := u.Query() - form := url.Values{} - - // we're either creating a directory or setting a key - if a.Dir { - params.Set("dir", strconv.FormatBool(a.Dir)) - } else { - // These options are only valid for setting a key - if a.PrevValue != "" { - params.Set("prevValue", a.PrevValue) - } - form.Add("value", a.Value) - } - - // Options which apply to both setting a key and creating a dir - if a.PrevIndex != 0 { - params.Set("prevIndex", strconv.FormatUint(a.PrevIndex, 10)) - } - if a.PrevExist != PrevIgnore { - params.Set("prevExist", string(a.PrevExist)) - } - if a.TTL > 0 { - form.Add("ttl", strconv.FormatUint(uint64(a.TTL.Seconds()), 10)) - } - - if a.Refresh { - form.Add("refresh", "true") - } - if a.NoValueOnSuccess { - params.Set("noValueOnSuccess", strconv.FormatBool(a.NoValueOnSuccess)) - } - - u.RawQuery = params.Encode() - body := strings.NewReader(form.Encode()) - - req, _ := http.NewRequest("PUT", u.String(), body) - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - - return req -} - -type deleteAction struct { - Prefix string - Key string - PrevValue string - PrevIndex uint64 - Dir bool - Recursive bool -} - -func (a *deleteAction) HTTPRequest(ep url.URL) *http.Request { - u := v2KeysURL(ep, a.Prefix, a.Key) - - params := u.Query() - if a.PrevValue != "" { - params.Set("prevValue", a.PrevValue) - } - if a.PrevIndex != 0 { - params.Set("prevIndex", strconv.FormatUint(a.PrevIndex, 10)) - } - if a.Dir { - params.Set("dir", "true") - } - if a.Recursive { - params.Set("recursive", "true") - } - u.RawQuery = params.Encode() - - req, _ := http.NewRequest("DELETE", u.String(), nil) - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - - return req -} - -type createInOrderAction struct { - Prefix string - Dir string - Value string - TTL time.Duration -} - -func (a *createInOrderAction) HTTPRequest(ep url.URL) *http.Request { - u := v2KeysURL(ep, a.Prefix, a.Dir) - - form := url.Values{} - form.Add("value", a.Value) - if a.TTL > 0 { - form.Add("ttl", strconv.FormatUint(uint64(a.TTL.Seconds()), 10)) - } - body := strings.NewReader(form.Encode()) - - req, _ := http.NewRequest("POST", u.String(), body) - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - return req -} - -func unmarshalHTTPResponse(code int, header http.Header, body []byte) (res *Response, err error) { - switch code { - case http.StatusOK, http.StatusCreated: - if len(body) == 0 { - return nil, ErrEmptyBody - } - res, err = unmarshalSuccessfulKeysResponse(header, body) - default: - err = unmarshalFailedKeysResponse(body) - } - return res, err -} - -var jsonIterator = caseSensitiveJsonIterator() - -func unmarshalSuccessfulKeysResponse(header http.Header, body []byte) (*Response, error) { - var res Response - err := jsonIterator.Unmarshal(body, &res) - if err != nil { - return nil, ErrInvalidJSON - } - if header.Get("X-Etcd-Index") != "" { - res.Index, err = strconv.ParseUint(header.Get("X-Etcd-Index"), 10, 64) - if err != nil { - return nil, err - } - } - res.ClusterID = header.Get("X-Etcd-Cluster-ID") - return &res, nil -} - -func unmarshalFailedKeysResponse(body []byte) error { - var etcdErr Error - if err := json.Unmarshal(body, &etcdErr); err != nil { - return ErrInvalidJSON - } - return etcdErr -} diff --git a/vendor/go.etcd.io/etcd/client/members.go b/vendor/go.etcd.io/etcd/client/members.go deleted file mode 100644 index 657131ab0ce03..0000000000000 --- a/vendor/go.etcd.io/etcd/client/members.go +++ /dev/null @@ -1,303 +0,0 @@ -// Copyright 2015 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package client - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "net/http" - "net/url" - "path" - - "go.etcd.io/etcd/pkg/types" -) - -var ( - defaultV2MembersPrefix = "/v2/members" - defaultLeaderSuffix = "/leader" -) - -type Member struct { - // ID is the unique identifier of this Member. - ID string `json:"id"` - - // Name is a human-readable, non-unique identifier of this Member. - Name string `json:"name"` - - // PeerURLs represents the HTTP(S) endpoints this Member uses to - // participate in etcd's consensus protocol. - PeerURLs []string `json:"peerURLs"` - - // ClientURLs represents the HTTP(S) endpoints on which this Member - // serves its client-facing APIs. - ClientURLs []string `json:"clientURLs"` -} - -type memberCollection []Member - -func (c *memberCollection) UnmarshalJSON(data []byte) error { - d := struct { - Members []Member - }{} - - if err := json.Unmarshal(data, &d); err != nil { - return err - } - - if d.Members == nil { - *c = make([]Member, 0) - return nil - } - - *c = d.Members - return nil -} - -type memberCreateOrUpdateRequest struct { - PeerURLs types.URLs -} - -func (m *memberCreateOrUpdateRequest) MarshalJSON() ([]byte, error) { - s := struct { - PeerURLs []string `json:"peerURLs"` - }{ - PeerURLs: make([]string, len(m.PeerURLs)), - } - - for i, u := range m.PeerURLs { - s.PeerURLs[i] = u.String() - } - - return json.Marshal(&s) -} - -// NewMembersAPI constructs a new MembersAPI that uses HTTP to -// interact with etcd's membership API. -func NewMembersAPI(c Client) MembersAPI { - return &httpMembersAPI{ - client: c, - } -} - -type MembersAPI interface { - // List enumerates the current cluster membership. - List(ctx context.Context) ([]Member, error) - - // Add instructs etcd to accept a new Member into the cluster. - Add(ctx context.Context, peerURL string) (*Member, error) - - // Remove demotes an existing Member out of the cluster. - Remove(ctx context.Context, mID string) error - - // Update instructs etcd to update an existing Member in the cluster. - Update(ctx context.Context, mID string, peerURLs []string) error - - // Leader gets current leader of the cluster - Leader(ctx context.Context) (*Member, error) -} - -type httpMembersAPI struct { - client httpClient -} - -func (m *httpMembersAPI) List(ctx context.Context) ([]Member, error) { - req := &membersAPIActionList{} - resp, body, err := m.client.Do(ctx, req) - if err != nil { - return nil, err - } - - if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { - return nil, err - } - - var mCollection memberCollection - if err := json.Unmarshal(body, &mCollection); err != nil { - return nil, err - } - - return []Member(mCollection), nil -} - -func (m *httpMembersAPI) Add(ctx context.Context, peerURL string) (*Member, error) { - urls, err := types.NewURLs([]string{peerURL}) - if err != nil { - return nil, err - } - - req := &membersAPIActionAdd{peerURLs: urls} - resp, body, err := m.client.Do(ctx, req) - if err != nil { - return nil, err - } - - if err := assertStatusCode(resp.StatusCode, http.StatusCreated, http.StatusConflict); err != nil { - return nil, err - } - - if resp.StatusCode != http.StatusCreated { - var merr membersError - if err := json.Unmarshal(body, &merr); err != nil { - return nil, err - } - return nil, merr - } - - var memb Member - if err := json.Unmarshal(body, &memb); err != nil { - return nil, err - } - - return &memb, nil -} - -func (m *httpMembersAPI) Update(ctx context.Context, memberID string, peerURLs []string) error { - urls, err := types.NewURLs(peerURLs) - if err != nil { - return err - } - - req := &membersAPIActionUpdate{peerURLs: urls, memberID: memberID} - resp, body, err := m.client.Do(ctx, req) - if err != nil { - return err - } - - if err := assertStatusCode(resp.StatusCode, http.StatusNoContent, http.StatusNotFound, http.StatusConflict); err != nil { - return err - } - - if resp.StatusCode != http.StatusNoContent { - var merr membersError - if err := json.Unmarshal(body, &merr); err != nil { - return err - } - return merr - } - - return nil -} - -func (m *httpMembersAPI) Remove(ctx context.Context, memberID string) error { - req := &membersAPIActionRemove{memberID: memberID} - resp, _, err := m.client.Do(ctx, req) - if err != nil { - return err - } - - return assertStatusCode(resp.StatusCode, http.StatusNoContent, http.StatusGone) -} - -func (m *httpMembersAPI) Leader(ctx context.Context) (*Member, error) { - req := &membersAPIActionLeader{} - resp, body, err := m.client.Do(ctx, req) - if err != nil { - return nil, err - } - - if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { - return nil, err - } - - var leader Member - if err := json.Unmarshal(body, &leader); err != nil { - return nil, err - } - - return &leader, nil -} - -type membersAPIActionList struct{} - -func (l *membersAPIActionList) HTTPRequest(ep url.URL) *http.Request { - u := v2MembersURL(ep) - req, _ := http.NewRequest("GET", u.String(), nil) - return req -} - -type membersAPIActionRemove struct { - memberID string -} - -func (d *membersAPIActionRemove) HTTPRequest(ep url.URL) *http.Request { - u := v2MembersURL(ep) - u.Path = path.Join(u.Path, d.memberID) - req, _ := http.NewRequest("DELETE", u.String(), nil) - return req -} - -type membersAPIActionAdd struct { - peerURLs types.URLs -} - -func (a *membersAPIActionAdd) HTTPRequest(ep url.URL) *http.Request { - u := v2MembersURL(ep) - m := memberCreateOrUpdateRequest{PeerURLs: a.peerURLs} - b, _ := json.Marshal(&m) - req, _ := http.NewRequest("POST", u.String(), bytes.NewReader(b)) - req.Header.Set("Content-Type", "application/json") - return req -} - -type membersAPIActionUpdate struct { - memberID string - peerURLs types.URLs -} - -func (a *membersAPIActionUpdate) HTTPRequest(ep url.URL) *http.Request { - u := v2MembersURL(ep) - m := memberCreateOrUpdateRequest{PeerURLs: a.peerURLs} - u.Path = path.Join(u.Path, a.memberID) - b, _ := json.Marshal(&m) - req, _ := http.NewRequest("PUT", u.String(), bytes.NewReader(b)) - req.Header.Set("Content-Type", "application/json") - return req -} - -func assertStatusCode(got int, want ...int) (err error) { - for _, w := range want { - if w == got { - return nil - } - } - return fmt.Errorf("unexpected status code %d", got) -} - -type membersAPIActionLeader struct{} - -func (l *membersAPIActionLeader) HTTPRequest(ep url.URL) *http.Request { - u := v2MembersURL(ep) - u.Path = path.Join(u.Path, defaultLeaderSuffix) - req, _ := http.NewRequest("GET", u.String(), nil) - return req -} - -// v2MembersURL add the necessary path to the provided endpoint -// to route requests to the default v2 members API. -func v2MembersURL(ep url.URL) *url.URL { - ep.Path = path.Join(ep.Path, defaultV2MembersPrefix) - return &ep -} - -type membersError struct { - Message string `json:"message"` - Code int `json:"-"` -} - -func (e membersError) Error() string { - return e.Message -} diff --git a/vendor/go.etcd.io/etcd/client/util.go b/vendor/go.etcd.io/etcd/client/util.go deleted file mode 100644 index 15a8babff4d4f..0000000000000 --- a/vendor/go.etcd.io/etcd/client/util.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2016 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package client - -import ( - "regexp" -) - -var ( - roleNotFoundRegExp *regexp.Regexp - userNotFoundRegExp *regexp.Regexp -) - -func init() { - roleNotFoundRegExp = regexp.MustCompile("auth: Role .* does not exist.") - userNotFoundRegExp = regexp.MustCompile("auth: User .* does not exist.") -} - -// IsKeyNotFound returns true if the error code is ErrorCodeKeyNotFound. -func IsKeyNotFound(err error) bool { - if cErr, ok := err.(Error); ok { - return cErr.Code == ErrorCodeKeyNotFound - } - return false -} - -// IsRoleNotFound returns true if the error means role not found of v2 API. -func IsRoleNotFound(err error) bool { - if ae, ok := err.(authError); ok { - return roleNotFoundRegExp.MatchString(ae.Message) - } - return false -} - -// IsUserNotFound returns true if the error means user not found of v2 API. -func IsUserNotFound(err error) bool { - if ae, ok := err.(authError); ok { - return userNotFoundRegExp.MatchString(ae.Message) - } - return false -} diff --git a/vendor/go.etcd.io/etcd/pkg/pathutil/BUILD.bazel b/vendor/go.etcd.io/etcd/pkg/pathutil/BUILD.bazel deleted file mode 100644 index 0336e9e60b206..0000000000000 --- a/vendor/go.etcd.io/etcd/pkg/pathutil/BUILD.bazel +++ /dev/null @@ -1,9 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["path.go"], - importmap = "k8s.io/kops/vendor/go.etcd.io/etcd/pkg/pathutil", - importpath = "go.etcd.io/etcd/pkg/pathutil", - visibility = ["//visibility:public"], -) diff --git a/vendor/go.etcd.io/etcd/pkg/pathutil/path.go b/vendor/go.etcd.io/etcd/pkg/pathutil/path.go deleted file mode 100644 index f26254ba933eb..0000000000000 --- a/vendor/go.etcd.io/etcd/pkg/pathutil/path.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package pathutil implements utility functions for handling slash-separated -// paths. -package pathutil - -import "path" - -// CanonicalURLPath returns the canonical url path for p, which follows the rules: -// 1. the path always starts with "/" -// 2. replace multiple slashes with a single slash -// 3. replace each '.' '..' path name element with equivalent one -// 4. keep the trailing slash -// The function is borrowed from stdlib http.cleanPath in server.go. -func CanonicalURLPath(p string) string { - if p == "" { - return "/" - } - if p[0] != '/' { - p = "/" + p - } - np := path.Clean(p) - // path.Clean removes trailing slash except for root, - // put the trailing slash back if necessary. - if p[len(p)-1] == '/' && np != "/" { - np += "/" - } - return np -} diff --git a/vendor/go.etcd.io/etcd/pkg/srv/BUILD.bazel b/vendor/go.etcd.io/etcd/pkg/srv/BUILD.bazel deleted file mode 100644 index 06d968e2c6fd2..0000000000000 --- a/vendor/go.etcd.io/etcd/pkg/srv/BUILD.bazel +++ /dev/null @@ -1,10 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["srv.go"], - importmap = "k8s.io/kops/vendor/go.etcd.io/etcd/pkg/srv", - importpath = "go.etcd.io/etcd/pkg/srv", - visibility = ["//visibility:public"], - deps = ["//vendor/go.etcd.io/etcd/pkg/types:go_default_library"], -) diff --git a/vendor/go.etcd.io/etcd/pkg/srv/srv.go b/vendor/go.etcd.io/etcd/pkg/srv/srv.go deleted file mode 100644 index c3560026d4817..0000000000000 --- a/vendor/go.etcd.io/etcd/pkg/srv/srv.go +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright 2015 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package srv looks up DNS SRV records. -package srv - -import ( - "fmt" - "net" - "net/url" - "strings" - - "go.etcd.io/etcd/pkg/types" -) - -var ( - // indirection for testing - lookupSRV = net.LookupSRV // net.DefaultResolver.LookupSRV when ctxs don't conflict - resolveTCPAddr = net.ResolveTCPAddr -) - -// GetCluster gets the cluster information via DNS discovery. -// Also sees each entry as a separate instance. -func GetCluster(serviceScheme, service, name, dns string, apurls types.URLs) ([]string, error) { - tempName := int(0) - tcp2ap := make(map[string]url.URL) - - // First, resolve the apurls - for _, url := range apurls { - tcpAddr, err := resolveTCPAddr("tcp", url.Host) - if err != nil { - return nil, err - } - tcp2ap[tcpAddr.String()] = url - } - - stringParts := []string{} - updateNodeMap := func(service, scheme string) error { - _, addrs, err := lookupSRV(service, "tcp", dns) - if err != nil { - return err - } - for _, srv := range addrs { - port := fmt.Sprintf("%d", srv.Port) - host := net.JoinHostPort(srv.Target, port) - tcpAddr, terr := resolveTCPAddr("tcp", host) - if terr != nil { - err = terr - continue - } - n := "" - url, ok := tcp2ap[tcpAddr.String()] - if ok { - n = name - } - if n == "" { - n = fmt.Sprintf("%d", tempName) - tempName++ - } - // SRV records have a trailing dot but URL shouldn't. - shortHost := strings.TrimSuffix(srv.Target, ".") - urlHost := net.JoinHostPort(shortHost, port) - if ok && url.Scheme != scheme { - err = fmt.Errorf("bootstrap at %s from DNS for %s has scheme mismatch with expected peer %s", scheme+"://"+urlHost, service, url.String()) - } else { - stringParts = append(stringParts, fmt.Sprintf("%s=%s://%s", n, scheme, urlHost)) - } - } - if len(stringParts) == 0 { - return err - } - return nil - } - - err := updateNodeMap(service, serviceScheme) - if err != nil { - return nil, fmt.Errorf("error querying DNS SRV records for _%s %s", service, err) - } - return stringParts, nil -} - -type SRVClients struct { - Endpoints []string - SRVs []*net.SRV -} - -// GetClient looks up the client endpoints for a service and domain. -func GetClient(service, domain string, serviceName string) (*SRVClients, error) { - var urls []*url.URL - var srvs []*net.SRV - - updateURLs := func(service, scheme string) error { - _, addrs, err := lookupSRV(service, "tcp", domain) - if err != nil { - return err - } - for _, srv := range addrs { - urls = append(urls, &url.URL{ - Scheme: scheme, - Host: net.JoinHostPort(srv.Target, fmt.Sprintf("%d", srv.Port)), - }) - } - srvs = append(srvs, addrs...) - return nil - } - - errHTTPS := updateURLs(GetSRVService(service, serviceName, "https"), "https") - errHTTP := updateURLs(GetSRVService(service, serviceName, "http"), "http") - - if errHTTPS != nil && errHTTP != nil { - return nil, fmt.Errorf("dns lookup errors: %s and %s", errHTTPS, errHTTP) - } - - endpoints := make([]string, len(urls)) - for i := range urls { - endpoints[i] = urls[i].String() - } - return &SRVClients{Endpoints: endpoints, SRVs: srvs}, nil -} - -// GetSRVService generates a SRV service including an optional suffix. -func GetSRVService(service, serviceName string, scheme string) (SRVService string) { - if scheme == "https" { - service = fmt.Sprintf("%s-ssl", service) - } - - if serviceName != "" { - return fmt.Sprintf("%s-%s", service, serviceName) - } - return service -} diff --git a/vendor/go.etcd.io/etcd/pkg/types/BUILD.bazel b/vendor/go.etcd.io/etcd/pkg/types/BUILD.bazel deleted file mode 100644 index 5d76e4bb3efdb..0000000000000 --- a/vendor/go.etcd.io/etcd/pkg/types/BUILD.bazel +++ /dev/null @@ -1,16 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = [ - "doc.go", - "id.go", - "set.go", - "slice.go", - "urls.go", - "urlsmap.go", - ], - importmap = "k8s.io/kops/vendor/go.etcd.io/etcd/pkg/types", - importpath = "go.etcd.io/etcd/pkg/types", - visibility = ["//visibility:public"], -) diff --git a/vendor/go.etcd.io/etcd/pkg/types/doc.go b/vendor/go.etcd.io/etcd/pkg/types/doc.go deleted file mode 100644 index de8ef0bd71266..0000000000000 --- a/vendor/go.etcd.io/etcd/pkg/types/doc.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2015 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package types declares various data types and implements type-checking -// functions. -package types diff --git a/vendor/go.etcd.io/etcd/pkg/types/id.go b/vendor/go.etcd.io/etcd/pkg/types/id.go deleted file mode 100644 index ae00388dde06c..0000000000000 --- a/vendor/go.etcd.io/etcd/pkg/types/id.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2015 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package types - -import "strconv" - -// ID represents a generic identifier which is canonically -// stored as a uint64 but is typically represented as a -// base-16 string for input/output -type ID uint64 - -func (i ID) String() string { - return strconv.FormatUint(uint64(i), 16) -} - -// IDFromString attempts to create an ID from a base-16 string. -func IDFromString(s string) (ID, error) { - i, err := strconv.ParseUint(s, 16, 64) - return ID(i), err -} - -// IDSlice implements the sort interface -type IDSlice []ID - -func (p IDSlice) Len() int { return len(p) } -func (p IDSlice) Less(i, j int) bool { return uint64(p[i]) < uint64(p[j]) } -func (p IDSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } diff --git a/vendor/go.etcd.io/etcd/pkg/types/set.go b/vendor/go.etcd.io/etcd/pkg/types/set.go deleted file mode 100644 index e7a3cdc9ab6d6..0000000000000 --- a/vendor/go.etcd.io/etcd/pkg/types/set.go +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright 2015 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package types - -import ( - "reflect" - "sort" - "sync" -) - -type Set interface { - Add(string) - Remove(string) - Contains(string) bool - Equals(Set) bool - Length() int - Values() []string - Copy() Set - Sub(Set) Set -} - -func NewUnsafeSet(values ...string) *unsafeSet { - set := &unsafeSet{make(map[string]struct{})} - for _, v := range values { - set.Add(v) - } - return set -} - -func NewThreadsafeSet(values ...string) *tsafeSet { - us := NewUnsafeSet(values...) - return &tsafeSet{us, sync.RWMutex{}} -} - -type unsafeSet struct { - d map[string]struct{} -} - -// Add adds a new value to the set (no-op if the value is already present) -func (us *unsafeSet) Add(value string) { - us.d[value] = struct{}{} -} - -// Remove removes the given value from the set -func (us *unsafeSet) Remove(value string) { - delete(us.d, value) -} - -// Contains returns whether the set contains the given value -func (us *unsafeSet) Contains(value string) (exists bool) { - _, exists = us.d[value] - return exists -} - -// ContainsAll returns whether the set contains all given values -func (us *unsafeSet) ContainsAll(values []string) bool { - for _, s := range values { - if !us.Contains(s) { - return false - } - } - return true -} - -// Equals returns whether the contents of two sets are identical -func (us *unsafeSet) Equals(other Set) bool { - v1 := sort.StringSlice(us.Values()) - v2 := sort.StringSlice(other.Values()) - v1.Sort() - v2.Sort() - return reflect.DeepEqual(v1, v2) -} - -// Length returns the number of elements in the set -func (us *unsafeSet) Length() int { - return len(us.d) -} - -// Values returns the values of the Set in an unspecified order. -func (us *unsafeSet) Values() (values []string) { - values = make([]string, 0) - for val := range us.d { - values = append(values, val) - } - return values -} - -// Copy creates a new Set containing the values of the first -func (us *unsafeSet) Copy() Set { - cp := NewUnsafeSet() - for val := range us.d { - cp.Add(val) - } - - return cp -} - -// Sub removes all elements in other from the set -func (us *unsafeSet) Sub(other Set) Set { - oValues := other.Values() - result := us.Copy().(*unsafeSet) - - for _, val := range oValues { - if _, ok := result.d[val]; !ok { - continue - } - delete(result.d, val) - } - - return result -} - -type tsafeSet struct { - us *unsafeSet - m sync.RWMutex -} - -func (ts *tsafeSet) Add(value string) { - ts.m.Lock() - defer ts.m.Unlock() - ts.us.Add(value) -} - -func (ts *tsafeSet) Remove(value string) { - ts.m.Lock() - defer ts.m.Unlock() - ts.us.Remove(value) -} - -func (ts *tsafeSet) Contains(value string) (exists bool) { - ts.m.RLock() - defer ts.m.RUnlock() - return ts.us.Contains(value) -} - -func (ts *tsafeSet) Equals(other Set) bool { - ts.m.RLock() - defer ts.m.RUnlock() - - // If ts and other represent the same variable, avoid calling - // ts.us.Equals(other), to avoid double RLock bug - if _other, ok := other.(*tsafeSet); ok { - if _other == ts { - return true - } - } - return ts.us.Equals(other) -} - -func (ts *tsafeSet) Length() int { - ts.m.RLock() - defer ts.m.RUnlock() - return ts.us.Length() -} - -func (ts *tsafeSet) Values() (values []string) { - ts.m.RLock() - defer ts.m.RUnlock() - return ts.us.Values() -} - -func (ts *tsafeSet) Copy() Set { - ts.m.RLock() - defer ts.m.RUnlock() - usResult := ts.us.Copy().(*unsafeSet) - return &tsafeSet{usResult, sync.RWMutex{}} -} - -func (ts *tsafeSet) Sub(other Set) Set { - ts.m.RLock() - defer ts.m.RUnlock() - - // If ts and other represent the same variable, avoid calling - // ts.us.Sub(other), to avoid double RLock bug - if _other, ok := other.(*tsafeSet); ok { - if _other == ts { - usResult := NewUnsafeSet() - return &tsafeSet{usResult, sync.RWMutex{}} - } - } - usResult := ts.us.Sub(other).(*unsafeSet) - return &tsafeSet{usResult, sync.RWMutex{}} -} diff --git a/vendor/go.etcd.io/etcd/pkg/types/slice.go b/vendor/go.etcd.io/etcd/pkg/types/slice.go deleted file mode 100644 index 0dd9ca798ae42..0000000000000 --- a/vendor/go.etcd.io/etcd/pkg/types/slice.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2015 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package types - -// Uint64Slice implements sort interface -type Uint64Slice []uint64 - -func (p Uint64Slice) Len() int { return len(p) } -func (p Uint64Slice) Less(i, j int) bool { return p[i] < p[j] } -func (p Uint64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } diff --git a/vendor/go.etcd.io/etcd/pkg/types/urls.go b/vendor/go.etcd.io/etcd/pkg/types/urls.go deleted file mode 100644 index 9e5d03ff6457b..0000000000000 --- a/vendor/go.etcd.io/etcd/pkg/types/urls.go +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2015 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package types - -import ( - "errors" - "fmt" - "net" - "net/url" - "sort" - "strings" -) - -type URLs []url.URL - -func NewURLs(strs []string) (URLs, error) { - all := make([]url.URL, len(strs)) - if len(all) == 0 { - return nil, errors.New("no valid URLs given") - } - for i, in := range strs { - in = strings.TrimSpace(in) - u, err := url.Parse(in) - if err != nil { - return nil, err - } - if u.Scheme != "http" && u.Scheme != "https" && u.Scheme != "unix" && u.Scheme != "unixs" { - return nil, fmt.Errorf("URL scheme must be http, https, unix, or unixs: %s", in) - } - if _, _, err := net.SplitHostPort(u.Host); err != nil { - return nil, fmt.Errorf(`URL address does not have the form "host:port": %s`, in) - } - if u.Path != "" { - return nil, fmt.Errorf("URL must not contain a path: %s", in) - } - all[i] = *u - } - us := URLs(all) - us.Sort() - - return us, nil -} - -func MustNewURLs(strs []string) URLs { - urls, err := NewURLs(strs) - if err != nil { - panic(err) - } - return urls -} - -func (us URLs) String() string { - return strings.Join(us.StringSlice(), ",") -} - -func (us *URLs) Sort() { - sort.Sort(us) -} -func (us URLs) Len() int { return len(us) } -func (us URLs) Less(i, j int) bool { return us[i].String() < us[j].String() } -func (us URLs) Swap(i, j int) { us[i], us[j] = us[j], us[i] } - -func (us URLs) StringSlice() []string { - out := make([]string, len(us)) - for i := range us { - out[i] = us[i].String() - } - - return out -} diff --git a/vendor/go.etcd.io/etcd/pkg/types/urlsmap.go b/vendor/go.etcd.io/etcd/pkg/types/urlsmap.go deleted file mode 100644 index 47690cc381a35..0000000000000 --- a/vendor/go.etcd.io/etcd/pkg/types/urlsmap.go +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2015 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package types - -import ( - "fmt" - "sort" - "strings" -) - -// URLsMap is a map from a name to its URLs. -type URLsMap map[string]URLs - -// NewURLsMap returns a URLsMap instantiated from the given string, -// which consists of discovery-formatted names-to-URLs, like: -// mach0=http://1.1.1.1:2380,mach0=http://2.2.2.2::2380,mach1=http://3.3.3.3:2380,mach2=http://4.4.4.4:2380 -func NewURLsMap(s string) (URLsMap, error) { - m := parse(s) - - cl := URLsMap{} - for name, urls := range m { - us, err := NewURLs(urls) - if err != nil { - return nil, err - } - cl[name] = us - } - return cl, nil -} - -// NewURLsMapFromStringMap takes a map of strings and returns a URLsMap. The -// string values in the map can be multiple values separated by the sep string. -func NewURLsMapFromStringMap(m map[string]string, sep string) (URLsMap, error) { - var err error - um := URLsMap{} - for k, v := range m { - um[k], err = NewURLs(strings.Split(v, sep)) - if err != nil { - return nil, err - } - } - return um, nil -} - -// String turns URLsMap into discovery-formatted name-to-URLs sorted by name. -func (c URLsMap) String() string { - var pairs []string - for name, urls := range c { - for _, url := range urls { - pairs = append(pairs, fmt.Sprintf("%s=%s", name, url.String())) - } - } - sort.Strings(pairs) - return strings.Join(pairs, ",") -} - -// URLs returns a list of all URLs. -// The returned list is sorted in ascending lexicographical order. -func (c URLsMap) URLs() []string { - var urls []string - for _, us := range c { - for _, u := range us { - urls = append(urls, u.String()) - } - } - sort.Strings(urls) - return urls -} - -// Len returns the size of URLsMap. -func (c URLsMap) Len() int { - return len(c) -} - -// parse parses the given string and returns a map listing the values specified for each key. -func parse(s string) map[string][]string { - m := make(map[string][]string) - for s != "" { - key := s - if i := strings.IndexAny(key, ","); i >= 0 { - key, s = key[:i], key[i+1:] - } else { - s = "" - } - if key == "" { - continue - } - value := "" - if i := strings.Index(key, "="); i >= 0 { - key, value = key[:i], key[i+1:] - } - m[key] = append(m[key], value) - } - return m -} diff --git a/vendor/go.etcd.io/etcd/version/BUILD.bazel b/vendor/go.etcd.io/etcd/version/BUILD.bazel deleted file mode 100644 index 4b60925516468..0000000000000 --- a/vendor/go.etcd.io/etcd/version/BUILD.bazel +++ /dev/null @@ -1,10 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["version.go"], - importmap = "k8s.io/kops/vendor/go.etcd.io/etcd/version", - importpath = "go.etcd.io/etcd/version", - visibility = ["//visibility:public"], - deps = ["//vendor/github.com/coreos/go-semver/semver:go_default_library"], -) diff --git a/vendor/go.etcd.io/etcd/version/version.go b/vendor/go.etcd.io/etcd/version/version.go deleted file mode 100644 index ee97e461e7fa5..0000000000000 --- a/vendor/go.etcd.io/etcd/version/version.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2015 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package version implements etcd version parsing and contains latest version -// information. -package version - -import ( - "fmt" - "strings" - - "github.com/coreos/go-semver/semver" -) - -var ( - // MinClusterVersion is the min cluster version this etcd binary is compatible with. - MinClusterVersion = "3.0.0" - Version = "3.4.13" - APIVersion = "unknown" - - // Git SHA Value will be set during build - GitSHA = "Not provided (use ./build instead of go build)" -) - -func init() { - ver, err := semver.NewVersion(Version) - if err == nil { - APIVersion = fmt.Sprintf("%d.%d", ver.Major, ver.Minor) - } -} - -type Versions struct { - Server string `json:"etcdserver"` - Cluster string `json:"etcdcluster"` - // TODO: raft state machine version -} - -// Cluster only keeps the major.minor. -func Cluster(v string) string { - vs := strings.Split(v, ".") - if len(vs) <= 2 { - return v - } - return fmt.Sprintf("%s.%s", vs[0], vs[1]) -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 7dc400144f0e3..2a19c3a85089c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -171,8 +171,6 @@ github.com/chai2010/gettext-go/gettext/plural github.com/chai2010/gettext-go/gettext/po # github.com/containerd/containerd v1.3.4 github.com/containerd/containerd/errdefs -# github.com/coreos/go-semver v0.3.0 -github.com/coreos/go-semver/semver # github.com/cpuguy83/go-md2man/v2 v2.0.0 github.com/cpuguy83/go-md2man/v2/md2man # github.com/davecgh/go-spew v1.1.1 @@ -421,9 +419,6 @@ github.com/mailru/easyjson/jwriter github.com/mattn/go-ieproxy # github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 github.com/matttproud/golang_protobuf_extensions/pbutil -# github.com/miekg/coredns v0.0.0-20161111164017-20e25559d5ea -## explicit -github.com/miekg/coredns/middleware/etcd/msg # github.com/miekg/dns v1.1.4 github.com/miekg/dns # github.com/mitchellh/copystructure v1.0.0 @@ -550,13 +545,6 @@ github.com/zclconf/go-cty/cty/function/stdlib github.com/zclconf/go-cty/cty/gocty github.com/zclconf/go-cty/cty/json github.com/zclconf/go-cty/cty/set -# go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489 -## explicit -go.etcd.io/etcd/client -go.etcd.io/etcd/pkg/pathutil -go.etcd.io/etcd/pkg/srv -go.etcd.io/etcd/pkg/types -go.etcd.io/etcd/version # go.opencensus.io v0.22.3 go.opencensus.io go.opencensus.io/internal