func (e *Endpoints) NetworkAddress() string {
	e.mutex.RLock()
	defer e.mutex.RUnlock()
	listener := e.listeners[network]
	if listener == nil {
		return ""
	}
	return listener.Addr().String()
}
NetworkAddress returns the network addresses of the network endpoint, or an
empty string if there's no network endpoint
package endpoints
import (
	"fmt"
	"net"
	"sync"
	"time"
	"github.com/go-kit/kit/log"
	"github.com/go-kit/kit/log/level"
	"github.com/pkg/errors"
	"github.com/spoke-d/thermionic/internal/cert"
	"github.com/spoke-d/thermionic/internal/clock"
	"github.com/spoke-d/thermionic/internal/retrier"
	"github.com/spoke-d/thermionic/internal/tomb"
)
const DefaultPort = "8080"
type kind int
const (
	network kind = iota
	pprof
)
func (k kind) Description() string {
	switch k {
	case network:
		return "TCP socket"
	case pprof:
		return "pprof socket"
	default:
		return "unknown"
	}
}
type Server interface {
	Serve(net.Listener) error
}
type Endpoints struct {
	tomb      *tomb.Tomb
	mutex     sync.RWMutex
	listeners map[kind]net.Listener
	servers   map[kind]Server
	cert      *cert.Info
	logger    log.Logger
	sleeper   clock.Sleeper
}
func New(restServer Server, cert *cert.Info, options ...Option) *Endpoints {
	opts := newOptions()
	opts.restServer = restServer
	opts.cert = cert
	for _, option := range options {
		option(opts)
	}
	return &Endpoints{
		tomb: tomb.New(),
		listeners: map[kind]net.Listener{
			network: networkCreateListener(opts.networkAddress, cert, opts.logger),
			pprof:   pprofCreateListener(opts.debugAddress, opts.logger),
		},
		servers: map[kind]Server{
			network: opts.restServer,
			pprof:   pprofCreateServer(),
		},
		cert:    opts.cert,
		logger:  opts.logger,
		sleeper: opts.sleeper,
	}
}
func (e *Endpoints) Up() error {
	e.mutex.Lock()
	defer e.mutex.Unlock()
	level.Info(e.logger).Log("msg", "REST API daemon")
	if err := e.serveHTTP(network); err != nil {
		return errors.WithStack(err)
	}
	if err := e.serveHTTP(pprof); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (e *Endpoints) Down() error {
	e.mutex.Lock()
	defer e.mutex.Unlock()
	for _, v := range []kind{network, pprof} {
		if e.listeners[v] != nil {
			level.Info(e.logger).Log("msg", "Stopping API handler", "kind", v.Description())
			err := e.closeListener(v)
			if err != nil {
				return errors.WithStack(err)
			}
		}
	}
	if e.tomb != nil {
		e.tomb.Kill(nil)
		e.tomb.Wait()
	}
	return nil
}