2016-12-18 18:21:29 +13:00
|
|
|
package main // import "github.com/portainer/portainer"
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/portainer/portainer"
|
|
|
|
"github.com/portainer/portainer/bolt"
|
|
|
|
"github.com/portainer/portainer/cli"
|
2017-02-06 18:29:34 +13:00
|
|
|
"github.com/portainer/portainer/cron"
|
2016-12-18 18:21:29 +13:00
|
|
|
"github.com/portainer/portainer/crypto"
|
2016-12-26 09:34:02 +13:00
|
|
|
"github.com/portainer/portainer/file"
|
2016-12-18 18:21:29 +13:00
|
|
|
"github.com/portainer/portainer/http"
|
|
|
|
"github.com/portainer/portainer/jwt"
|
2017-08-10 10:35:23 +02:00
|
|
|
"github.com/portainer/portainer/ldap"
|
2016-12-18 18:21:29 +13:00
|
|
|
|
|
|
|
"log"
|
|
|
|
)
|
|
|
|
|
2017-02-07 16:26:12 +13:00
|
|
|
func initCLI() *portainer.CLIFlags {
|
2016-12-18 18:21:29 +13:00
|
|
|
var cli portainer.CLIService = &cli.Service{}
|
|
|
|
flags, err := cli.ParseFlags(portainer.APIVersion)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = cli.ValidateFlags(flags)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2017-02-07 16:26:12 +13:00
|
|
|
return flags
|
|
|
|
}
|
2016-12-18 18:21:29 +13:00
|
|
|
|
2017-02-07 16:26:12 +13:00
|
|
|
func initFileService(dataStorePath string) portainer.FileService {
|
|
|
|
fileService, err := file.NewService(dataStorePath, "")
|
2016-12-18 18:21:29 +13:00
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2017-02-07 16:26:12 +13:00
|
|
|
return fileService
|
|
|
|
}
|
2016-12-18 18:21:29 +13:00
|
|
|
|
2017-02-07 16:26:12 +13:00
|
|
|
func initStore(dataStorePath string) *bolt.Store {
|
2017-03-12 17:24:15 +01:00
|
|
|
store, err := bolt.NewStore(dataStorePath)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = store.Open()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = store.MigrateData()
|
2016-12-18 18:21:29 +13:00
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2017-02-07 16:26:12 +13:00
|
|
|
return store
|
|
|
|
}
|
2016-12-18 18:21:29 +13:00
|
|
|
|
2017-02-07 16:26:12 +13:00
|
|
|
func initJWTService(authenticationEnabled bool) portainer.JWTService {
|
|
|
|
if authenticationEnabled {
|
|
|
|
jwtService, err := jwt.NewService()
|
2017-02-01 22:13:48 +13:00
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2017-02-07 16:26:12 +13:00
|
|
|
return jwtService
|
2016-12-26 09:34:02 +13:00
|
|
|
}
|
2017-02-07 16:26:12 +13:00
|
|
|
return nil
|
|
|
|
}
|
2016-12-18 18:21:29 +13:00
|
|
|
|
2017-02-07 16:26:12 +13:00
|
|
|
func initCryptoService() portainer.CryptoService {
|
|
|
|
return &crypto.Service{}
|
|
|
|
}
|
2016-12-18 18:21:29 +13:00
|
|
|
|
2017-08-10 10:35:23 +02:00
|
|
|
func initLDAPService() portainer.LDAPService {
|
|
|
|
return &ldap.Service{}
|
|
|
|
}
|
|
|
|
|
2017-02-07 16:26:12 +13:00
|
|
|
func initEndpointWatcher(endpointService portainer.EndpointService, externalEnpointFile string, syncInterval string) bool {
|
2017-02-06 18:29:34 +13:00
|
|
|
authorizeEndpointMgmt := true
|
2017-02-07 16:26:12 +13:00
|
|
|
if externalEnpointFile != "" {
|
2017-02-06 18:29:34 +13:00
|
|
|
authorizeEndpointMgmt = false
|
2017-02-07 16:26:12 +13:00
|
|
|
log.Println("Using external endpoint definition. Endpoint management via the API will be disabled.")
|
|
|
|
endpointWatcher := cron.NewWatcher(endpointService, syncInterval)
|
|
|
|
err := endpointWatcher.WatchEndpointFile(externalEnpointFile)
|
2017-02-01 22:13:48 +13:00
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2016-12-26 09:34:02 +13:00
|
|
|
}
|
2017-02-07 16:26:12 +13:00
|
|
|
return authorizeEndpointMgmt
|
|
|
|
}
|
2017-02-06 18:29:34 +13:00
|
|
|
|
2017-06-01 10:14:55 +02:00
|
|
|
func initStatus(authorizeEndpointMgmt bool, flags *portainer.CLIFlags) *portainer.Status {
|
|
|
|
return &portainer.Status{
|
2017-03-03 12:54:22 +01:00
|
|
|
Analytics: !*flags.NoAnalytics,
|
2017-02-06 18:29:34 +13:00
|
|
|
Authentication: !*flags.NoAuth,
|
|
|
|
EndpointManagement: authorizeEndpointMgmt,
|
2017-06-01 10:14:55 +02:00
|
|
|
Version: portainer.APIVersion,
|
2017-02-06 18:29:34 +13:00
|
|
|
}
|
2017-02-07 16:26:12 +13:00
|
|
|
}
|
2016-12-26 09:34:02 +13:00
|
|
|
|
2017-06-20 13:00:32 +02:00
|
|
|
func initDockerHub(dockerHubService portainer.DockerHubService) error {
|
|
|
|
_, err := dockerHubService.DockerHub()
|
|
|
|
if err == portainer.ErrDockerHubNotFound {
|
|
|
|
dockerhub := &portainer.DockerHub{
|
|
|
|
Authentication: false,
|
|
|
|
Username: "",
|
|
|
|
Password: "",
|
|
|
|
}
|
|
|
|
return dockerHubService.StoreDockerHub(dockerhub)
|
|
|
|
} else if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-06-01 10:14:55 +02:00
|
|
|
func initSettings(settingsService portainer.SettingsService, flags *portainer.CLIFlags) error {
|
|
|
|
_, err := settingsService.Settings()
|
|
|
|
if err == portainer.ErrSettingsNotFound {
|
|
|
|
settings := &portainer.Settings{
|
|
|
|
LogoURL: *flags.Logo,
|
|
|
|
DisplayExternalContributors: true,
|
2017-08-10 10:35:23 +02:00
|
|
|
AuthenticationMethod: portainer.AuthenticationInternal,
|
|
|
|
LDAPSettings: portainer.LDAPSettings{
|
|
|
|
TLSConfig: portainer.TLSConfiguration{},
|
|
|
|
SearchSettings: []portainer.LDAPSearchSettings{
|
|
|
|
portainer.LDAPSearchSettings{},
|
|
|
|
},
|
|
|
|
},
|
2017-09-27 09:26:04 +02:00
|
|
|
AllowBindMountsForRegularUsers: true,
|
|
|
|
AllowPrivilegedModeForRegularUsers: true,
|
2017-06-01 10:14:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if *flags.Templates != "" {
|
|
|
|
settings.TemplatesURL = *flags.Templates
|
|
|
|
} else {
|
|
|
|
settings.TemplatesURL = portainer.DefaultTemplatesURL
|
|
|
|
}
|
|
|
|
|
|
|
|
if *flags.Labels != nil {
|
|
|
|
settings.BlackListedLabels = *flags.Labels
|
|
|
|
} else {
|
|
|
|
settings.BlackListedLabels = make([]portainer.Pair, 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
return settingsService.StoreSettings(settings)
|
|
|
|
} else if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-02-07 16:26:12 +13:00
|
|
|
func retrieveFirstEndpointFromDatabase(endpointService portainer.EndpointService) *portainer.Endpoint {
|
|
|
|
endpoints, err := endpointService.Endpoints()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
return &endpoints[0]
|
|
|
|
}
|
2016-12-18 18:21:29 +13:00
|
|
|
|
2017-02-07 16:26:12 +13:00
|
|
|
func main() {
|
|
|
|
flags := initCLI()
|
|
|
|
|
|
|
|
fileService := initFileService(*flags.Data)
|
|
|
|
|
|
|
|
store := initStore(*flags.Data)
|
|
|
|
defer store.Close()
|
|
|
|
|
|
|
|
jwtService := initJWTService(!*flags.NoAuth)
|
|
|
|
|
|
|
|
cryptoService := initCryptoService()
|
|
|
|
|
2017-08-10 10:35:23 +02:00
|
|
|
ldapService := initLDAPService()
|
|
|
|
|
2017-02-07 16:26:12 +13:00
|
|
|
authorizeEndpointMgmt := initEndpointWatcher(store.EndpointService, *flags.ExternalEndpoints, *flags.SyncInterval)
|
|
|
|
|
2017-06-01 10:14:55 +02:00
|
|
|
err := initSettings(store.SettingsService, flags)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2017-06-20 13:00:32 +02:00
|
|
|
err = initDockerHub(store.DockerHubService)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2017-06-01 10:14:55 +02:00
|
|
|
applicationStatus := initStatus(authorizeEndpointMgmt, flags)
|
2017-02-07 16:26:12 +13:00
|
|
|
|
2017-03-12 17:24:15 +01:00
|
|
|
if *flags.Endpoint != "" {
|
|
|
|
var endpoints []portainer.Endpoint
|
|
|
|
endpoints, err := store.EndpointService.Endpoints()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
if len(endpoints) == 0 {
|
|
|
|
endpoint := &portainer.Endpoint{
|
2017-09-14 08:08:37 +02:00
|
|
|
Name: "primary",
|
|
|
|
URL: *flags.Endpoint,
|
|
|
|
TLSConfig: portainer.TLSConfiguration{
|
|
|
|
TLS: *flags.TLSVerify,
|
|
|
|
TLSSkipVerify: false,
|
|
|
|
TLSCACertPath: *flags.TLSCacert,
|
|
|
|
TLSCertPath: *flags.TLSCert,
|
|
|
|
TLSKeyPath: *flags.TLSKey,
|
|
|
|
},
|
2017-05-23 20:56:10 +02:00
|
|
|
AuthorizedUsers: []portainer.UserID{},
|
|
|
|
AuthorizedTeams: []portainer.TeamID{},
|
2017-03-12 17:24:15 +01:00
|
|
|
}
|
|
|
|
err = store.EndpointService.CreateEndpoint(endpoint)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
log.Println("Instance already has defined endpoints. Skipping the endpoint defined via CLI.")
|
|
|
|
}
|
|
|
|
}
|
2016-12-18 18:21:29 +13:00
|
|
|
|
2017-09-25 18:13:56 +02:00
|
|
|
adminPasswordHash := ""
|
|
|
|
if *flags.AdminPasswordFile != "" {
|
|
|
|
content, err := file.GetStringFromFile(*flags.AdminPasswordFile)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
adminPasswordHash, err = cryptoService.Hash(content)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
} else if *flags.AdminPassword != "" {
|
|
|
|
adminPasswordHash = *flags.AdminPassword
|
|
|
|
}
|
|
|
|
|
|
|
|
if adminPasswordHash != "" {
|
|
|
|
|
|
|
|
log.Printf("Creating admin user with password hash %s", adminPasswordHash)
|
2017-04-16 17:54:51 +10:00
|
|
|
user := &portainer.User{
|
|
|
|
Username: "admin",
|
|
|
|
Role: portainer.AdministratorRole,
|
2017-09-25 18:13:56 +02:00
|
|
|
Password: adminPasswordHash,
|
2017-04-16 17:54:51 +10:00
|
|
|
}
|
|
|
|
err := store.UserService.CreateUser(user)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-18 18:21:29 +13:00
|
|
|
var server portainer.Server = &http.Server{
|
2017-06-01 10:14:55 +02:00
|
|
|
Status: applicationStatus,
|
2017-03-12 17:24:15 +01:00
|
|
|
BindAddress: *flags.Addr,
|
|
|
|
AssetsPath: *flags.Assets,
|
|
|
|
AuthDisabled: *flags.NoAuth,
|
|
|
|
EndpointManagement: authorizeEndpointMgmt,
|
|
|
|
UserService: store.UserService,
|
2017-05-23 20:56:10 +02:00
|
|
|
TeamService: store.TeamService,
|
|
|
|
TeamMembershipService: store.TeamMembershipService,
|
2017-03-12 17:24:15 +01:00
|
|
|
EndpointService: store.EndpointService,
|
|
|
|
ResourceControlService: store.ResourceControlService,
|
2017-06-01 10:14:55 +02:00
|
|
|
SettingsService: store.SettingsService,
|
2017-06-20 13:00:32 +02:00
|
|
|
RegistryService: store.RegistryService,
|
|
|
|
DockerHubService: store.DockerHubService,
|
2017-03-12 17:24:15 +01:00
|
|
|
CryptoService: cryptoService,
|
|
|
|
JWTService: jwtService,
|
|
|
|
FileService: fileService,
|
2017-08-10 10:35:23 +02:00
|
|
|
LDAPService: ldapService,
|
2017-04-25 11:51:22 +02:00
|
|
|
SSL: *flags.SSL,
|
|
|
|
SSLCert: *flags.SSLCert,
|
|
|
|
SSLKey: *flags.SSLKey,
|
2016-12-18 18:21:29 +13:00
|
|
|
}
|
|
|
|
|
2017-09-04 19:04:30 +02:00
|
|
|
log.Printf("Starting Portainer %s on %s", portainer.APIVersion, *flags.Addr)
|
2017-06-01 10:14:55 +02:00
|
|
|
err = server.Start()
|
2016-12-18 18:21:29 +13:00
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|