adding secure middleware to enforce security headers, most of the options can be configured via env variables adding prefix for mcs env variables adding http redirect to https, adding csp report only, etc solving conflicts passing tls port configured by cli to secure middleware update go.sum adding default port, tlsport, host and tlshostname fix tlsport bug
140 lines
3.6 KiB
Go
140 lines
3.6 KiB
Go
// This file is part of MinIO Console Server
|
||
// Copyright (c) 2020 MinIO, Inc.
|
||
//
|
||
// This program is free software: you can redistribute it and/or modify
|
||
// it under the terms of the GNU Affero General Public License as published by
|
||
// the Free Software Foundation, either version 3 of the License, or
|
||
// (at your option) any later version.
|
||
//
|
||
// This program is distributed in the hope that it will be useful,
|
||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
// GNU Affero General Public License for more details.
|
||
//
|
||
// You should have received a copy of the GNU Affero General Public License
|
||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
//
|
||
|
||
package main
|
||
|
||
import (
|
||
"os"
|
||
"path/filepath"
|
||
"sort"
|
||
|
||
"github.com/minio/mcs/pkg"
|
||
|
||
"github.com/minio/minio/pkg/console"
|
||
"github.com/minio/minio/pkg/trie"
|
||
"github.com/minio/minio/pkg/words"
|
||
|
||
"github.com/minio/cli"
|
||
)
|
||
|
||
// Help template for m3.
|
||
var mcsHelpTemplate = `NAME:
|
||
{{.Name}} - {{.Usage}}
|
||
|
||
DESCRIPTION:
|
||
{{.Description}}
|
||
|
||
USAGE:
|
||
{{.HelpName}} {{if .VisibleFlags}}[FLAGS] {{end}}COMMAND{{if .VisibleFlags}}{{end}} [ARGS...]
|
||
|
||
COMMANDS:
|
||
{{range .VisibleCommands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
|
||
{{end}}{{if .VisibleFlags}}
|
||
FLAGS:
|
||
{{range .VisibleFlags}}{{.}}
|
||
{{end}}{{end}}
|
||
VERSION:
|
||
{{.Version}}
|
||
`
|
||
|
||
var appCmds = []cli.Command{
|
||
serverCmd,
|
||
versionCmd,
|
||
}
|
||
|
||
func newApp(name string) *cli.App {
|
||
// Collection of m3 commands currently supported are.
|
||
var commands []cli.Command
|
||
|
||
// Collection of m3 commands currently supported in a trie tree.
|
||
commandsTree := trie.NewTrie()
|
||
|
||
// registerCommand registers a cli command.
|
||
registerCommand := func(command cli.Command) {
|
||
commands = append(commands, command)
|
||
commandsTree.Insert(command.Name)
|
||
}
|
||
|
||
// register commands
|
||
for _, cmd := range appCmds {
|
||
registerCommand(cmd)
|
||
}
|
||
|
||
findClosestCommands := func(command string) []string {
|
||
var closestCommands []string
|
||
for _, value := range commandsTree.PrefixMatch(command) {
|
||
closestCommands = append(closestCommands, value.(string))
|
||
}
|
||
|
||
sort.Strings(closestCommands)
|
||
// Suggest other close commands - allow missed, wrongly added and
|
||
// even transposed characters
|
||
for _, value := range commandsTree.Walk(commandsTree.Root()) {
|
||
if sort.SearchStrings(closestCommands, value.(string)) < len(closestCommands) {
|
||
continue
|
||
}
|
||
// 2 is arbitrary and represents the max
|
||
// allowed number of typed errors
|
||
if words.DamerauLevenshteinDistance(command, value.(string)) < 2 {
|
||
closestCommands = append(closestCommands, value.(string))
|
||
}
|
||
}
|
||
|
||
return closestCommands
|
||
}
|
||
|
||
cli.HelpFlag = cli.BoolFlag{
|
||
Name: "help, h",
|
||
Usage: "show help",
|
||
}
|
||
|
||
app := cli.NewApp()
|
||
app.Name = name
|
||
app.Version = pkg.Version
|
||
app.Author = "MinIO, Inc."
|
||
app.Usage = "mcs COMMAND"
|
||
app.Description = `MinIO Console Server`
|
||
app.Commands = commands
|
||
app.HideHelpCommand = true // Hide `help, h` command, we already have `minio --help`.
|
||
app.CustomAppHelpTemplate = mcsHelpTemplate
|
||
app.CommandNotFound = func(ctx *cli.Context, command string) {
|
||
console.Printf("‘%s’ is not a mcs sub-command. See ‘mcs --help’.\n", command)
|
||
closestCommands := findClosestCommands(command)
|
||
if len(closestCommands) > 0 {
|
||
console.Println()
|
||
console.Println("Did you mean one of these?")
|
||
for _, cmd := range closestCommands {
|
||
console.Printf("\t‘%s’\n", cmd)
|
||
}
|
||
}
|
||
|
||
os.Exit(1)
|
||
}
|
||
|
||
return app
|
||
}
|
||
|
||
func main() {
|
||
args := os.Args
|
||
// Set the orchestrator app name.
|
||
appName := filepath.Base(args[0])
|
||
// Run the app - exit on error.
|
||
if err := newApp(appName).Run(args); err != nil {
|
||
os.Exit(1)
|
||
}
|
||
}
|