func (s *Server) SignalHandler(k8sUtils k8sutils.UtilsInterface) {
	go func() {
		signal.Notify(s.SigChan, syscall.SIGINT, syscall.SIGHUP)
		log.Debug("SignalHandler setup to listen for SIGINT and SIGHUP")
		sig := <-s.SigChan
		log.Infof("Received signal: %v\n", sig)
		k8sUtils.StopInformer()
		err := s.HTTPServer.Shutdown(context.Background())
		if err != nil {
			log.Fatalf("Error during graceful shutdown of the server: %v", err)
		} else {
			log.Info("Server shutdown gracefully on signal")
		}
		close(s.SigChan)
	}()
}
SignalHandler - listens for SIGINT and SIGHUP
when the signal is received it stops the k8s informer
and attempts to shutdown the HTTPS server gracefully
package main
import (
	"context"
	"net/http"
	"os"
	"os/signal"
	"path/filepath"
	"revproxy/v2/pkg/common"
	"revproxy/v2/pkg/config"
	"revproxy/v2/pkg/k8sutils"
	"revproxy/v2/pkg/linkedproxy"
	"revproxy/v2/pkg/standaloneproxy"
	"revproxy/v2/pkg/utils"
	"strings"
	"sync"
	"syscall"
	"time"
	log "github.com/sirupsen/logrus"
	"github.com/kubernetes-csi/csi-lib-utils/leaderelection"
	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
	corev1 "k8s.io/api/core/v1"
)
type RevProxy interface {
	ServeReverseProxy(res http.ResponseWriter, req *http.Request)
	UpdateConfig(proxyConfig config.ProxyConfig) error
	GetRouter() http.Handler
}
type ServerOpts struct {
	CertDir        string
	TLSCertDir     string
	NameSpace      string
	CertFile       string
	KeyFile        string
	ConfigDir      string
	ConfigFileName string
	InCluster      bool
}
func getEnv(envName, defaultValue string) string {
	envVal, found := os.LookupEnv(envName)
	if !found {
		envVal = defaultValue
	}
	return envVal
}
func getServerOpts() ServerOpts {
	certDir := getEnv(common.EnvCertDirName, common.DefaultCertDirName)
	tlsCertDir := getEnv(common.EnvTLSCertDirName, common.DefaultTLSCertDirName)
	defaultNameSpace := getEnv(common.EnvWatchNameSpace, common.DefaultNameSpace)
	configFile := getEnv(common.EnvConfigFileName, common.DefaultConfigFileName)
	configDir := getEnv(common.EnvConfigDirName, common.DefaultConfigDir)
	inClusterEnvVal := getEnv(common.EnvInClusterConfig, "false")
	inCluster := false
	if strings.ToLower(inClusterEnvVal) == "true" {
		inCluster = true
	}
	return ServerOpts{
		CertDir:        certDir,
		TLSCertDir:     tlsCertDir,
		NameSpace:      defaultNameSpace,
		ConfigFileName: configFile,
		ConfigDir:      configDir,
		CertFile:       common.DefaultCertFile,
		KeyFile:        common.DefaultKeyFile,
		InCluster:      inCluster,
	}
}
type Server struct {
	HTTPServer      *http.Server
	Mode            config.ProxyMode
	Port            string
	CertFile        string
	KeyFile         string
	config          *config.ProxyConfig
	LinkedProxy     *linkedproxy.LinkedProxy
	StandAloneProxy *standaloneproxy.StandAloneProxy
	SigChan         chan os.Signal
	WaitGroup       sync.WaitGroup
	Mutex           sync.Mutex
	Opts            ServerOpts
}
func (s *Server) SetConfig(c *config.ProxyConfig) {
	s.Mutex.Lock()
	defer s.Mutex.Unlock()
	s.config = c
}
func (s *Server) Config() *config.ProxyConfig {
	s.Mutex.Lock()
	defer s.Mutex.Unlock()
	return s.config
}
func (s *Server) Setup(k8sUtils k8sutils.UtilsInterface) error {
	proxyConfigMap, err := config.ReadConfig(s.Opts.ConfigFileName, s.Opts.ConfigDir)
	if err != nil {
		return err
	}
	updateRevProxyLogParams(proxyConfigMap.LogFormat, proxyConfigMap.LogLevel)
	proxyConfig, err := config.NewProxyConfig(proxyConfigMap, k8sUtils)
	if err != nil {
		return err
	}
	s.CertFile = filepath.Join(s.Opts.TLSCertDir, s.Opts.CertFile)
	s.KeyFile = filepath.Join(s.Opts.TLSCertDir, s.Opts.KeyFile)
	s.Port = proxyConfig.Port
	if proxyConfig.Mode == config.Linked {
		linkedProxy, err := linkedproxy.NewLinkedProxy(*proxyConfig.LinkProxyConfig)
		if err != nil {
			return err
		}
		s.LinkedProxy = linkedProxy
	} else if proxyConfig.Mode == config.StandAlone {
		standAloneProxy, err := standaloneproxy.NewStandAloneProxy(*proxyConfig.StandAloneProxyConfig)
		if err != nil {
			return err
		}
		s.StandAloneProxy = standAloneProxy
	}
	s.SetConfig(proxyConfig)
	s.SigChan = make(chan os.Signal, 1)
	return nil
}
func (s *Server) GetRevProxy() RevProxy {
	if s.LinkedProxy != nil {
		return s.LinkedProxy
	}
	return s.StandAloneProxy
}
func (s *Server) Start() {
	s.WaitGroup.Add(1)
	if s.HTTPServer == nil {
		port := utils.GetListenAddress(s.Port)
		handler := s.GetRevProxy().GetRouter()
		server := http.Server{
			Addr:    port,
			Handler: handler,
		}
		go func() {
			defer s.WaitGroup.Done()
			if err := server.ListenAndServeTLS(s.CertFile, s.KeyFile); err != http.ErrServerClosed {
				log.Fatalf("ListenAndServe(): %v", err)
			}
		}()
		s.HTTPServer = &server
	}
}