Ejemplo n.º 1
0
func (g *Backend) Records(name string, exact bool) ([]msg.Service, error) {
	path, star := msg.PathWithWildcard(name)
	r, err := g.get(path, true)
	if err != nil {
		return nil, err
	}
	segments := strings.Split(msg.Path(name), "/")
	switch {
	case exact && r.Node.Dir:
		return nil, nil
	case r.Node.Dir:
		return g.loopNodes(&r.Node.Nodes, segments, star, nil)
	default:
		return g.loopNodes(&etcd.Nodes{r.Node}, segments, false, nil)
	}
}
Ejemplo n.º 2
0
func (g *Backend) ReverseRecord(name string) (*msg.Service, error) {
	path, star := msg.PathWithWildcard(name)
	if star {
		return nil, fmt.Errorf("reverse can not contain wildcards")
	}
	r, err := g.get(path, true)
	if err != nil {
		return nil, err
	}
	if r.Node.Dir {
		return nil, fmt.Errorf("reverse must not be a directory")
	}
	segments := strings.Split(msg.Path(name), "/")
	records, err := g.loopNodes(&etcd.Nodes{r.Node}, segments, false, nil)
	if err != nil {
		return nil, err
	}
	if len(records) != 1 {
		return nil, fmt.Errorf("must be only one service record")
	}
	return &records[0], nil
}
Ejemplo n.º 3
0
func main() {
	flag.Parse()
	machines := strings.Split(machine, ",")
	client := newClient(machines, tlspem, tlskey, cacert)

	if nameserver != "" {
		for _, hostPort := range strings.Split(nameserver, ",") {
			if err := validateHostPort(hostPort); err != nil {
				log.Fatalf("skydns: nameserver is invalid: %s", err)
			}
			config.Nameservers = append(config.Nameservers, hostPort)
		}
	}
	if err := validateHostPort(config.DnsAddr); err != nil {
		log.Fatalf("skydns: addr is invalid: %s", err)
	}

	if err := loadConfig(client, config); err != nil {
		log.Fatalf("skydns: %s", err)
	}
	server.SetDefaults(config)

	if config.Local != "" {
		config.Local = dns.Fqdn(config.Local)
	}

	backend := backendetcd.NewBackend(client, &backendetcd.Config{
		Ttl:      config.Ttl,
		Priority: config.Priority,
	})
	s := server.New(backend, config)

	if discover {
		go func() {
			recv := make(chan *etcd.Response)
			go client.Watch("/_etcd/machines/", 0, true, recv, nil)
			duration := 1 * time.Second
			for {
				select {
				case n := <-recv:
					if n != nil {
						if client := updateClient(n, tlskey, tlspem, cacert); client != nil {
							backend.UpdateClient(client)
						}
						duration = 1 * time.Second // reset
					} else {
						// we can see an n == nil, probably when we can't connect to etcd.
						log.Printf("skydns: etcd machine cluster update failed, sleeping %s + ~3s", duration)
						time.Sleep(duration + (time.Duration(rand.Float32() * 3e9))) // Add some random.
						duration *= 2
						if duration > 32*time.Second {
							duration = 32 * time.Second
						}
					}
				}
			}
		}()
	}

	if stub {
		s.UpdateStubZones()
		go func() {
			recv := make(chan *etcd.Response)
			go client.Watch(msg.Path(config.Domain)+"/dns/stub/", 0, true, recv, nil)
			duration := 1 * time.Second
			for {
				select {
				case n := <-recv:
					if n != nil {
						s.UpdateStubZones()
						log.Printf("skydns: stubzone update")
						duration = 1 * time.Second // reset
					} else {
						// we can see an n == nil, probably when we can't connect to etcd.
						log.Printf("skydns: stubzone update failed, sleeping %s + ~3s", duration)
						time.Sleep(duration + (time.Duration(rand.Float32() * 3e9))) // Add some random.
						duration *= 2
						if duration > 32*time.Second {
							duration = 32 * time.Second
						}
					}
				}
			}
		}()
	}

	stats.Collect()  // Graphite
	server.Metrics() // Prometheus

	if err := s.Run(); err != nil {
		log.Fatalf("skydns: %s", err)
	}
}