github.com/minio/console@v1.4.1/cmd/console/server.go (about)

     1  // This file is part of MinIO Console Server
     2  // Copyright (c) 2021 MinIO, Inc.
     3  //
     4  // This program is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Affero General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // This program is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  // GNU Affero General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Affero General Public License
    15  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package main
    18  
    19  import (
    20  	"fmt"
    21  	"os"
    22  	"path/filepath"
    23  	"syscall"
    24  
    25  	"github.com/go-openapi/loads"
    26  	"github.com/jessevdk/go-flags"
    27  	"github.com/minio/cli"
    28  	"github.com/minio/console/api"
    29  	"github.com/minio/console/api/operations"
    30  	"github.com/minio/console/pkg/certs"
    31  )
    32  
    33  // starts the server
    34  var serverCmd = cli.Command{
    35  	Name:    "server",
    36  	Aliases: []string{"srv"},
    37  	Usage:   "Start MinIO Console server",
    38  	Action:  StartServer,
    39  	Flags: []cli.Flag{
    40  		cli.StringFlag{
    41  			Name:  "host",
    42  			Value: api.GetHostname(),
    43  			Usage: "bind to a specific HOST, HOST can be an IP or hostname",
    44  		},
    45  		cli.IntFlag{
    46  			Name:  "port",
    47  			Value: api.GetPort(),
    48  			Usage: "bind to specific HTTP port",
    49  		},
    50  		// This is kept here for backward compatibility,
    51  		// hostname's do not have HTTP or HTTPs
    52  		// hostnames are opaque so using --host
    53  		// works for both HTTP and HTTPS setup.
    54  		cli.StringFlag{
    55  			Name:   "tls-host",
    56  			Value:  api.GetHostname(),
    57  			Hidden: true,
    58  		},
    59  		cli.StringFlag{
    60  			Name:  "certs-dir",
    61  			Value: certs.GlobalCertsCADir.Get(),
    62  			Usage: "path to certs directory",
    63  		},
    64  		cli.IntFlag{
    65  			Name:  "tls-port",
    66  			Value: api.GetTLSPort(),
    67  			Usage: "bind to specific HTTPS port",
    68  		},
    69  		cli.StringFlag{
    70  			Name:  "tls-redirect",
    71  			Value: api.GetTLSRedirect(),
    72  			Usage: "toggle HTTP->HTTPS redirect",
    73  		},
    74  		cli.StringFlag{
    75  			Name:   "tls-certificate",
    76  			Value:  "",
    77  			Usage:  "path to TLS public certificate",
    78  			Hidden: true,
    79  		},
    80  		cli.StringFlag{
    81  			Name:   "tls-key",
    82  			Value:  "",
    83  			Usage:  "path to TLS private key",
    84  			Hidden: true,
    85  		},
    86  		cli.StringFlag{
    87  			Name:   "tls-ca",
    88  			Value:  "",
    89  			Usage:  "path to TLS Certificate Authority",
    90  			Hidden: true,
    91  		},
    92  	},
    93  }
    94  
    95  func buildServer() (*api.Server, error) {
    96  	swaggerSpec, err := loads.Embedded(api.SwaggerJSON, api.FlatSwaggerJSON)
    97  	if err != nil {
    98  		return nil, err
    99  	}
   100  
   101  	consoleAPI := operations.NewConsoleAPI(swaggerSpec)
   102  	consoleAPI.Logger = api.LogInfo
   103  	server := api.NewServer(consoleAPI)
   104  
   105  	parser := flags.NewParser(server, flags.Default)
   106  	parser.ShortDescription = "MinIO Console Server"
   107  	parser.LongDescription = swaggerSpec.Spec().Info.Description
   108  
   109  	server.ConfigureFlags()
   110  
   111  	// register all APIs
   112  	server.ConfigureAPI()
   113  
   114  	for _, optsGroup := range consoleAPI.CommandLineOptionsGroups {
   115  		_, err := parser.AddGroup(optsGroup.ShortDescription, optsGroup.LongDescription, optsGroup.Options)
   116  		if err != nil {
   117  			return nil, err
   118  		}
   119  	}
   120  
   121  	if _, err := parser.Parse(); err != nil {
   122  		return nil, err
   123  	}
   124  
   125  	return server, nil
   126  }
   127  
   128  func loadAllCerts(ctx *cli.Context) error {
   129  	var err error
   130  	// Set all certs and CAs directories path
   131  	certs.GlobalCertsDir, _, err = certs.NewConfigDirFromCtx(ctx, "certs-dir", certs.DefaultCertsDir.Get)
   132  	if err != nil {
   133  		return err
   134  	}
   135  
   136  	certs.GlobalCertsCADir = &certs.ConfigDir{Path: filepath.Join(certs.GlobalCertsDir.Get(), certs.CertsCADir)}
   137  	// check if certs and CAs directories exists or can be created
   138  	if err = certs.MkdirAllIgnorePerm(certs.GlobalCertsCADir.Get()); err != nil {
   139  		return fmt.Errorf("unable to create certs CA directory at %s: failed with %w", certs.GlobalCertsCADir.Get(), err)
   140  	}
   141  
   142  	// load the certificates and the CAs
   143  	api.GlobalRootCAs, api.GlobalPublicCerts, api.GlobalTLSCertsManager, err = certs.GetAllCertificatesAndCAs()
   144  	if err != nil {
   145  		return fmt.Errorf("unable to load certificates at %s: failed with %w", certs.GlobalCertsDir.Get(), err)
   146  	}
   147  
   148  	{
   149  		// TLS flags from swagger server, used to support VMware vsphere operator version.
   150  		swaggerServerCertificate := ctx.String("tls-certificate")
   151  		swaggerServerCertificateKey := ctx.String("tls-key")
   152  		swaggerServerCACertificate := ctx.String("tls-ca")
   153  		// load tls cert and key from swagger server tls-certificate and tls-key flags
   154  		if swaggerServerCertificate != "" && swaggerServerCertificateKey != "" {
   155  			if err = api.GlobalTLSCertsManager.AddCertificate(swaggerServerCertificate, swaggerServerCertificateKey); err != nil {
   156  				return err
   157  			}
   158  			x509Certs, err := certs.ParsePublicCertFile(swaggerServerCertificate)
   159  			if err == nil {
   160  				api.GlobalPublicCerts = append(api.GlobalPublicCerts, x509Certs...)
   161  			}
   162  		}
   163  
   164  		// load ca cert from swagger server tls-ca flag
   165  		if swaggerServerCACertificate != "" {
   166  			caCert, caCertErr := os.ReadFile(swaggerServerCACertificate)
   167  			if caCertErr == nil {
   168  				api.GlobalRootCAs.AppendCertsFromPEM(caCert)
   169  			}
   170  		}
   171  	}
   172  
   173  	if api.GlobalTLSCertsManager != nil {
   174  		api.GlobalTLSCertsManager.ReloadOnSignal(syscall.SIGHUP)
   175  	}
   176  
   177  	return nil
   178  }