2016-12-18 05:21:29 +00:00
package cli
import (
2017-06-01 08:14:55 +00:00
"log"
2017-02-06 05:29:34 +00:00
"time"
2016-12-18 05:21:29 +00:00
"github.com/portainer/portainer"
"os"
"strings"
2016-12-25 20:34:02 +00:00
"gopkg.in/alecthomas/kingpin.v2"
2016-12-18 05:21:29 +00:00
)
// Service implements the CLIService interface
type Service struct { }
const (
2017-09-25 16:13:56 +00:00
errInvalidEndpointProtocol = portainer . Error ( "Invalid endpoint protocol: Portainer only supports unix:// or tcp://" )
errSocketNotFound = portainer . Error ( "Unable to locate Unix socket" )
errEndpointsFileNotFound = portainer . Error ( "Unable to locate external endpoints file" )
errInvalidSyncInterval = portainer . Error ( "Invalid synchronization interval" )
errEndpointExcludeExternal = portainer . Error ( "Cannot use the -H flag mutually with --external-endpoints" )
errNoAuthExcludeAdminPassword = portainer . Error ( "Cannot use --no-auth with --admin-password or --admin-password-file" )
errAdminPassExcludeAdminPassFile = portainer . Error ( "Cannot use --admin-password with --admin-password-file" )
2016-12-18 05:21:29 +00:00
)
// ParseFlags parse the CLI flags and return a portainer.Flags struct
func ( * Service ) ParseFlags ( version string ) ( * portainer . CLIFlags , error ) {
kingpin . Version ( version )
flags := & portainer . CLIFlags {
2017-02-06 05:29:34 +00:00
Endpoint : kingpin . Flag ( "host" , "Dockerd endpoint" ) . Short ( 'H' ) . String ( ) ,
ExternalEndpoints : kingpin . Flag ( "external-endpoints" , "Path to a file defining available endpoints" ) . String ( ) ,
SyncInterval : kingpin . Flag ( "sync-interval" , "Duration between each synchronization via the external endpoints source" ) . Default ( defaultSyncInterval ) . String ( ) ,
Addr : kingpin . Flag ( "bind" , "Address and port to serve Portainer" ) . Default ( defaultBindAddress ) . Short ( 'p' ) . String ( ) ,
Assets : kingpin . Flag ( "assets" , "Path to the assets" ) . Default ( defaultAssetsDirectory ) . Short ( 'a' ) . String ( ) ,
Data : kingpin . Flag ( "data" , "Path to the folder where the data is stored" ) . Default ( defaultDataDirectory ) . Short ( 'd' ) . String ( ) ,
NoAuth : kingpin . Flag ( "no-auth" , "Disable authentication" ) . Default ( defaultNoAuth ) . Bool ( ) ,
2017-09-10 08:00:48 +00:00
NoAnalytics : kingpin . Flag ( "no-analytics" , "Disable Analytics in app" ) . Default ( defaultNoAnalytics ) . Bool ( ) ,
2017-02-06 05:29:34 +00:00
TLSVerify : kingpin . Flag ( "tlsverify" , "TLS support" ) . Default ( defaultTLSVerify ) . Bool ( ) ,
TLSCacert : kingpin . Flag ( "tlscacert" , "Path to the CA" ) . Default ( defaultTLSCACertPath ) . String ( ) ,
TLSCert : kingpin . Flag ( "tlscert" , "Path to the TLS certificate file" ) . Default ( defaultTLSCertPath ) . String ( ) ,
TLSKey : kingpin . Flag ( "tlskey" , "Path to the TLS key" ) . Default ( defaultTLSKeyPath ) . String ( ) ,
2017-04-25 09:51:22 +00:00
SSL : kingpin . Flag ( "ssl" , "Secure Portainer instance using SSL" ) . Default ( defaultSSL ) . Bool ( ) ,
SSLCert : kingpin . Flag ( "sslcert" , "Path to the SSL certificate used to secure the Portainer instance" ) . Default ( defaultSSLCertPath ) . String ( ) ,
SSLKey : kingpin . Flag ( "sslkey" , "Path to the SSL key used to secure the Portainer instance" ) . Default ( defaultSSLKeyPath ) . String ( ) ,
2017-04-16 07:54:51 +00:00
AdminPassword : kingpin . Flag ( "admin-password" , "Hashed admin password" ) . String ( ) ,
2017-09-25 16:13:56 +00:00
AdminPasswordFile : kingpin . Flag ( "admin-password-file" , "Path to the file containing the password for the admin user" ) . String ( ) ,
2017-06-01 08:14:55 +00:00
// Deprecated flags
Labels : pairs ( kingpin . Flag ( "hide-label" , "Hide containers with a specific label in the UI" ) . Short ( 'l' ) ) ,
Logo : kingpin . Flag ( "logo" , "URL for the logo displayed in the UI" ) . String ( ) ,
Templates : kingpin . Flag ( "templates" , "URL to the templates (apps) definitions" ) . Short ( 't' ) . String ( ) ,
2016-12-18 05:21:29 +00:00
}
kingpin . Parse ( )
return flags , nil
}
// ValidateFlags validates the values of the flags.
func ( * Service ) ValidateFlags ( flags * portainer . CLIFlags ) error {
2017-02-07 03:26:12 +00:00
if * flags . Endpoint != "" && * flags . ExternalEndpoints != "" {
return errEndpointExcludeExternal
}
err := validateEndpoint ( * flags . Endpoint )
if err != nil {
return err
}
err = validateExternalEndpoints ( * flags . ExternalEndpoints )
if err != nil {
return err
}
err = validateSyncInterval ( * flags . SyncInterval )
if err != nil {
return err
}
2017-09-25 16:13:56 +00:00
if * flags . NoAuth && ( * flags . AdminPassword != "" || * flags . AdminPasswordFile != "" ) {
2017-05-23 19:01:19 +00:00
return errNoAuthExcludeAdminPassword
}
2017-04-16 07:54:51 +00:00
2017-09-25 16:13:56 +00:00
if * flags . AdminPassword != "" && * flags . AdminPasswordFile != "" {
return errAdminPassExcludeAdminPassFile
}
2017-06-01 08:14:55 +00:00
displayDeprecationWarnings ( * flags . Templates , * flags . Logo , * flags . Labels )
2017-02-07 03:26:12 +00:00
return nil
}
func validateEndpoint ( endpoint string ) error {
if endpoint != "" {
if ! strings . HasPrefix ( endpoint , "unix://" ) && ! strings . HasPrefix ( endpoint , "tcp://" ) {
2017-04-16 07:54:51 +00:00
return errInvalidEndpointProtocol
2016-12-25 20:34:02 +00:00
}
2016-12-18 05:21:29 +00:00
2017-02-07 03:26:12 +00:00
if strings . HasPrefix ( endpoint , "unix://" ) {
socketPath := strings . TrimPrefix ( endpoint , "unix://" )
2016-12-25 20:34:02 +00:00
if _ , err := os . Stat ( socketPath ) ; err != nil {
if os . IsNotExist ( err ) {
return errSocketNotFound
}
return err
2016-12-18 05:21:29 +00:00
}
}
}
2017-02-07 03:26:12 +00:00
return nil
}
2016-12-18 05:21:29 +00:00
2017-02-07 03:26:12 +00:00
func validateExternalEndpoints ( externalEndpoints string ) error {
if externalEndpoints != "" {
if _ , err := os . Stat ( externalEndpoints ) ; err != nil {
2017-02-06 05:29:34 +00:00
if os . IsNotExist ( err ) {
return errEndpointsFileNotFound
}
return err
}
}
2017-02-07 03:26:12 +00:00
return nil
}
2017-02-06 05:29:34 +00:00
2017-02-07 03:26:12 +00:00
func validateSyncInterval ( syncInterval string ) error {
if syncInterval != defaultSyncInterval {
_ , err := time . ParseDuration ( syncInterval )
2017-02-06 05:29:34 +00:00
if err != nil {
return errInvalidSyncInterval
}
}
2016-12-18 05:21:29 +00:00
return nil
}
2017-06-01 08:14:55 +00:00
func displayDeprecationWarnings ( templates , logo string , labels [ ] portainer . Pair ) {
if templates != "" {
log . Println ( "Warning: the --templates / -t flag is deprecated and will be removed in future versions." )
}
if logo != "" {
log . Println ( "Warning: the --logo flag is deprecated and will be removed in future versions." )
}
if labels != nil {
log . Println ( "Warning: the --hide-label / -l flag is deprecated and will be removed in future versions." )
}
}