Esempio n. 1
0
// setUpIntermediate sets up a test intermediate server.
func setUpIntermediate(name string, addr string) (fixture, error) {
	var (
		fix fixture
		err error
	)

	fix.server, err = MakeTestIntermediateServer(
		name, addr,
		&pb.ResourceTemplate{
			IdentifierGlob: proto.String("*"),
			Capacity:       proto.Float64(100),
			SafeCapacity:   proto.Float64(2),
			Algorithm: &pb.Algorithm{
				Kind:            pb.Algorithm_PROPORTIONAL_SHARE.Enum(),
				RefreshInterval: proto.Int64(1),
				LeaseLength:     proto.Int64(2),
			},
		})
	if err != nil {
		return fixture{}, err
	}

	lis, err := net.Listen("tcp", ":0")
	if err != nil {
		return fixture{}, err
	}

	fix.lis = lis

	fix.rpcServer = rpc.NewServer()

	pb.RegisterCapacityServer(fix.rpcServer, fix.server)

	go fix.rpcServer.Serve(lis)

	conn, err := rpc.Dial(fix.Addr(), rpc.WithInsecure())
	if err != nil {
		return fixture{}, err
	}

	fix.client = pb.NewCapacityClient(conn)
	return fix, nil
}
Esempio n. 2
0
func main() {
	flag.Parse()
	if err := flagenv.Populate(flag.CommandLine, "DOORMAN"); err != nil {
		log.Exit(err)
	}

	if *config == "" {
		log.Exit("--config cannot be empty")
	}
	var (
		etcdEndpointsSlice = strings.Split(*etcdEndpoints, ",")
		masterElection     election.Election
	)
	if *masterElectionLock != "" {

		if len(etcdEndpointsSlice) == 1 && etcdEndpointsSlice[0] == "" {
			log.Exit("-etcd_endpoints cannot be empty if -master_election_lock is provided")
		}

		masterElection = election.Etcd(etcdEndpointsSlice, *masterElectionLock, *masterDelay)
	} else {
		masterElection = election.Trivial()
	}

	dm, err := doorman.New(context.Background(), getServerID(*port), *parent, masterElection,
		connection.MinimumRefreshInterval(*minimumRefreshInterval),
		connection.DialOpts(
			rpc.WithTimeout(*rpcDialTimeout)))
	if err != nil {
		log.Exitf("doorman.NewIntermediate: %v", err)
	}

	var opts []rpc.ServerOption
	if *tls {
		log.Infof("Loading credentials from %v and %v.", *certFile, *keyFile)
		creds, err := credentials.NewServerTLSFromFile(*certFile, *keyFile)
		if err != nil {
			log.Exitf("Failed to generate credentials %v", err)
		}
		opts = []rpc.ServerOption{rpc.Creds(creds)}
	}
	server := rpc.NewServer(opts...)

	pb.RegisterCapacityServer(server, dm)

	if *config == "" {
		log.Exit("-config cannot be empty")
	}

	var cfg configuration.Source
	kind, path := configuration.ParseSource(*config)
	switch {
	case kind == "file":
		cfg = configuration.LocalFile(path)
	case kind == "etcd":
		if len(etcdEndpointsSlice) == 1 && etcdEndpointsSlice[0] == "" {
			log.Exit("-etcd_endpoints cannot be empty if a config source etcd is provided")
		}
		cfg = configuration.Etcd(path, etcdEndpointsSlice)
	default:
		panic("unreachable")
	}

	// Try to load the background. If there's a problem with loading
	// the server for the first time, the server will keep running,
	// but will not serve traffic.
	go func() {
		for {
			data, err := cfg(context.Background())
			if err != nil {
				log.Errorf("cannot load config data: %v", err)
				continue
			}
			cfg := new(pb.ResourceRepository)
			if err := yaml.Unmarshal(data, cfg); err != nil {
				log.Errorf("cannot unmarshal config data: %q", data)
				continue
			}

			if err := dm.LoadConfig(context.Background(), cfg, map[string]*time.Time{}); err != nil {
				log.Errorf("cannot load config: %v", err)
			}
		}
	}()

	status.AddStatusPart("Doorman", statusz, func(context.Context) interface{} { return dm.Status() })

	// Redirect form / to /debug/status.
	http.Handle("/", http.RedirectHandler("/debug/status", http.StatusMovedPermanently))
	AddServer(dm)

	http.Handle("/metrics", prometheus.Handler())

	go http.ListenAndServe(fmt.Sprintf(":%v", *debugPort), nil)

	// Waits for the server to get its initial configuration. This guarantees that
	// the server will never run without a valid configuration.
	log.Info("Waiting for the server to be configured...")
	dm.WaitUntilConfigured()

	// Runs the server.
	log.Info("Server is configured, ready to go!")

	lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
	if err != nil {
		log.Exit(err)
	}

	server.Serve(lis)

}