Example #1
0
func init() {
	ctxt, _ = context.WithTimeout(context.Background(), etcdTimeout)

	etcdCfg := etcdc.Config{
		Endpoints: []string{"http://localhost:2379"},
	}
	cli, _ := etcdc.New(etcdCfg)
	etc = Etcd{
		Proxy:      proxy.New([]string{"8.8.8.8:53"}),
		PathPrefix: "skydns",
		Ctx:        context.Background(),
		Inflight:   &singleflight.Group{},
		Zones:      []string{"skydns.test.", "skydns_extra.test.", "in-addr.arpa."},
		Client:     etcdc.NewKeysAPI(cli),
	}
}
Example #2
0
// Look in .../dns/stub/<zone>/xx for msg.Services. Loop through them
// extract <zone> and add them as forwarders (ip:port-combos) for
// the stub zones. Only numeric (i.e. IP address) hosts are used.
// Only the first zone configured on e is used for the lookup.
func (e *Etcd) updateStubZones() {
	zone := e.Zones[0]
	services, err := e.Records(stubDomain+"."+zone, false)
	if err != nil {
		return
	}

	stubmap := make(map[string]proxy.Proxy)
	// track the nameservers on a per domain basis, but allow a list on the domain.
	nameservers := map[string][]string{}

	for _, serv := range services {
		if serv.Port == 0 {
			serv.Port = 53
		}
		ip := net.ParseIP(serv.Host)
		if ip == nil {
			log.Printf("[WARNING] Non IP address stub nameserver: %s", serv.Host)
			continue
		}

		domain := msg.Domain(serv.Key)
		labels := dns.SplitDomainName(domain)

		// If the remaining name equals any of the zones we have, we ignore it.
		for _, z := range e.Zones {
			// Chop of left most label, because that is used as the nameserver place holder
			// and drop the right most labels that belong to zone.
			// We must *also* chop of dns.stub. which means cutting two more labels.
			domain = dns.Fqdn(strings.Join(labels[1:len(labels)-dns.CountLabel(z)-2], "."))
			if domain == z {
				log.Printf("[WARNING] Skipping nameserver for domain we are authoritative for: %s", domain)
				continue
			}
			nameservers[domain] = append(nameservers[domain], net.JoinHostPort(serv.Host, strconv.Itoa(serv.Port)))
		}
	}
	for domain, nss := range nameservers {
		stubmap[domain] = proxy.New(nss)
	}
	// atomic swap (at least that's what we hope it is)
	if len(stubmap) > 0 {
		e.Stubmap = &stubmap
	}
	return
}
Example #3
0
func TestLookupProxy(t *testing.T) {
	name, rm, err := test.TempFile(t, ".", exampleOrg)
	if err != nil {
		t.Fatalf("failed to created zone: %s", err)
	}
	defer rm()

	corefile := `example.org:0 {
	file ` + name + `
}
`
	ex, _, udp, err := Server(t, corefile)
	if err != nil {
		t.Fatalf("Could get server: %s", err)
	}
	defer ex.Stop()

	log.SetOutput(ioutil.Discard)

	p := proxy.New([]string{udp})
	state := middleware.State{W: &test.ResponseWriter{}, Req: new(dns.Msg)}
	resp, err := p.Lookup(state, "example.org.", dns.TypeA)
	if err != nil {
		t.Error("Expected to receive reply, but didn't")
		return
	}
	// expect answer section with A record in it
	if len(resp.Answer) == 0 {
		t.Error("Expected to at least one RR in the answer section, got none")
	}
	if resp.Answer[0].Header().Rrtype != dns.TypeA {
		t.Error("Expected RR to A, got: %d", resp.Answer[0].Header().Rrtype)
	}
	if resp.Answer[0].(*dns.A).A.String() != "127.0.0.1" {
		t.Error("Expected 127.0.0.1, got: %d", resp.Answer[0].(*dns.A).A.String())
	}
}
Example #4
0
func kubernetesParse(c *Controller) (kubernetes.Kubernetes, error) {

	/*
	 * TODO: Remove unused state and simplify.
	 * Inflight and Ctx might not be needed. Leaving in place until
	 * we take a pass at API caching and optimizing connector to the
	 * k8s API. Single flight (or limited upper-bound) for inflight
	 * API calls may be desirable.
	 */

	k8s := kubernetes.Kubernetes{
		Proxy: proxy.New([]string{}),
		Ctx:   context.Background(),
		//      Inflight:   &singleflight.Group{},
	}
	var (
		endpoints  = []string{defaultK8sEndpoint}
		template   = defaultNameTemplate
		namespaces = []string{}
	)

	k8s.APIConn = k8sc.NewK8sConnector(endpoints[0])
	k8s.NameTemplate = new(nametemplate.NameTemplate)
	k8s.NameTemplate.SetTemplate(template)

	for c.Next() {
		if c.Val() == "kubernetes" {
			zones := c.RemainingArgs()

			if len(zones) == 0 {
				k8s.Zones = c.ServerBlockHosts
			} else {
				// Normalize requested zones
				k8s.Zones = kubernetes.NormalizeZoneList(zones)
			}

			middleware.Zones(k8s.Zones).FullyQualify()
			if c.NextBlock() {
				// TODO(miek): 2 switches?
				switch c.Val() {
				case "endpoint":
					args := c.RemainingArgs()
					if len(args) == 0 {
						return kubernetes.Kubernetes{}, c.ArgErr()
					}
					endpoints = args
					k8s.APIConn = k8sc.NewK8sConnector(endpoints[0])
				}
				for c.Next() {
					switch c.Val() {
					case "template":
						args := c.RemainingArgs()
						if len(args) == 0 {
							return kubernetes.Kubernetes{}, c.ArgErr()
						}
						template = strings.Join(args, "")
						err := k8s.NameTemplate.SetTemplate(template)
						if err != nil {
							return kubernetes.Kubernetes{}, err
						}
					case "namespaces":
						args := c.RemainingArgs()
						if len(args) == 0 {
							return kubernetes.Kubernetes{}, c.ArgErr()
						}
						namespaces = args
						k8s.Namespaces = &namespaces
					}
				}
			}
			return k8s, nil
		}
	}
	return kubernetes.Kubernetes{}, nil
}
Example #5
0
func etcdParse(c *Controller) (etcd.Etcd, bool, error) {
	stub := make(map[string]proxy.Proxy)
	etc := etcd.Etcd{
		Proxy:      proxy.New([]string{"8.8.8.8:53", "8.8.4.4:53"}),
		PathPrefix: "skydns",
		Ctx:        context.Background(),
		Inflight:   &singleflight.Group{},
		Stubmap:    &stub,
	}
	var (
		client        etcdc.KeysAPI
		tlsCertFile   = ""
		tlsKeyFile    = ""
		tlsCAcertFile = ""
		endpoints     = []string{defaultEndpoint}
		stubzones     = false
	)
	for c.Next() {
		if c.Val() == "etcd" {
			etc.Client = client
			etc.Zones = c.RemainingArgs()
			if len(etc.Zones) == 0 {
				etc.Zones = c.ServerBlockHosts
			}
			middleware.Zones(etc.Zones).FullyQualify()
			if c.NextBlock() {
				// TODO(miek): 2 switches?
				switch c.Val() {
				case "stubzones":
					stubzones = true
				case "debug":
					etc.Debug = true
				case "path":
					if !c.NextArg() {
						return etcd.Etcd{}, false, c.ArgErr()
					}
					etc.PathPrefix = c.Val()
				case "endpoint":
					args := c.RemainingArgs()
					if len(args) == 0 {
						return etcd.Etcd{}, false, c.ArgErr()
					}
					endpoints = args
				case "upstream":
					args := c.RemainingArgs()
					if len(args) == 0 {
						return etcd.Etcd{}, false, c.ArgErr()
					}
					for i := 0; i < len(args); i++ {
						h, p, e := net.SplitHostPort(args[i])
						if e != nil && p == "" {
							args[i] = h + ":53"
						}
					}
					endpoints = args
					etc.Proxy = proxy.New(args)
				case "tls": // cert key cacertfile
					args := c.RemainingArgs()
					if len(args) != 3 {
						return etcd.Etcd{}, false, c.ArgErr()
					}
					tlsCertFile, tlsKeyFile, tlsCAcertFile = args[0], args[1], args[2]
				}
				for c.Next() {
					switch c.Val() {
					case "stubzones":
						stubzones = true
					case "debug":
						etc.Debug = true
					case "path":
						if !c.NextArg() {
							return etcd.Etcd{}, false, c.ArgErr()
						}
						etc.PathPrefix = c.Val()
					case "endpoint":
						args := c.RemainingArgs()
						if len(args) == 0 {
							return etcd.Etcd{}, false, c.ArgErr()
						}
						endpoints = args
					case "upstream":
						args := c.RemainingArgs()
						if len(args) == 0 {
							return etcd.Etcd{}, false, c.ArgErr()
						}
						for i := 0; i < len(args); i++ {
							h, p, e := net.SplitHostPort(args[i])
							if e != nil && p == "" {
								args[i] = h + ":53"
							}
						}
						etc.Proxy = proxy.New(args)
					case "tls": // cert key cacertfile
						args := c.RemainingArgs()
						if len(args) != 3 {
							return etcd.Etcd{}, false, c.ArgErr()
						}
						tlsCertFile, tlsKeyFile, tlsCAcertFile = args[0], args[1], args[2]
					}
				}
			}
			client, err := newEtcdClient(endpoints, tlsCertFile, tlsKeyFile, tlsCAcertFile)
			if err != nil {
				return etcd.Etcd{}, false, err
			}
			etc.Client = client
			return etc, stubzones, nil
		}
	}
	return etcd.Etcd{}, false, nil
}