portainer/api/api.go

103 lines
1.9 KiB
Go

package main
import (
"crypto/tls"
"errors"
"github.com/gorilla/securecookie"
"log"
"net/http"
"net/url"
)
type (
api struct {
endpoint *url.URL
bindAddress string
assetPath string
dataPath string
tlsConfig *tls.Config
templatesURL string
dataStore *dataStore
secret []byte
}
apiConfig struct {
Endpoint string
BindAddress string
AssetPath string
DataPath string
SwarmSupport bool
TLSEnabled bool
TLSCACertPath string
TLSCertPath string
TLSKeyPath string
TemplatesURL string
}
)
const (
datastoreFileName = "portainer.db"
)
var (
errSecretKeyGeneration = errors.New("Unable to generate secret key to sign JWT")
)
func (a *api) run(settings *Settings) {
err := a.initDatabase()
if err != nil {
log.Fatal(err)
}
defer a.cleanUp()
handler := a.newHandler(settings)
log.Printf("Starting portainer on %s", a.bindAddress)
if err := http.ListenAndServe(a.bindAddress, handler); err != nil {
log.Fatal(err)
}
}
func (a *api) cleanUp() {
a.dataStore.cleanUp()
}
func (a *api) initDatabase() error {
dataStore, err := newDataStore(a.dataPath + "/" + datastoreFileName)
if err != nil {
return err
}
err = dataStore.initDataStore()
if err != nil {
return err
}
a.dataStore = dataStore
return nil
}
func newAPI(apiConfig apiConfig) *api {
endpointURL, err := url.Parse(apiConfig.Endpoint)
if err != nil {
log.Fatal(err)
}
secret := securecookie.GenerateRandomKey(32)
if secret == nil {
log.Fatal(errSecretKeyGeneration)
}
var tlsConfig *tls.Config
if apiConfig.TLSEnabled {
tlsConfig = newTLSConfig(apiConfig.TLSCACertPath, apiConfig.TLSCertPath, apiConfig.TLSKeyPath)
}
return &api{
endpoint: endpointURL,
bindAddress: apiConfig.BindAddress,
assetPath: apiConfig.AssetPath,
dataPath: apiConfig.DataPath,
tlsConfig: tlsConfig,
templatesURL: apiConfig.TemplatesURL,
secret: secret,
}
}