func createTLSConfig(cert, key string) (*tls.Config, error) {
	var result *tls.Config
	c, err := tls.X509KeyPair([]byte(cert), []byte(key))
	if err != nil {
		return nil, errors.WithStack(err)
	}
	result = &tls.Config{
		Certificates: []tls.Certificate{c},
	}
	return result, nil
}
createTLSConfig creates a TLS config based on given config
package server
import (
	"context"
	"crypto/tls"
	"net/http"
	"strings"
	"time"
	operatorHTTP "github.com/arangodb/kube-arangodb/pkg/util/http"
	"github.com/arangodb/kube-arangodb/pkg/version"
	"github.com/arangodb/kube-arangodb/pkg/util/errors"
	"github.com/arangodb-helper/go-certificates"
	"github.com/gin-gonic/gin"
	"github.com/jessevdk/go-assets"
	prometheus "github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/rs/zerolog"
	core "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
	"github.com/arangodb/kube-arangodb/dashboard"
	"github.com/arangodb/kube-arangodb/pkg/util/probe"
)
type Config struct {
	Namespace          string
	Address            string  
	TLSSecretName      string  
	TLSSecretNamespace string  
	PodName            string  
	PodIP              string  
	AdminSecretName    string  
	AllowAnonymous     bool    
}
type OperatorDependency struct {
	Enabled bool
	Probe   *probe.ReadyProbe
}
type Dependencies struct {
	Log                   zerolog.Logger
	LivenessProbe         *probe.LivenessProbe
	Deployment            OperatorDependency
	DeploymentReplication OperatorDependency
	Storage               OperatorDependency
	Backup                OperatorDependency
	Operators             Operators
	Secrets               corev1.SecretInterface
}
type Operators interface {
	DeploymentOperator() DeploymentOperator
	DeploymentReplicationOperator() DeploymentReplicationOperator
	StorageOperator() StorageOperator
	FindOtherOperators() []OperatorReference
}
type Server struct {
	cfg        Config
	deps       Dependencies
	httpServer *http.Server
	auth       *serverAuthentication
}
func NewServer(cli corev1.CoreV1Interface, cfg Config, deps Dependencies) (*Server, error) {
	httpServer := &http.Server{
		Addr:              cfg.Address,
		ReadTimeout:       time.Second * 30,
		ReadHeaderTimeout: time.Second * 15,
		WriteTimeout:      time.Second * 30,
		TLSNextProto:      make(map[string]func(*http.Server, *tls.Conn, http.Handler)),
	}
	var cert, key string
	if cfg.TLSSecretName != "" && cfg.TLSSecretNamespace != "" {
		s, err := cli.Secrets(cfg.TLSSecretNamespace).Get(context.Background(), cfg.TLSSecretName, metav1.GetOptions{})
		if err != nil {
			return nil, errors.WithStack(err)
		}
		certBytes, found := s.Data[core.TLSCertKey]
		if !found {
			return nil, errors.WithStack(errors.Newf("No %s found in secret %s", core.TLSCertKey, cfg.TLSSecretName))
		}
		keyBytes, found := s.Data[core.TLSPrivateKeyKey]
		if !found {
			return nil, errors.WithStack(errors.Newf("No %s found in secret %s", core.TLSPrivateKeyKey, cfg.TLSSecretName))
		}
		cert = string(certBytes)
		key = string(keyBytes)
	} else {
		options := certificates.CreateCertificateOptions{
			CommonName: cfg.PodName,
			Hosts:      []string{cfg.PodName, cfg.PodIP},
			ValidFrom:  time.Now(),
			ValidFor:   time.Hour * 24 * 365 * 10,
			IsCA:       false,
			ECDSACurve: "P256",
		}
		var err error
		cert, key, err = certificates.CreateCertificate(options, nil)
		if err != nil {
			return nil, errors.WithStack(err)
		}
	}
	tlsConfig, err := createTLSConfig(cert, key)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	tlsConfig.BuildNameToCertificate()
	httpServer.TLSConfig = tlsConfig
	s := &Server{
		cfg:        cfg,
		deps:       deps,
		httpServer: httpServer,
		auth:       newServerAuthentication(deps.Log, deps.Secrets, cfg.AdminSecretName, cfg.AllowAnonymous),
	}
	gin.SetMode(gin.ReleaseMode)
	r := gin.New()
	r.Use(gin.Recovery())
	r.GET("/health", gin.WrapF(deps.LivenessProbe.LivenessHandler))
	versionV1Responser, err := operatorHTTP.NewSimpleJSONResponse(version.GetVersionV1())
	if err != nil {
		return nil, errors.WithStack(err)
	}
	r.GET("/_api/version", gin.WrapF(versionV1Responser.ServeHTTP))
	r.GET("/api/v1/version", gin.WrapF(versionV1Responser.ServeHTTP))
	var readyProbes []*probe.ReadyProbe
	if deps.Deployment.Enabled {
		r.GET("/ready/deployment", gin.WrapF(deps.Deployment.Probe.ReadyHandler))
		readyProbes = append(readyProbes, deps.Deployment.Probe)
	}
	if deps.DeploymentReplication.Enabled {
		r.GET("/ready/deployment-replication", gin.WrapF(deps.DeploymentReplication.Probe.ReadyHandler))
		readyProbes = append(readyProbes, deps.DeploymentReplication.Probe)
	}
	if deps.Storage.Enabled {
		r.GET("/ready/storage", gin.WrapF(deps.Storage.Probe.ReadyHandler))
		readyProbes = append(readyProbes, deps.Storage.Probe)
	}
	r.GET("/ready", gin.WrapF(ready(readyProbes...)))
	r.GET("/metrics", gin.WrapH(prometheus.Handler()))
	r.POST("/login", s.auth.handleLogin)
	api := r.Group("/api", s.auth.checkAuthentication)
	{
		api.GET("/operators", s.handleGetOperators)
		api.GET("/deployment", s.handleGetDeployments)
		api.GET("/deployment/:name", s.handleGetDeploymentDetails)
		api.GET("/deployment-replication", s.handleGetDeploymentReplications)
		api.GET("/deployment-replication/:name", s.handleGetDeploymentReplicationDetails)
		api.GET("/storage", s.handleGetLocalStorages)
		api.GET("/storage/:name", s.handleGetLocalStorageDetails)
	}
	r.GET("/", createAssetFileHandler(dashboard.Assets.Files["index.html"]))
	for path, file := range dashboard.Assets.Files {
		localPath := "/" + strings.TrimPrefix(path, "/")
		r.GET(localPath, createAssetFileHandler(file))
	}
	httpServer.Handler = r
	return s, nil
}
func createAssetFileHandler(file *assets.File) func(c *gin.Context) {
	return func(c *gin.Context) {
		http.ServeContent(c.Writer, c.Request, file.Name(), file.ModTime(), file)
	}
}
func (s *Server) Run() error {
	s.deps.Log.Info().Msgf("Serving on %s", s.httpServer.Addr)
	if err := s.httpServer.ListenAndServeTLS("", ""); err != nil && err != http.ErrServerClosed {
		return errors.WithStack(err)
	}
	return nil
}