1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-19 13:29:41 +02:00
portainer/api/http/server.go
Sven Dowideit f99329eb7e
chore(store) EE-1981: Refactor/store/error checking, and other refactoring (#6173)
* use the Store interface IsErrObjectNotFound() to avoid revealing internal errors

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* what happens when you extract the datastore interfaces into their own package

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* Start renaming Storage methods

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* extract the boltdb specific code from the Portainer storage code (example, the others need the same)

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* more extract bolt.Tx from datastore code

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* minimise imports by putting moving the struct definition into the file that needs the Service imports

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* more extraction of boltdb.Tx

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* extract the use of bucket.SetSequence

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* almost done - just endpoint.Synchonise :/

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* so, endpoint.Synchonize looks hard, but i can't find where we use it, so 'delete first refactoring'

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* fix test compile errors

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* test compile fixes after rebase

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* fix a mis-remembering I had wrt deserialisation - last time i used AnyData - jsoniter's bindTo looks interesting for the same reason

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* set us up to make the connection an interface

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* make the db connection a datastore interface, and separate out our datastore services from the bolt ones

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* rename methods to something less oltdb internals specific

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* these errors are not boltdb secific

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* start using the db-backend factory method too

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* export boltdb raw in case we can't export from the service layer

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* add a raw export from boltdb to yaml for broken db's, and an export services to yaml in backup

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* add the version info by hand for now

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* actually, the export from services can be fully typed - its the import that needs to do more work

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* redo raw export, and make import capable of using it

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* add DockerHub

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* migration from anything older than v1.21.0 has been broken for quite a while, deleting the un-tested code

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* fix go test ./... again

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* my goland wasn't setup to gofmt

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* move the two extremely dubious migration tests down into store, so they can use the test store code

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* the migrator is now free of boltdb

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* reverse goland overzealous replcement of internal with boltdb

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* more undo over-zealous goland internal->boltdb

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* yay, now bolt is only mentioned inside the api/database/ dir

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* and this might be the last of the boltdb references?

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* add todo

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* extract the store code into a separate module too

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* don't need the fileService in boltdb anymore

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* use IsErrObjectNotFound()

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* use a string to select what database backend we use

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* make isNew store an ephemeral bool that doesn't stay true after we've initialised it

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* move the import.json wip to a separate file so its more obvious - we'll be using it for testing, emergency fixups, and in the next part of the store work, when we improve migrations and data model lifecycles

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* undo vscode formatting html

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* fix app templates symbol (#6221)

* feat(webhook) EE-2125 send registry auth haeder when update swarms service via webhook (#6220)

* feat(webhook) EE-2125 add some helpers to registry utils

* feat(webhook) EE-2125 persist registryID when creating a webhook

* feat(webhook) EE-2125 send registry auth header when executing a webhook

* feat(webhook) EE-2125 send registryID to backend when creating a service with webhook

* feat(webhook) EE-2125 use the initial registry ID to create webhook on editing service screen

* feat(webhook) EE-2125 update webhook when update registry

* feat(webhook) EE-2125 add endpoint of update webhook

* feat(webhook) EE-2125 code cleanup

* feat(webhook) EE-2125 fix a typo

* feat(webhook) EE-2125 fix circle import issue with unit test

Co-authored-by: Simon Meng <simon.meng@portainer.io>

* fix(kubeconfig): show kubeconfig download button for non admin users [EE-2123] (#6204)

Co-authored-by: Simon Meng <simon.meng@portainer.io>

* fix data-cy for k8s cluster menu (#6226)

LGTM

* feat(stack): make stack created from app template editable EE-1941 (#6104)

feat(stack): make stack from app template editable

* fix(container):disable Duplicate/Edit button when the container is portainer (#6223)

* fix/ee-1909/show-pull-image-error (#6195)

Co-authored-by: sunportainer <ericsun@SG1.local>

* feat(cy): add data-cy to helm install button (#6241)

* feat(cy): add data-cy to add registry button (#6242)

* refactor(app): convert root folder files to es6 (#4159)

* refactor(app): duplicate constants as es6 exports (#4158)

* fix(docker): provide workaround to save network name variable  (#6080)

* fix/EE-1862/unable-to-stop-or-remove-stack workaround for var without default value in yaml file

* fix/EE-1862/unable-to-stop-or-remove-stack check yaml file

* fixed func and var names

* wrapper error and used bool for stringset

* UT case for createNetworkEnvFile

* UT case for %s=%s

* powerful StringSet

* wrapper error for extract network name

* wrapper all the return err

* store more env

* put to env file

* make default value None

* feat: gzip static resources (#6258)

* fix(ssl)//handle --sslcert and --sslkey ee-2106 (#6203)

* fix/ee-2106/handle-sslcert-sslkey

Co-authored-by: sunportainer <ericsun@SG1.local>

* fix(server):support disable https only ee-2068 (#6232)

* fix/ee-2068/disable-forcely-https

* feat(store): implement store tests EE-2112 (#6224)

* add store tests

* add some more tests

* Update missing helm user repo methods

* remove redundant comments

* add webhook export

* update webhooks

* use the Store interface IsErrObjectNotFound() to avoid revealing internal errors

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* what happens when you extract the datastore interfaces into their own package

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* Start renaming Storage methods

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* extract the boltdb specific code from the Portainer storage code (example, the others need the same)

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* more extract bolt.Tx from datastore code

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* minimise imports by putting moving the struct definition into the file that needs the Service imports

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* more extraction of boltdb.Tx

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* extract the use of bucket.SetSequence

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* almost done - just endpoint.Synchonise :/

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* so, endpoint.Synchonize looks hard, but i can't find where we use it, so 'delete first refactoring'

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* fix test compile errors

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* test compile fixes after rebase

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* fix a mis-remembering I had wrt deserialisation - last time i used AnyData - jsoniter's bindTo looks interesting for the same reason

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* set us up to make the connection an interface

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* make the db connection a datastore interface, and separate out our datastore services from the bolt ones

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* rename methods to something less oltdb internals specific

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* these errors are not boltdb secific

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* start using the db-backend factory method too

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* export boltdb raw in case we can't export from the service layer

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* add a raw export from boltdb to yaml for broken db's, and an export services to yaml in backup

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* add the version info by hand for now

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* actually, the export from services can be fully typed - its the import that needs to do more work

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* redo raw export, and make import capable of using it

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* add DockerHub

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* migration from anything older than v1.21.0 has been broken for quite a while, deleting the un-tested code

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* fix go test ./... again

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* my goland wasn't setup to gofmt

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* move the two extremely dubious migration tests down into store, so they can use the test store code

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* the migrator is now free of boltdb

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* reverse goland overzealous replcement of internal with boltdb

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* more undo over-zealous goland internal->boltdb

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* yay, now bolt is only mentioned inside the api/database/ dir

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* and this might be the last of the boltdb references?

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* add todo

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* extract the store code into a separate module too

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* don't need the fileService in boltdb anymore

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* use IsErrObjectNotFound()

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* use a string to select what database backend we use

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* make isNew store an ephemeral bool that doesn't stay true after we've initialised it

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* move the import.json wip to a separate file so its more obvious - we'll be using it for testing, emergency fixups, and in the next part of the store work, when we improve migrations and data model lifecycles

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* undo vscode formatting html

Signed-off-by: Sven Dowideit <sven.dowideit@portainer.io>

* Update missing helm user repo methods

* feat(store): implement store tests EE-2112 (#6224)

* add store tests

* add some more tests

* remove redundant comments

* add webhook export

* update webhooks

* fix build issues after rebasing

* move migratorparams

* remove unneeded integer type conversions

* disable the db import/export for now

Co-authored-by: Richard Wei <54336863+WaysonWei@users.noreply.github.com>
Co-authored-by: cong meng <mcpacino@gmail.com>
Co-authored-by: Simon Meng <simon.meng@portainer.io>
Co-authored-by: Marcelo Rydel <marcelorydel26@gmail.com>
Co-authored-by: Hao Zhang <hao.zhang@portainer.io>
Co-authored-by: sunportainer <93502624+sunportainer@users.noreply.github.com>
Co-authored-by: sunportainer <ericsun@SG1.local>
Co-authored-by: wheresolivia <78844659+wheresolivia@users.noreply.github.com>
Co-authored-by: Chaim Lev-Ari <chiptus@users.noreply.github.com>
Co-authored-by: Chao Geng <93526589+chaogeng77977@users.noreply.github.com>
Co-authored-by: Dmitry Salakhov <to@dimasalakhov.com>
Co-authored-by: Matt Hook <hookenz@gmail.com>
2021-12-15 15:26:09 +13:00

348 lines
15 KiB
Go

package http
import (
"context"
"crypto/tls"
"fmt"
"log"
"net/http"
"path/filepath"
"time"
"github.com/portainer/libhelm"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/adminmonitor"
"github.com/portainer/portainer/api/apikey"
"github.com/portainer/portainer/api/crypto"
"github.com/portainer/portainer/api/dataservices"
"github.com/portainer/portainer/api/docker"
"github.com/portainer/portainer/api/http/handler"
"github.com/portainer/portainer/api/http/handler/auth"
"github.com/portainer/portainer/api/http/handler/backup"
"github.com/portainer/portainer/api/http/handler/customtemplates"
"github.com/portainer/portainer/api/http/handler/edgegroups"
"github.com/portainer/portainer/api/http/handler/edgejobs"
"github.com/portainer/portainer/api/http/handler/edgestacks"
"github.com/portainer/portainer/api/http/handler/edgetemplates"
"github.com/portainer/portainer/api/http/handler/endpointedge"
"github.com/portainer/portainer/api/http/handler/endpointgroups"
"github.com/portainer/portainer/api/http/handler/endpointproxy"
"github.com/portainer/portainer/api/http/handler/endpoints"
"github.com/portainer/portainer/api/http/handler/file"
"github.com/portainer/portainer/api/http/handler/helm"
"github.com/portainer/portainer/api/http/handler/hostmanagement/openamt"
kubehandler "github.com/portainer/portainer/api/http/handler/kubernetes"
"github.com/portainer/portainer/api/http/handler/ldap"
"github.com/portainer/portainer/api/http/handler/motd"
"github.com/portainer/portainer/api/http/handler/registries"
"github.com/portainer/portainer/api/http/handler/resourcecontrols"
"github.com/portainer/portainer/api/http/handler/roles"
"github.com/portainer/portainer/api/http/handler/settings"
sslhandler "github.com/portainer/portainer/api/http/handler/ssl"
"github.com/portainer/portainer/api/http/handler/stacks"
"github.com/portainer/portainer/api/http/handler/status"
"github.com/portainer/portainer/api/http/handler/storybook"
"github.com/portainer/portainer/api/http/handler/tags"
"github.com/portainer/portainer/api/http/handler/teammemberships"
"github.com/portainer/portainer/api/http/handler/teams"
"github.com/portainer/portainer/api/http/handler/templates"
"github.com/portainer/portainer/api/http/handler/upload"
"github.com/portainer/portainer/api/http/handler/users"
"github.com/portainer/portainer/api/http/handler/webhooks"
"github.com/portainer/portainer/api/http/handler/websocket"
"github.com/portainer/portainer/api/http/offlinegate"
"github.com/portainer/portainer/api/http/proxy"
"github.com/portainer/portainer/api/http/proxy/factory/kubernetes"
"github.com/portainer/portainer/api/http/security"
"github.com/portainer/portainer/api/internal/authorization"
"github.com/portainer/portainer/api/internal/ssl"
k8s "github.com/portainer/portainer/api/kubernetes"
"github.com/portainer/portainer/api/kubernetes/cli"
"github.com/portainer/portainer/api/scheduler"
stackdeployer "github.com/portainer/portainer/api/stacks"
)
// Server implements the portainer.Server interface
type Server struct {
AuthorizationService *authorization.Service
BindAddress string
BindAddressHTTPS string
HTTPEnabled bool
AssetsPath string
Status *portainer.Status
ReverseTunnelService portainer.ReverseTunnelService
ComposeStackManager portainer.ComposeStackManager
CryptoService portainer.CryptoService
SignatureService portainer.DigitalSignatureService
SnapshotService portainer.SnapshotService
FileService portainer.FileService
DataStore dataservices.DataStore
GitService portainer.GitService
OpenAMTService portainer.OpenAMTService
APIKeyService apikey.APIKeyService
JWTService dataservices.JWTService
LDAPService portainer.LDAPService
OAuthService portainer.OAuthService
SwarmStackManager portainer.SwarmStackManager
ProxyManager *proxy.Manager
KubernetesTokenCacheManager *kubernetes.TokenCacheManager
KubeConfigService k8s.KubeConfigService
Handler *handler.Handler
SSLService *ssl.Service
DockerClientFactory *docker.ClientFactory
KubernetesClientFactory *cli.ClientFactory
KubernetesDeployer portainer.KubernetesDeployer
HelmPackageManager libhelm.HelmPackageManager
Scheduler *scheduler.Scheduler
ShutdownCtx context.Context
ShutdownTrigger context.CancelFunc
StackDeployer stackdeployer.StackDeployer
BaseURL string
}
// Start starts the HTTP server
func (server *Server) Start() error {
kubernetesTokenCacheManager := server.KubernetesTokenCacheManager
requestBouncer := security.NewRequestBouncer(server.DataStore, server.JWTService, server.APIKeyService)
rateLimiter := security.NewRateLimiter(10, 1*time.Second, 1*time.Hour)
offlineGate := offlinegate.NewOfflineGate()
var authHandler = auth.NewHandler(requestBouncer, rateLimiter)
authHandler.DataStore = server.DataStore
authHandler.CryptoService = server.CryptoService
authHandler.JWTService = server.JWTService
authHandler.LDAPService = server.LDAPService
authHandler.ProxyManager = server.ProxyManager
authHandler.KubernetesTokenCacheManager = kubernetesTokenCacheManager
authHandler.OAuthService = server.OAuthService
adminMonitor := adminmonitor.New(5*time.Minute, server.DataStore, server.ShutdownCtx)
adminMonitor.Start()
var backupHandler = backup.NewHandler(requestBouncer, server.DataStore, offlineGate, server.FileService.GetDatastorePath(), server.ShutdownTrigger, adminMonitor)
var roleHandler = roles.NewHandler(requestBouncer)
roleHandler.DataStore = server.DataStore
var customTemplatesHandler = customtemplates.NewHandler(requestBouncer)
customTemplatesHandler.DataStore = server.DataStore
customTemplatesHandler.FileService = server.FileService
customTemplatesHandler.GitService = server.GitService
var edgeGroupsHandler = edgegroups.NewHandler(requestBouncer)
edgeGroupsHandler.DataStore = server.DataStore
var edgeJobsHandler = edgejobs.NewHandler(requestBouncer)
edgeJobsHandler.DataStore = server.DataStore
edgeJobsHandler.FileService = server.FileService
edgeJobsHandler.ReverseTunnelService = server.ReverseTunnelService
var edgeStacksHandler = edgestacks.NewHandler(requestBouncer)
edgeStacksHandler.DataStore = server.DataStore
edgeStacksHandler.FileService = server.FileService
edgeStacksHandler.GitService = server.GitService
edgeStacksHandler.KubernetesDeployer = server.KubernetesDeployer
var edgeTemplatesHandler = edgetemplates.NewHandler(requestBouncer)
edgeTemplatesHandler.DataStore = server.DataStore
var endpointHandler = endpoints.NewHandler(requestBouncer)
endpointHandler.DataStore = server.DataStore
endpointHandler.FileService = server.FileService
endpointHandler.ProxyManager = server.ProxyManager
endpointHandler.SnapshotService = server.SnapshotService
endpointHandler.K8sClientFactory = server.KubernetesClientFactory
endpointHandler.ReverseTunnelService = server.ReverseTunnelService
endpointHandler.ComposeStackManager = server.ComposeStackManager
endpointHandler.AuthorizationService = server.AuthorizationService
endpointHandler.BindAddress = server.BindAddress
endpointHandler.BindAddressHTTPS = server.BindAddressHTTPS
var endpointEdgeHandler = endpointedge.NewHandler(requestBouncer)
endpointEdgeHandler.DataStore = server.DataStore
endpointEdgeHandler.FileService = server.FileService
endpointEdgeHandler.ReverseTunnelService = server.ReverseTunnelService
var endpointGroupHandler = endpointgroups.NewHandler(requestBouncer)
endpointGroupHandler.AuthorizationService = server.AuthorizationService
endpointGroupHandler.DataStore = server.DataStore
var endpointProxyHandler = endpointproxy.NewHandler(requestBouncer)
endpointProxyHandler.DataStore = server.DataStore
endpointProxyHandler.ProxyManager = server.ProxyManager
endpointProxyHandler.ReverseTunnelService = server.ReverseTunnelService
var kubernetesHandler = kubehandler.NewHandler(requestBouncer, server.AuthorizationService, server.DataStore, server.KubernetesClientFactory, server.BaseURL)
kubernetesHandler.JwtService = server.JWTService
var fileHandler = file.NewHandler(filepath.Join(server.AssetsPath, "public"))
var endpointHelmHandler = helm.NewHandler(requestBouncer, server.DataStore, server.JWTService, server.KubernetesDeployer, server.HelmPackageManager, server.KubeConfigService)
var helmTemplatesHandler = helm.NewTemplateHandler(requestBouncer, server.HelmPackageManager)
var ldapHandler = ldap.NewHandler(requestBouncer)
ldapHandler.DataStore = server.DataStore
ldapHandler.FileService = server.FileService
ldapHandler.LDAPService = server.LDAPService
var motdHandler = motd.NewHandler(requestBouncer)
var registryHandler = registries.NewHandler(requestBouncer)
registryHandler.DataStore = server.DataStore
registryHandler.FileService = server.FileService
registryHandler.ProxyManager = server.ProxyManager
registryHandler.K8sClientFactory = server.KubernetesClientFactory
var resourceControlHandler = resourcecontrols.NewHandler(requestBouncer)
resourceControlHandler.DataStore = server.DataStore
var settingsHandler = settings.NewHandler(requestBouncer)
settingsHandler.DataStore = server.DataStore
settingsHandler.FileService = server.FileService
settingsHandler.JWTService = server.JWTService
settingsHandler.LDAPService = server.LDAPService
settingsHandler.SnapshotService = server.SnapshotService
var sslHandler = sslhandler.NewHandler(requestBouncer)
sslHandler.SSLService = server.SSLService
openAMTHandler, err := openamt.NewHandler(requestBouncer, server.DataStore)
if err != nil {
return err
}
if openAMTHandler != nil {
openAMTHandler.OpenAMTService = server.OpenAMTService
openAMTHandler.DataStore = server.DataStore
}
var stackHandler = stacks.NewHandler(requestBouncer)
stackHandler.DataStore = server.DataStore
stackHandler.DockerClientFactory = server.DockerClientFactory
stackHandler.FileService = server.FileService
stackHandler.KubernetesDeployer = server.KubernetesDeployer
stackHandler.GitService = server.GitService
stackHandler.Scheduler = server.Scheduler
stackHandler.SwarmStackManager = server.SwarmStackManager
stackHandler.ComposeStackManager = server.ComposeStackManager
stackHandler.StackDeployer = server.StackDeployer
var storybookHandler = storybook.NewHandler(server.AssetsPath)
var tagHandler = tags.NewHandler(requestBouncer)
tagHandler.DataStore = server.DataStore
var teamHandler = teams.NewHandler(requestBouncer)
teamHandler.DataStore = server.DataStore
var teamMembershipHandler = teammemberships.NewHandler(requestBouncer)
teamMembershipHandler.DataStore = server.DataStore
var statusHandler = status.NewHandler(requestBouncer, server.Status)
var templatesHandler = templates.NewHandler(requestBouncer)
templatesHandler.DataStore = server.DataStore
templatesHandler.FileService = server.FileService
templatesHandler.GitService = server.GitService
var uploadHandler = upload.NewHandler(requestBouncer)
uploadHandler.FileService = server.FileService
var userHandler = users.NewHandler(requestBouncer, rateLimiter, server.APIKeyService)
userHandler.DataStore = server.DataStore
userHandler.CryptoService = server.CryptoService
var websocketHandler = websocket.NewHandler(server.KubernetesTokenCacheManager, requestBouncer)
websocketHandler.DataStore = server.DataStore
websocketHandler.SignatureService = server.SignatureService
websocketHandler.ReverseTunnelService = server.ReverseTunnelService
websocketHandler.KubernetesClientFactory = server.KubernetesClientFactory
var webhookHandler = webhooks.NewHandler(requestBouncer)
webhookHandler.DataStore = server.DataStore
webhookHandler.DockerClientFactory = server.DockerClientFactory
server.Handler = &handler.Handler{
RoleHandler: roleHandler,
AuthHandler: authHandler,
BackupHandler: backupHandler,
CustomTemplatesHandler: customTemplatesHandler,
EdgeGroupsHandler: edgeGroupsHandler,
EdgeJobsHandler: edgeJobsHandler,
EdgeStacksHandler: edgeStacksHandler,
EdgeTemplatesHandler: edgeTemplatesHandler,
EndpointGroupHandler: endpointGroupHandler,
EndpointHandler: endpointHandler,
EndpointHelmHandler: endpointHelmHandler,
EndpointEdgeHandler: endpointEdgeHandler,
EndpointProxyHandler: endpointProxyHandler,
FileHandler: fileHandler,
LDAPHandler: ldapHandler,
HelmTemplatesHandler: helmTemplatesHandler,
KubernetesHandler: kubernetesHandler,
MOTDHandler: motdHandler,
OpenAMTHandler: openAMTHandler,
RegistryHandler: registryHandler,
ResourceControlHandler: resourceControlHandler,
SettingsHandler: settingsHandler,
SSLHandler: sslHandler,
StatusHandler: statusHandler,
StackHandler: stackHandler,
StorybookHandler: storybookHandler,
TagHandler: tagHandler,
TeamHandler: teamHandler,
TeamMembershipHandler: teamMembershipHandler,
TemplatesHandler: templatesHandler,
UploadHandler: uploadHandler,
UserHandler: userHandler,
WebSocketHandler: websocketHandler,
WebhookHandler: webhookHandler,
}
handler := offlineGate.WaitingMiddleware(time.Minute, server.Handler)
if server.HTTPEnabled {
go func() {
log.Printf("[INFO] [http,server] [message: starting HTTP server on port %s]", server.BindAddress)
httpServer := &http.Server{
Addr: server.BindAddress,
Handler: handler,
}
go shutdown(server.ShutdownCtx, httpServer)
err := httpServer.ListenAndServe()
if err != nil && err != http.ErrServerClosed {
log.Printf("[ERROR] [message: http server failed] [error: %s]", err)
}
}()
}
log.Printf("[INFO] [http,server] [message: starting HTTPS server on port %s]", server.BindAddressHTTPS)
httpsServer := &http.Server{
Addr: server.BindAddressHTTPS,
Handler: handler,
}
httpsServer.TLSConfig = crypto.CreateServerTLSConfiguration()
httpsServer.TLSConfig.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
return server.SSLService.GetRawCertificate(), nil
}
go shutdown(server.ShutdownCtx, httpsServer)
return httpsServer.ListenAndServeTLS("", "")
}
func shutdown(shutdownCtx context.Context, httpServer *http.Server) {
<-shutdownCtx.Done()
log.Println("[DEBUG] [http,server] [message: shutting down http server]")
shutdownTimeout, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
err := httpServer.Shutdown(shutdownTimeout)
if err != nil {
fmt.Printf("[ERROR] [http,server] [message: failed shutdown http server] [error: %s]", err)
}
}