ci: add dedicated authelia-gen command (#3463)
Adds a dedicated authelia code/doc gen command.pull/3518/head
parent
802b21f3b5
commit
5304178165
|
@ -0,0 +1,34 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newAllCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "all",
|
||||
Short: "Run all generators with default options",
|
||||
RunE: allRunE,
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func allRunE(cmd *cobra.Command, args []string) (err error) {
|
||||
for _, subCmd := range cmd.Parent().Commands() {
|
||||
if subCmd == cmd || subCmd.Use == "completion" || subCmd.Use == "help [command]" {
|
||||
continue
|
||||
}
|
||||
|
||||
switch {
|
||||
case subCmd.RunE != nil:
|
||||
if err = subCmd.RunE(subCmd, args); err != nil {
|
||||
return err
|
||||
}
|
||||
case subCmd.Run != nil:
|
||||
subCmd.Run(subCmd, args)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newCodeCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "code",
|
||||
Short: "Generate code",
|
||||
RunE: codeRunE,
|
||||
}
|
||||
|
||||
cmd.AddCommand(newCodeKeysCmd())
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func codeRunE(cmd *cobra.Command, args []string) (err error) {
|
||||
for _, subCmd := range cmd.Commands() {
|
||||
switch {
|
||||
case subCmd.RunE != nil:
|
||||
if err = subCmd.RunE(subCmd, args); err != nil {
|
||||
return err
|
||||
}
|
||||
case subCmd.Run != nil:
|
||||
subCmd.Run(subCmd, args)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -16,92 +16,63 @@ import (
|
|||
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
||||
)
|
||||
|
||||
// NewRunGenCmd implements the code generation cobra command.
|
||||
func NewRunGenCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "gen",
|
||||
RunE: runGenE,
|
||||
func newCodeKeysCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "keys",
|
||||
Short: "Generate the list of valid configuration keys",
|
||||
RunE: codeKeysRunE,
|
||||
}
|
||||
|
||||
cmd.Flags().StringP("file", "f", "./internal/configuration/schema/keys.go", "Sets the path of the keys file")
|
||||
cmd.Flags().String("package", "schema", "Sets the package name of the keys file")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func runGenE(cmd *cobra.Command, args []string) (err error) {
|
||||
if err = genConfigurationKeys(); err != nil {
|
||||
func codeKeysRunE(cmd *cobra.Command, args []string) (err error) {
|
||||
var (
|
||||
file string
|
||||
|
||||
f *os.File
|
||||
)
|
||||
|
||||
data := keysTemplateStruct{
|
||||
Timestamp: time.Now(),
|
||||
Keys: readTags("", reflect.TypeOf(schema.Configuration{})),
|
||||
}
|
||||
|
||||
if file, err = cmd.Flags().GetString("file"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func genConfigurationKeys() (err error) {
|
||||
data := loadKeysTemplate()
|
||||
|
||||
f, err := os.Create("./internal/configuration/schema/keys.go")
|
||||
if err != nil {
|
||||
if data.Package, err = cmd.Flags().GetString("package"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return keysTemplate.Execute(f, data)
|
||||
if f, err = os.Create(file); err != nil {
|
||||
return fmt.Errorf("failed to create file '%s': %w", file, err)
|
||||
}
|
||||
|
||||
var (
|
||||
content []byte
|
||||
tmpl *template.Template
|
||||
)
|
||||
|
||||
if content, err = templatesFS.ReadFile("templates/config_keys.go.tmpl"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if tmpl, err = template.New("keys").Parse(string(content)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tmpl.Execute(f, data)
|
||||
}
|
||||
|
||||
var keysTemplate = template.Must(template.New("keys").Parse(`// Code generated by go generate. DO NOT EDIT.
|
||||
//
|
||||
// Run the following command to generate this file:
|
||||
// go run ./cmd/authelia-scripts gen
|
||||
//
|
||||
|
||||
package schema
|
||||
|
||||
// Keys represents the detected schema keys.
|
||||
var Keys = []string{
|
||||
{{- range .Keys }}
|
||||
{{ printf "%q" . }},
|
||||
{{- end }}
|
||||
}
|
||||
`))
|
||||
|
||||
type keysTemplateStruct struct {
|
||||
Timestamp time.Time
|
||||
Keys []string
|
||||
}
|
||||
|
||||
func loadKeysTemplate() keysTemplateStruct {
|
||||
config := schema.Configuration{
|
||||
Storage: schema.StorageConfiguration{
|
||||
Local: &schema.LocalStorageConfiguration{},
|
||||
MySQL: &schema.MySQLStorageConfiguration{},
|
||||
PostgreSQL: &schema.PostgreSQLStorageConfiguration{},
|
||||
},
|
||||
Notifier: schema.NotifierConfiguration{
|
||||
FileSystem: &schema.FileSystemNotifierConfiguration{},
|
||||
SMTP: &schema.SMTPNotifierConfiguration{
|
||||
TLS: &schema.TLSConfig{},
|
||||
},
|
||||
},
|
||||
AuthenticationBackend: schema.AuthenticationBackendConfiguration{
|
||||
File: &schema.FileAuthenticationBackendConfiguration{
|
||||
Password: &schema.PasswordConfiguration{},
|
||||
},
|
||||
LDAP: &schema.LDAPAuthenticationBackendConfiguration{
|
||||
TLS: &schema.TLSConfig{},
|
||||
},
|
||||
},
|
||||
Session: schema.SessionConfiguration{
|
||||
Redis: &schema.RedisSessionConfiguration{
|
||||
TLS: &schema.TLSConfig{},
|
||||
HighAvailability: &schema.RedisHighAvailabilityConfiguration{},
|
||||
},
|
||||
},
|
||||
IdentityProviders: schema.IdentityProvidersConfiguration{
|
||||
OIDC: &schema.OpenIDConnectConfiguration{},
|
||||
},
|
||||
}
|
||||
|
||||
return keysTemplateStruct{
|
||||
Timestamp: time.Now(),
|
||||
Keys: readTags("", reflect.TypeOf(config)),
|
||||
}
|
||||
Package string
|
||||
}
|
||||
|
||||
var decodedTypes = []reflect.Type{
|
|
@ -0,0 +1,33 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newDocsCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "docs",
|
||||
Short: "Generate docs",
|
||||
RunE: docsRunE,
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().StringP("cwd", "C", "", "Sets the CWD for git commands")
|
||||
cmd.AddCommand(newDocsCLICmd(), newDocsDateCmd())
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func docsRunE(cmd *cobra.Command, args []string) (err error) {
|
||||
for _, subCmd := range cmd.Commands() {
|
||||
switch {
|
||||
case subCmd.RunE != nil:
|
||||
if err = subCmd.RunE(subCmd, args); err != nil {
|
||||
return err
|
||||
}
|
||||
case subCmd.Run != nil:
|
||||
subCmd.Run(subCmd, args)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/cobra/doc"
|
||||
|
||||
cmdscripts "github.com/authelia/authelia/v4/cmd/authelia-scripts/cmd"
|
||||
"github.com/authelia/authelia/v4/internal/commands"
|
||||
)
|
||||
|
||||
func newDocsCLICmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "cli",
|
||||
Short: "Generate CLI docs",
|
||||
RunE: docsCLIRunE,
|
||||
}
|
||||
|
||||
cmd.Flags().StringP("directory", "d", "./docs/content/en/reference/cli", "The directory to store the markdown in")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func docsCLIRunE(cmd *cobra.Command, args []string) (err error) {
|
||||
var root string
|
||||
|
||||
if root, err = cmd.Flags().GetString("directory"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = os.MkdirAll(root, 0775); err != nil {
|
||||
if !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err = genCLIDoc(commands.NewRootCmd(), filepath.Join(root, "authelia")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = genCLIDocWriteIndex(root, "authelia"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = genCLIDoc(cmdscripts.NewRootCmd(), filepath.Join(root, "authelia-scripts")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = genCLIDocWriteIndex(root, "authelia-scripts"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = genCLIDoc(newRootCmd(), filepath.Join(root, "authelia-gen")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = genCLIDocWriteIndex(root, "authelia-gen"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func genCLIDoc(cmd *cobra.Command, path string) (err error) {
|
||||
if err = os.Mkdir(path, 0755); err != nil {
|
||||
if !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err = doc.GenMarkdownTreeCustom(cmd, path, prepend, linker); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func genCLIDocWriteIndex(path, name string) (err error) {
|
||||
now := time.Now()
|
||||
|
||||
f, err := os.Create(filepath.Join(path, name, "_index.md"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
weight := 900
|
||||
|
||||
if name == "authelia" {
|
||||
weight = 320
|
||||
}
|
||||
|
||||
_, err = fmt.Fprintf(f, indexDocs, name, now.Format(dateFmtYAML), "cli-"+name, weight)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func prepend(input string) string {
|
||||
now := time.Now()
|
||||
|
||||
pathz := strings.Split(strings.Replace(input, ".md", "", 1), "\\")
|
||||
parts := strings.Split(pathz[len(pathz)-1], "_")
|
||||
|
||||
cmd := parts[0]
|
||||
|
||||
args := strings.Join(parts, " ")
|
||||
|
||||
weight := 330
|
||||
if len(parts) == 1 {
|
||||
weight = 320
|
||||
}
|
||||
|
||||
return fmt.Sprintf(prefixDocs, args, fmt.Sprintf("Reference for the %s command.", args), "", now.Format(dateFmtYAML), "cli-"+cmd, weight)
|
||||
}
|
||||
|
||||
func linker(input string) string {
|
||||
return input
|
||||
}
|
||||
|
||||
const indexDocs = `---
|
||||
title: "%s"
|
||||
description: ""
|
||||
lead: ""
|
||||
date: %s
|
||||
draft: false
|
||||
images: []
|
||||
menu:
|
||||
reference:
|
||||
parent: "cli"
|
||||
identifier: "%s"
|
||||
weight: %d
|
||||
toc: true
|
||||
---
|
||||
`
|
||||
|
||||
const prefixDocs = `---
|
||||
title: "%s"
|
||||
description: "%s"
|
||||
lead: "%s"
|
||||
date: %s
|
||||
draft: false
|
||||
images: []
|
||||
menu:
|
||||
reference:
|
||||
parent: "%s"
|
||||
weight: %d
|
||||
toc: true
|
||||
---
|
||||
|
||||
`
|
|
@ -0,0 +1,220 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func newDocsDateCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "date",
|
||||
Short: "Generate doc dates",
|
||||
RunE: docsDateRunE,
|
||||
}
|
||||
|
||||
cmd.Flags().StringP("directory", "d", "./docs/content", "The directory to modify")
|
||||
cmd.Flags().String("commit-until", "HEAD", "The commit to check the logs until")
|
||||
cmd.Flags().String("commit-since", "", "The commit to check the logs since")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func docsDateRunE(cmd *cobra.Command, args []string) (err error) {
|
||||
var (
|
||||
dir, cwd, commitUtil, commitSince, commitFilter string
|
||||
)
|
||||
|
||||
if dir, err = cmd.Flags().GetString("directory"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cwd, err = cmd.Flags().GetString("cwd"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("commit-since") {
|
||||
if commitUtil, err = cmd.Flags().GetString("commit-util"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if commitSince, err = cmd.Flags().GetString("commit-since"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
commitFilter = fmt.Sprintf("%s...%s", commitUtil, commitSince)
|
||||
}
|
||||
|
||||
return filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !strings.HasSuffix(info.Name(), ".md") {
|
||||
return nil
|
||||
}
|
||||
|
||||
abs, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
frontmatterBytes := getFrontmatter(abs)
|
||||
|
||||
if frontmatterBytes == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
frontmatter := map[string]interface{}{}
|
||||
|
||||
if err = yaml.Unmarshal(frontmatterBytes, frontmatter); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var (
|
||||
date time.Time
|
||||
)
|
||||
|
||||
if value, ok := frontmatter["date"]; ok {
|
||||
date = value.(time.Time)
|
||||
}
|
||||
|
||||
dateGit := getDateFromGit(cwd, abs, commitFilter)
|
||||
|
||||
replaceDates(abs, date, dateGit)
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
var newline = []byte("\n")
|
||||
|
||||
func getDateFromGit(cwd, path, commitFilter string) *time.Time {
|
||||
var args []string
|
||||
|
||||
if len(cwd) != 0 {
|
||||
args = append(args, "-C", cwd)
|
||||
}
|
||||
|
||||
args = append(args, "log")
|
||||
|
||||
if len(commitFilter) != 0 {
|
||||
args = append(args, commitFilter)
|
||||
}
|
||||
|
||||
args = append(args, "-1", "--follow", "--diff-filter=A", "--pretty=format:%cD", "--", path)
|
||||
|
||||
return getTimeFromGitCmd(exec.Command("git", args...))
|
||||
}
|
||||
|
||||
func getTimeFromGitCmd(cmd *exec.Cmd) *time.Time {
|
||||
var (
|
||||
output []byte
|
||||
err error
|
||||
t time.Time
|
||||
)
|
||||
|
||||
if output, err = cmd.Output(); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if t, err = time.Parse(dateFmtRFC2822, string(output)); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &t
|
||||
}
|
||||
|
||||
func replaceDates(path string, date time.Time, dateGit *time.Time) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
buf := bytes.Buffer{}
|
||||
|
||||
scanner := bufio.NewScanner(f)
|
||||
|
||||
var dateGitLine string
|
||||
|
||||
dateLine := fmt.Sprintf("date: %s", date.Format(dateFmtYAML))
|
||||
|
||||
if dateGit != nil {
|
||||
dateGitLine = fmt.Sprintf("date: %s", dateGit.Format(dateFmtYAML))
|
||||
} else {
|
||||
dateGitLine = dateLine
|
||||
}
|
||||
|
||||
found := 0
|
||||
|
||||
frontmatter := 0
|
||||
|
||||
for scanner.Scan() {
|
||||
if found < 2 && frontmatter < 2 {
|
||||
switch {
|
||||
case scanner.Text() == frontmatterDelimiterLine:
|
||||
buf.Write(scanner.Bytes())
|
||||
frontmatter++
|
||||
case frontmatter != 0 && strings.HasPrefix(scanner.Text(), "date: "):
|
||||
buf.WriteString(dateGitLine)
|
||||
found++
|
||||
default:
|
||||
buf.Write(scanner.Bytes())
|
||||
}
|
||||
} else {
|
||||
buf.Write(scanner.Bytes())
|
||||
}
|
||||
|
||||
buf.Write(newline)
|
||||
}
|
||||
|
||||
f.Close()
|
||||
|
||||
newF, err := os.Create(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, _ = buf.WriteTo(newF)
|
||||
|
||||
newF.Close()
|
||||
}
|
||||
|
||||
func getFrontmatter(path string) []byte {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
scanner := bufio.NewScanner(f)
|
||||
|
||||
var start bool
|
||||
|
||||
buf := bytes.Buffer{}
|
||||
|
||||
for scanner.Scan() {
|
||||
if start {
|
||||
if scanner.Text() == frontmatterDelimiterLine {
|
||||
break
|
||||
}
|
||||
|
||||
buf.Write(scanner.Bytes())
|
||||
buf.Write(newline)
|
||||
} else if scanner.Text() == frontmatterDelimiterLine {
|
||||
start = true
|
||||
}
|
||||
}
|
||||
|
||||
return buf.Bytes()
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package main
|
||||
|
||||
const (
|
||||
dateFmtRFC2822 = "Mon, _2 Jan 2006 15:04:05 -0700"
|
||||
dateFmtYAML = "2006-01-02T15:04:05-07:00"
|
||||
frontmatterDelimiterLine = "---"
|
||||
)
|
|
@ -0,0 +1,27 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
//go:embed templates/*
|
||||
var templatesFS embed.FS
|
||||
|
||||
func main() {
|
||||
if err := newRootCmd().Execute(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func newRootCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "authelia-gen",
|
||||
Short: "Authelia's generator tooling",
|
||||
}
|
||||
|
||||
cmd.AddCommand(newAllCmd(), newCodeCmd(), newDocsCmd())
|
||||
|
||||
return cmd
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
// Code generated by go generate. DO NOT EDIT.
|
||||
//
|
||||
// Run the following command to generate this file:
|
||||
// go run ./cmd/authelia-gen code keys
|
||||
//
|
||||
|
||||
package {{ .Package }}
|
||||
|
||||
// Keys is a list of valid schema keys detected by reflecting over a schema.Configuration struct.
|
||||
var Keys = []string{
|
||||
{{- range .Keys }}
|
||||
{{ printf "%q" . }},
|
||||
{{- end }}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package main
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
@ -12,10 +12,53 @@ import (
|
|||
"github.com/authelia/authelia/v4/internal/utils"
|
||||
)
|
||||
|
||||
// HostEntry represents an entry in /etc/hosts.
|
||||
type HostEntry struct {
|
||||
Domain string
|
||||
IP string
|
||||
func newBootstrapCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "bootstrap",
|
||||
Short: cmdBootstrapShort,
|
||||
Long: cmdBootstrapLong,
|
||||
Example: cmdBootstrapExample,
|
||||
Args: cobra.NoArgs,
|
||||
Run: cmdBootstrapRun,
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func cmdBootstrapRun(_ *cobra.Command, _ []string) {
|
||||
bootstrapPrintln("Checking command installation...")
|
||||
checkCommandExist("node", "Follow installation guidelines from https://nodejs.org/en/download/package-manager/ or download installer from https://nodejs.org/en/download/")
|
||||
checkCommandExist("pnpm", "Follow installation guidelines from https://pnpm.io/installation")
|
||||
checkCommandExist("docker", "Follow installation guidelines from https://docs.docker.com/get-docker/")
|
||||
checkCommandExist("docker-compose", "Follow installation guidelines from https://docs.docker.com/compose/install/")
|
||||
|
||||
bootstrapPrintln("Getting versions of tools")
|
||||
readVersions()
|
||||
|
||||
bootstrapPrintln("Checking if GOPATH is set")
|
||||
|
||||
goPathFound := false
|
||||
|
||||
for _, v := range os.Environ() {
|
||||
if strings.HasPrefix(v, "GOPATH=") {
|
||||
goPathFound = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !goPathFound {
|
||||
log.Fatal("GOPATH is not set")
|
||||
}
|
||||
|
||||
createTemporaryDirectory()
|
||||
createPNPMDirectory()
|
||||
|
||||
bootstrapPrintln("Preparing /etc/hosts to serve subdomains of example.com...")
|
||||
prepareHostsFile()
|
||||
|
||||
fmt.Println()
|
||||
bootstrapPrintln("Run 'authelia-scripts suites setup Standalone' to start Authelia and visit https://home.example.com:8080.")
|
||||
bootstrapPrintln("More details at https://github.com/authelia/authelia/blob/master/docs/getting-started.md")
|
||||
}
|
||||
|
||||
var hostEntries = []HostEntry{
|
||||
|
@ -78,9 +121,8 @@ func runCommand(cmd string, args ...string) {
|
|||
func checkCommandExist(cmd string, resolutionHint string) {
|
||||
fmt.Print("Checking if '" + cmd + "' command is installed...")
|
||||
command := exec.Command("bash", "-c", "command -v "+cmd) //nolint:gosec // Used only in development.
|
||||
err := command.Run()
|
||||
|
||||
if err != nil {
|
||||
if command.Run() != nil {
|
||||
msg := "[ERROR] You must install " + cmd + " on your machine."
|
||||
if resolutionHint != "" {
|
||||
msg += fmt.Sprintf(" %s", resolutionHint)
|
||||
|
@ -214,40 +256,3 @@ func readVersions() {
|
|||
readVersion("docker", "--version")
|
||||
readVersion("docker-compose", "version")
|
||||
}
|
||||
|
||||
// Bootstrap bootstrap authelia dev environment.
|
||||
func Bootstrap(cobraCmd *cobra.Command, args []string) {
|
||||
bootstrapPrintln("Checking command installation...")
|
||||
checkCommandExist("node", "Follow installation guidelines from https://nodejs.org/en/download/package-manager/ or download installer from https://nodejs.org/en/download/")
|
||||
checkCommandExist("pnpm", "Follow installation guidelines from https://pnpm.io/installation")
|
||||
checkCommandExist("docker", "Follow installation guidelines from https://docs.docker.com/get-docker/")
|
||||
checkCommandExist("docker-compose", "Follow installation guidelines from https://docs.docker.com/compose/install/")
|
||||
|
||||
bootstrapPrintln("Getting versions of tools")
|
||||
readVersions()
|
||||
|
||||
bootstrapPrintln("Checking if GOPATH is set")
|
||||
|
||||
goPathFound := false
|
||||
|
||||
for _, v := range os.Environ() {
|
||||
if strings.HasPrefix(v, "GOPATH=") {
|
||||
goPathFound = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !goPathFound {
|
||||
log.Fatal("GOPATH is not set")
|
||||
}
|
||||
|
||||
createTemporaryDirectory()
|
||||
createPNPMDirectory()
|
||||
|
||||
bootstrapPrintln("Preparing /etc/hosts to serve subdomains of example.com...")
|
||||
prepareHostsFile()
|
||||
|
||||
fmt.Println()
|
||||
bootstrapPrintln("Run 'authelia-scripts suites setup Standalone' to start Authelia and visit https://home.example.com:8080.")
|
||||
bootstrapPrintln("More details at https://github.com/authelia/authelia/blob/master/docs/getting-started.md")
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package main
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
@ -12,56 +12,114 @@ import (
|
|||
"github.com/authelia/authelia/v4/internal/utils"
|
||||
)
|
||||
|
||||
func buildAutheliaBinary(xflags []string, buildkite bool) {
|
||||
func newBuildCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "build",
|
||||
Short: cmdBuildShort,
|
||||
Long: cmdBuildLong,
|
||||
Example: cmdBuildExample,
|
||||
Args: cobra.NoArgs,
|
||||
Run: cmdBuildRun,
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func cmdBuildRun(cobraCmd *cobra.Command, args []string) {
|
||||
branch := os.Getenv("BUILDKITE_BRANCH")
|
||||
|
||||
if strings.HasPrefix(branch, "renovate/") {
|
||||
buildFrontend(branch)
|
||||
log.Info("Skip building Authelia for deps...")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
log.Info("Building Authelia...")
|
||||
|
||||
cmdCleanRun(cobraCmd, args)
|
||||
|
||||
xflags, err := getXFlags(branch, os.Getenv("BUILDKITE_BUILD_NUMBER"), "")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Debug("Creating `" + OutputDir + "` directory")
|
||||
|
||||
if err = os.MkdirAll(OutputDir, os.ModePerm); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Debug("Building Authelia frontend...")
|
||||
buildFrontend(branch)
|
||||
|
||||
log.Debug("Building swagger-ui frontend...")
|
||||
buildSwagger()
|
||||
|
||||
buildkite, _ := cobraCmd.Flags().GetBool("buildkite")
|
||||
|
||||
if buildkite {
|
||||
var wg sync.WaitGroup
|
||||
log.Info("Building Authelia Go binaries with gox...")
|
||||
|
||||
s := time.Now()
|
||||
|
||||
wg.Add(2)
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
cmd := utils.CommandWithStdout("gox", "-output={{.Dir}}-{{.OS}}-{{.Arch}}-musl", "-buildmode=pie", "-trimpath", "-cgo", "-ldflags=-linkmode=external -s -w "+strings.Join(xflags, " "), "-osarch=linux/amd64 linux/arm linux/arm64", "./cmd/authelia/")
|
||||
|
||||
cmd.Env = append(os.Environ(),
|
||||
"CGO_CPPFLAGS=-D_FORTIFY_SOURCE=2 -fstack-protector-strong", "CGO_LDFLAGS=-Wl,-z,relro,-z,now",
|
||||
"GOX_LINUX_ARM_CC=arm-linux-musleabihf-gcc", "GOX_LINUX_ARM64_CC=aarch64-linux-musl-gcc")
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
cmd := utils.CommandWithStdout("bash", "-c", "docker run --rm -e GOX_LINUX_ARM_CC=arm-linux-gnueabihf-gcc -e GOX_LINUX_ARM64_CC=aarch64-linux-gnu-gcc -e GOX_FREEBSD_AMD64_CC=x86_64-pc-freebsd13-gcc -v ${PWD}:/workdir -v /buildkite/.go:/root/go authelia/crossbuild "+
|
||||
"gox -output={{.Dir}}-{{.OS}}-{{.Arch}} -buildmode=pie -trimpath -cgo -ldflags=\"-linkmode=external -s -w "+strings.Join(xflags, " ")+"\" -osarch=\"linux/amd64 linux/arm linux/arm64 freebsd/amd64\" ./cmd/authelia/")
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
|
||||
e := time.Since(s)
|
||||
|
||||
log.Debugf("Binary compilation completed in %s.", e)
|
||||
buildAutheliaBinaryGOX(xflags)
|
||||
} else {
|
||||
cmd := utils.CommandWithStdout("go", "build", "-buildmode=pie", "-trimpath", "-o", OutputDir+"/authelia", "-ldflags", "-linkmode=external -s -w "+strings.Join(xflags, " "), "./cmd/authelia/")
|
||||
log.Info("Building Authelia Go binary...")
|
||||
|
||||
buildAutheliaBinaryGO(xflags)
|
||||
}
|
||||
|
||||
cleanAssets()
|
||||
}
|
||||
|
||||
func buildAutheliaBinaryGOX(xflags []string) {
|
||||
var wg sync.WaitGroup
|
||||
|
||||
s := time.Now()
|
||||
|
||||
wg.Add(2)
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
cmd := utils.CommandWithStdout("gox", "-output={{.Dir}}-{{.OS}}-{{.Arch}}-musl", "-buildmode=pie", "-trimpath", "-cgo", "-ldflags=-linkmode=external -s -w "+strings.Join(xflags, " "), "-osarch=linux/amd64 linux/arm linux/arm64", "./cmd/authelia/")
|
||||
|
||||
cmd.Env = append(os.Environ(),
|
||||
"CGO_CPPFLAGS=-D_FORTIFY_SOURCE=2 -fstack-protector-strong", "CGO_LDFLAGS=-Wl,-z,relro,-z,now")
|
||||
"CGO_CPPFLAGS=-D_FORTIFY_SOURCE=2 -fstack-protector-strong", "CGO_LDFLAGS=-Wl,-z,relro,-z,now",
|
||||
"GOX_LINUX_ARM_CC=arm-linux-musleabihf-gcc", "GOX_LINUX_ARM64_CC=aarch64-linux-musl-gcc")
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
cmd := utils.CommandWithStdout("bash", "-c", "docker run --rm -e GOX_LINUX_ARM_CC=arm-linux-gnueabihf-gcc -e GOX_LINUX_ARM64_CC=aarch64-linux-gnu-gcc -e GOX_FREEBSD_AMD64_CC=x86_64-pc-freebsd13-gcc -v ${PWD}:/workdir -v /buildkite/.go:/root/go authelia/crossbuild "+
|
||||
"gox -output={{.Dir}}-{{.OS}}-{{.Arch}} -buildmode=pie -trimpath -cgo -ldflags=\"-linkmode=external -s -w "+strings.Join(xflags, " ")+"\" -osarch=\"linux/amd64 linux/arm linux/arm64 freebsd/amd64\" ./cmd/authelia/")
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
|
||||
e := time.Since(s)
|
||||
|
||||
log.Debugf("Binary compilation completed in %s.", e)
|
||||
}
|
||||
|
||||
func buildAutheliaBinaryGO(xflags []string) {
|
||||
cmd := utils.CommandWithStdout("go", "build", "-buildmode=pie", "-trimpath", "-o", OutputDir+"/authelia", "-ldflags", "-linkmode=external -s -w "+strings.Join(xflags, " "), "./cmd/authelia/")
|
||||
|
||||
cmd.Env = append(os.Environ(),
|
||||
"CGO_CPPFLAGS=-D_FORTIFY_SOURCE=2 -fstack-protector-strong", "CGO_LDFLAGS=-Wl,-z,relro,-z,now")
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,47 +191,3 @@ func cleanAssets() {
|
|||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Build build Authelia.
|
||||
func Build(cobraCmd *cobra.Command, args []string) {
|
||||
buildkite, _ := cobraCmd.Flags().GetBool("buildkite")
|
||||
branch := os.Getenv("BUILDKITE_BRANCH")
|
||||
|
||||
if strings.HasPrefix(branch, "renovate/") {
|
||||
buildFrontend(branch)
|
||||
log.Info("Skip building Authelia for deps...")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
log.Info("Building Authelia...")
|
||||
|
||||
Clean(cobraCmd, args)
|
||||
|
||||
xflags, err := getXFlags(branch, os.Getenv("BUILDKITE_BUILD_NUMBER"), "")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Debug("Creating `" + OutputDir + "` directory")
|
||||
err = os.MkdirAll(OutputDir, os.ModePerm)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Debug("Building Authelia frontend...")
|
||||
buildFrontend(branch)
|
||||
|
||||
log.Debug("Building swagger-ui frontend...")
|
||||
buildSwagger()
|
||||
|
||||
if buildkite {
|
||||
log.Debug("Building Authelia Go binaries with gox...")
|
||||
} else {
|
||||
log.Debug("Building Authelia Go binary...")
|
||||
}
|
||||
|
||||
buildAutheliaBinary(xflags, buildkite)
|
||||
|
||||
cleanAssets()
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package main
|
||||
package cmd
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
@ -7,12 +7,23 @@ import (
|
|||
"github.com/authelia/authelia/v4/internal/utils"
|
||||
)
|
||||
|
||||
// RunCI run the CI scripts.
|
||||
func RunCI(cmd *cobra.Command, args []string) {
|
||||
func newCICmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "ci",
|
||||
Short: cmdCIShort,
|
||||
Long: cmdCILong,
|
||||
Example: cmdCIExample,
|
||||
Args: cobra.NoArgs,
|
||||
Run: cmdCIRun,
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func cmdCIRun(cmd *cobra.Command, _ []string) {
|
||||
log.Info("=====> Build stage <=====")
|
||||
|
||||
buildkite, _ := cmd.Flags().GetBool("buildkite")
|
||||
if buildkite {
|
||||
if buildkite, _ := cmd.Flags().GetBool("buildkite"); buildkite {
|
||||
if err := utils.CommandWithStdout("authelia-scripts", "--log-level", "debug", "--buildkite", "build").Run(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newCleanCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "clean",
|
||||
Short: cmdCleanShort,
|
||||
Long: cmdCleanLong,
|
||||
Example: cmdCleanExample,
|
||||
Args: cobra.NoArgs,
|
||||
Run: cmdCleanRun,
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func cmdCleanRun(_ *cobra.Command, _ []string) {
|
||||
log.Debug("Removing `" + OutputDir + "` directory")
|
||||
err := os.RemoveAll(OutputDir)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
package cmd
|
||||
|
||||
// OutputDir the output directory where the built version of Authelia is located.
|
||||
var OutputDir = "dist"
|
||||
|
||||
// DockerImageName the official name of Authelia docker image.
|
||||
var DockerImageName = "authelia/authelia"
|
||||
|
||||
// IntermediateDockerImageName local name of the docker image.
|
||||
var IntermediateDockerImageName = "authelia:dist"
|
||||
|
||||
const dockerhub = "docker.io"
|
||||
const ghcr = "ghcr.io"
|
||||
|
||||
const masterTag = "master"
|
||||
const stringFalse = "false"
|
||||
const webDirectory = "web"
|
||||
|
||||
const fmtLDFLAGSX = "-X 'github.com/authelia/authelia/v4/internal/utils.%s=%s'"
|
||||
|
||||
const (
|
||||
cmdRootShort = "A utility used in the Authelia development process."
|
||||
|
||||
cmdRootLong = `The authelia-scripts utility is utilized by developers and the CI/CD pipeline for configuring
|
||||
testing suites and various other aspects of the environment.
|
||||
|
||||
It can be used to automate or manually run unit testing, integration testing, etc.`
|
||||
|
||||
cmdRootExample = `authelia-scripts help`
|
||||
|
||||
cmdBootstrapShort = "Prepare environment for development and testing"
|
||||
|
||||
cmdBootstrapLong = `Prepare environment for development and testing.`
|
||||
|
||||
cmdBootstrapExample = `authelia-scripts bootstrap`
|
||||
|
||||
cmdBuildShort = "Build Authelia binary and static assets"
|
||||
|
||||
cmdBuildLong = `Build Authelia binary and static assets.`
|
||||
|
||||
cmdBuildExample = `authelia-scripts build`
|
||||
|
||||
cmdCleanShort = "Clean build artifacts"
|
||||
|
||||
cmdCleanLong = `Clean build artifacts.`
|
||||
|
||||
cmdCleanExample = `authelia-scripts clean`
|
||||
|
||||
cmdCIShort = "Run the continuous integration script"
|
||||
|
||||
cmdCILong = `Run the continuous integration script.`
|
||||
|
||||
cmdCIExample = `authelia-scripts ci`
|
||||
|
||||
cmdDockerShort = "Commands related to building and publishing docker image"
|
||||
|
||||
cmdDockerLong = `Commands related to building and publishing docker image.`
|
||||
|
||||
cmdDockerExample = `authelia-scripts docker`
|
||||
|
||||
cmdDockerBuildShort = "Build the docker image of Authelia"
|
||||
|
||||
cmdDockerBuildLong = `Build the docker image of Authelia.`
|
||||
|
||||
cmdDockerBuildExample = `authelia-scripts docker build`
|
||||
|
||||
cmdDockerPushManifestShort = "Push Authelia docker manifest to the Docker registries"
|
||||
|
||||
cmdDockerPushManifestLong = `Push Authelia docker manifest to the Docker registries.`
|
||||
|
||||
cmdDockerPushManifestExample = `authelia-scripts docker push-manifest`
|
||||
|
||||
cmdServeShort = "Serve compiled version of Authelia"
|
||||
|
||||
cmdServeLong = `Serve compiled version of Authelia.`
|
||||
|
||||
cmdServeExample = `authelia-scripts serve test.yml`
|
||||
|
||||
cmdSuitesShort = "Commands related to suites management"
|
||||
|
||||
cmdSuitesLong = `Commands related to suites management.`
|
||||
|
||||
cmdSuitesExample = `authelia-scripts suites`
|
||||
|
||||
cmdSuitesListShort = "List available suites"
|
||||
|
||||
cmdSuitesListLong = `List available suites.
|
||||
|
||||
Suites can be ran with the authelia-scripts suites test [suite] command.`
|
||||
|
||||
cmdSuitesListExample = `authelia-scripts suites list`
|
||||
|
||||
cmdSuitesTestShort = "Run a test suite"
|
||||
|
||||
cmdSuitesTestLong = `Run a test suite.
|
||||
|
||||
Suites can be listed with the authelia-scripts suites list command.`
|
||||
|
||||
cmdSuitesTestExample = `authelia-scripts suites test Standalone`
|
||||
|
||||
cmdSuitesSetupShort = "Setup a test suite environment"
|
||||
|
||||
cmdSuitesSetupLong = `Setup a test suite environment.
|
||||
|
||||
Suites can be listed with the authelia-scripts suites list command.`
|
||||
|
||||
cmdSuitesSetupExample = `authelia-scripts suites setup Standalone`
|
||||
|
||||
cmdSuitesTeardownShort = "Teardown a test suite environment"
|
||||
|
||||
cmdSuitesTeardownLong = `Teardown a test suite environment.
|
||||
|
||||
Suites can be listed with the authelia-scripts suites list command.`
|
||||
|
||||
cmdSuitesTeardownExample = `authelia-scripts suites setup Standalone`
|
||||
|
||||
cmdUnitTestShort = "Run unit tests"
|
||||
|
||||
cmdUnitTestLong = `Run unit tests.`
|
||||
|
||||
cmdUnitTestExample = `authelia-scripts unittest`
|
||||
|
||||
cmdXFlagsShort = "Generate X LDFlags for building Authelia"
|
||||
|
||||
cmdXFlagsLong = `Generate X LDFlags for building Authelia.`
|
||||
|
||||
cmdXFlagsExample = `authelia-scripts xflags`
|
||||
)
|
|
@ -1,4 +1,4 @@
|
|||
package main
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
@ -23,8 +23,103 @@ var ignoredSuffixes = regexp.MustCompile("alpha|beta")
|
|||
var publicRepo = regexp.MustCompile(`.*:.*`)
|
||||
var tags = dockerTags.FindStringSubmatch(ciTag)
|
||||
|
||||
func init() {
|
||||
DockerBuildCmd.PersistentFlags().StringVar(&container, "container", defaultContainer, "target container among: "+strings.Join(containers, ", "))
|
||||
func newDockerCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "docker",
|
||||
Short: cmdDockerShort,
|
||||
Long: cmdDockerLong,
|
||||
Example: cmdDockerExample,
|
||||
Args: cobra.NoArgs,
|
||||
Run: cmdDockerBuildRun,
|
||||
}
|
||||
|
||||
cmd.AddCommand(newDockerBuildCmd(), newDockerPushManifestCmd())
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newDockerBuildCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "build",
|
||||
Short: cmdDockerBuildShort,
|
||||
Long: cmdDockerBuildLong,
|
||||
Example: cmdDockerBuildExample,
|
||||
Args: cobra.NoArgs,
|
||||
Run: cmdDockerBuildRun,
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().StringVar(&container, "container", defaultContainer, "target container among: "+strings.Join(containers, ", "))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newDockerPushManifestCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "push-manifest",
|
||||
Short: cmdDockerPushManifestShort,
|
||||
Long: cmdDockerPushManifestLong,
|
||||
Example: cmdDockerPushManifestExample,
|
||||
Args: cobra.NoArgs,
|
||||
Run: cmdDockerPushManifestRun,
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func cmdDockerBuildRun(_ *cobra.Command, _ []string) {
|
||||
log.Infof("Building Docker image %s...", DockerImageName)
|
||||
checkContainerIsSupported(container)
|
||||
err := dockerBuildOfficialImage(container)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
docker := &Docker{}
|
||||
err = docker.Tag(IntermediateDockerImageName, DockerImageName)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func cmdDockerPushManifestRun(_ *cobra.Command, _ []string) {
|
||||
docker := &Docker{}
|
||||
|
||||
switch {
|
||||
case ciTag != "":
|
||||
if len(tags) == 4 {
|
||||
log.Infof("Detected tags: '%s' | '%s' | '%s'", tags[1], tags[2], tags[3])
|
||||
login(docker, dockerhub)
|
||||
login(docker, ghcr)
|
||||
deployManifest(docker, tags[1])
|
||||
publishDockerReadme(docker)
|
||||
|
||||
if !ignoredSuffixes.MatchString(ciTag) {
|
||||
deployManifest(docker, tags[2])
|
||||
deployManifest(docker, tags[3])
|
||||
deployManifest(docker, "latest")
|
||||
publishDockerReadme(docker)
|
||||
}
|
||||
} else {
|
||||
log.Fatal("Docker manifest will not be published, the specified tag does not conform to the standard")
|
||||
}
|
||||
case ciBranch != masterTag && !publicRepo.MatchString(ciBranch):
|
||||
login(docker, dockerhub)
|
||||
login(docker, ghcr)
|
||||
deployManifest(docker, ciBranch)
|
||||
case ciBranch != masterTag && publicRepo.MatchString(ciBranch):
|
||||
login(docker, dockerhub)
|
||||
login(docker, ghcr)
|
||||
deployManifest(docker, "PR"+ciPullRequest)
|
||||
case ciBranch == masterTag && ciPullRequest == stringFalse:
|
||||
login(docker, dockerhub)
|
||||
login(docker, ghcr)
|
||||
deployManifest(docker, "master")
|
||||
publishDockerReadme(docker)
|
||||
default:
|
||||
log.Info("Docker manifest will not be published")
|
||||
}
|
||||
}
|
||||
|
||||
func checkContainerIsSupported(container string) {
|
||||
|
@ -51,37 +146,6 @@ func dockerBuildOfficialImage(arch string) error {
|
|||
strings.Join(flags, " "))
|
||||
}
|
||||
|
||||
// DockerBuildCmd Command for building docker image of Authelia.
|
||||
var DockerBuildCmd = &cobra.Command{
|
||||
Use: "build",
|
||||
Short: "Build the docker image of Authelia",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
log.Infof("Building Docker image %s...", DockerImageName)
|
||||
checkContainerIsSupported(container)
|
||||
err := dockerBuildOfficialImage(container)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
docker := &Docker{}
|
||||
err = docker.Tag(IntermediateDockerImageName, DockerImageName)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// DockerManifestCmd Command for pushing Authelia docker manifest to DockerHub.
|
||||
var DockerManifestCmd = &cobra.Command{
|
||||
Use: "push-manifest",
|
||||
Short: "Publish Authelia docker manifest to Docker Hub",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
publishDockerManifest()
|
||||
},
|
||||
}
|
||||
|
||||
func login(docker *Docker, registry string) {
|
||||
username := ""
|
||||
password := ""
|
||||
|
@ -122,45 +186,6 @@ func deployManifest(docker *Docker, tag string) {
|
|||
}
|
||||
}
|
||||
|
||||
func publishDockerManifest() {
|
||||
docker := &Docker{}
|
||||
|
||||
switch {
|
||||
case ciTag != "":
|
||||
if len(tags) == 4 {
|
||||
log.Infof("Detected tags: '%s' | '%s' | '%s'", tags[1], tags[2], tags[3])
|
||||
login(docker, dockerhub)
|
||||
login(docker, ghcr)
|
||||
deployManifest(docker, tags[1])
|
||||
publishDockerReadme(docker)
|
||||
|
||||
if !ignoredSuffixes.MatchString(ciTag) {
|
||||
deployManifest(docker, tags[2])
|
||||
deployManifest(docker, tags[3])
|
||||
deployManifest(docker, "latest")
|
||||
publishDockerReadme(docker)
|
||||
}
|
||||
} else {
|
||||
log.Fatal("Docker manifest will not be published, the specified tag does not conform to the standard")
|
||||
}
|
||||
case ciBranch != masterTag && !publicRepo.MatchString(ciBranch):
|
||||
login(docker, dockerhub)
|
||||
login(docker, ghcr)
|
||||
deployManifest(docker, ciBranch)
|
||||
case ciBranch != masterTag && publicRepo.MatchString(ciBranch):
|
||||
login(docker, dockerhub)
|
||||
login(docker, ghcr)
|
||||
deployManifest(docker, "PR"+ciPullRequest)
|
||||
case ciBranch == masterTag && ciPullRequest == stringFalse:
|
||||
login(docker, dockerhub)
|
||||
login(docker, ghcr)
|
||||
deployManifest(docker, "master")
|
||||
publishDockerReadme(docker)
|
||||
default:
|
||||
log.Info("Docker manifest will not be published")
|
||||
}
|
||||
}
|
||||
|
||||
func publishDockerReadme(docker *Docker) {
|
||||
log.Info("Docker pushing README.md to Docker Hub")
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
// ErrNotAvailableSuite error raised when suite is not available.
|
||||
var ErrNotAvailableSuite = errors.New("unavailable suite")
|
||||
|
||||
// ErrNoRunningSuite error raised when no suite is running.
|
||||
var ErrNoRunningSuite = errors.New("no running suite")
|
|
@ -1,4 +1,4 @@
|
|||
package main
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
|
@ -1,4 +1,4 @@
|
|||
package main
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/authelia/authelia/v4/internal/utils"
|
|
@ -0,0 +1,17 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var logLevel string
|
||||
|
||||
func levelStringToLevel(level string) log.Level {
|
||||
if level == "debug" {
|
||||
return log.DebugLevel
|
||||
} else if level == "warning" {
|
||||
return log.WarnLevel
|
||||
}
|
||||
|
||||
return log.InfoLevel
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// NewRootCmd returns the root authelia-scripts cmd.
|
||||
func NewRootCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "authelia-scripts",
|
||||
Short: cmdRootShort,
|
||||
Long: cmdRootLong,
|
||||
Example: cmdRootExample,
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().Bool("buildkite", false, "Set CI flag for Buildkite")
|
||||
cmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "Set the log level for the command")
|
||||
|
||||
cmd.AddCommand(newBootstrapCmd(), newBuildCmd(), newCleanCmd(), newCICmd(), newDockerCmd(), newServeCmd(), newSuitesCmd(), newUnitTestCmd(), newXFlagsCmd())
|
||||
|
||||
cobra.OnInitialize(cmdRootInit)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func cmdRootInit() {
|
||||
log.SetLevel(levelStringToLevel(logLevel))
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/authelia/authelia/v4/internal/utils"
|
||||
)
|
||||
|
||||
func newServeCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "serve [config]",
|
||||
Short: cmdServeShort,
|
||||
Long: cmdServeLong,
|
||||
Example: cmdServeExample,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Run: cmdServeRun,
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func cmdServeRun(_ *cobra.Command, args []string) {
|
||||
log.Infof("Running Authelia with config %s...", args[0])
|
||||
execCmd := utils.CommandWithStdout(OutputDir+"/authelia", "--config", args[0])
|
||||
utils.RunCommandUntilCtrlC(execCmd)
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package main
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
@ -17,92 +17,156 @@ import (
|
|||
"github.com/authelia/authelia/v4/internal/utils"
|
||||
)
|
||||
|
||||
// ErrNotAvailableSuite error raised when suite is not available.
|
||||
var ErrNotAvailableSuite = errors.New("unavailable suite")
|
||||
var (
|
||||
runningSuiteFile = ".suite"
|
||||
failfast, headless bool
|
||||
testPattern string
|
||||
)
|
||||
|
||||
// ErrNoRunningSuite error raised when no suite is running.
|
||||
var ErrNoRunningSuite = errors.New("no running suite")
|
||||
func newSuitesCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "suites",
|
||||
Short: cmdSuitesShort,
|
||||
Long: cmdSuitesLong,
|
||||
Example: cmdSuitesExample,
|
||||
Run: cmdSuitesListRun,
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
|
||||
// runningSuiteFile name of the file containing the currently running suite.
|
||||
var runningSuiteFile = ".suite"
|
||||
cmd.AddCommand(newSuitesListCmd(), newSuitesSetupCmd(), newSuitesTestCmd(), newSuitesTeardownCmd())
|
||||
|
||||
var failfast bool
|
||||
var headless bool
|
||||
var testPattern string
|
||||
|
||||
func init() {
|
||||
SuitesTestCmd.Flags().BoolVar(&failfast, "failfast", false, "Stops tests on first failure")
|
||||
SuitesTestCmd.Flags().BoolVar(&headless, "headless", false, "Run tests in headless mode")
|
||||
SuitesTestCmd.Flags().StringVar(&testPattern, "test", "", "The single test to run")
|
||||
return cmd
|
||||
}
|
||||
|
||||
// SuitesListCmd Command for listing the available suites.
|
||||
var SuitesListCmd = &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List available suites.",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println(strings.Join(listSuites(), "\n"))
|
||||
},
|
||||
Args: cobra.ExactArgs(0),
|
||||
func newSuitesListCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "list",
|
||||
Short: cmdSuitesListShort,
|
||||
Long: cmdSuitesListLong,
|
||||
Example: cmdSuitesListExample,
|
||||
Run: cmdSuitesListRun,
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// SuitesSetupCmd Command to setup a suite environment.
|
||||
var SuitesSetupCmd = &cobra.Command{
|
||||
Use: "setup [suite]",
|
||||
Short: "Setup a Go suite environment. Suites can be listed using the list command.",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
providedSuite := args[0]
|
||||
func newSuitesSetupCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "setup [suite]",
|
||||
Short: cmdSuitesSetupShort,
|
||||
Long: cmdSuitesSetupLong,
|
||||
Example: cmdSuitesSetupExample,
|
||||
Run: cmdSuitesSetupRun,
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newSuitesTeardownCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "teardown [suite]",
|
||||
Short: cmdSuitesTeardownShort,
|
||||
Long: cmdSuitesTeardownLong,
|
||||
Example: cmdSuitesTeardownExample,
|
||||
Run: cmdSuitesTeardownRun,
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newSuitesTestCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "test [suite]",
|
||||
Short: cmdSuitesTestShort,
|
||||
Long: cmdSuitesTestLong,
|
||||
Example: cmdSuitesTestExample,
|
||||
Run: cmdSuitesTestRun,
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
}
|
||||
|
||||
cmd.Flags().BoolVar(&failfast, "failfast", false, "Stops tests on first failure")
|
||||
cmd.Flags().BoolVar(&headless, "headless", false, "Run tests in headless mode")
|
||||
cmd.Flags().StringVar(&testPattern, "test", "", "The single test to run")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func cmdSuitesListRun(_ *cobra.Command, _ []string) {
|
||||
fmt.Println(strings.Join(listSuites(), "\n"))
|
||||
}
|
||||
|
||||
func cmdSuitesSetupRun(_ *cobra.Command, args []string) {
|
||||
providedSuite := args[0]
|
||||
runningSuite, err := getRunningSuite()
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if runningSuite != "" && runningSuite != providedSuite {
|
||||
log.Fatal("A suite is already running")
|
||||
}
|
||||
|
||||
if err := setupSuite(providedSuite); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func cmdSuitesTeardownRun(_ *cobra.Command, args []string) {
|
||||
var suiteName string
|
||||
if len(args) == 1 {
|
||||
suiteName = args[0]
|
||||
} else {
|
||||
runningSuite, err := getRunningSuite()
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if runningSuite != "" && runningSuite != providedSuite {
|
||||
log.Fatal("A suite is already running")
|
||||
if runningSuite == "" {
|
||||
log.Fatal(ErrNoRunningSuite)
|
||||
}
|
||||
suiteName = runningSuite
|
||||
}
|
||||
|
||||
if err := setupSuite(providedSuite); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
},
|
||||
Args: cobra.ExactArgs(1),
|
||||
if err := teardownSuite(suiteName); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// SuitesTeardownCmd Command for tearing down a suite environment.
|
||||
var SuitesTeardownCmd = &cobra.Command{
|
||||
Use: "teardown [suite]",
|
||||
Short: "Teardown a Go suite environment. Suites can be listed using the list command.",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
var suiteName string
|
||||
if len(args) == 1 {
|
||||
suiteName = args[0]
|
||||
} else {
|
||||
runningSuite, err := getRunningSuite()
|
||||
func cmdSuitesTestRun(_ *cobra.Command, args []string) {
|
||||
runningSuite, err := getRunningSuite()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
// If suite(s) are provided as argument.
|
||||
if len(args) >= 1 {
|
||||
suiteArg := args[0]
|
||||
|
||||
if runningSuite != "" && suiteArg != runningSuite {
|
||||
log.Fatal(errors.New("Running suite (" + runningSuite + ") is different than suite(s) to be tested (" + suiteArg + "). Shutdown running suite and retry"))
|
||||
}
|
||||
|
||||
if err := runMultipleSuitesTests(strings.Split(suiteArg, ","), runningSuite == ""); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
} else {
|
||||
if runningSuite != "" {
|
||||
fmt.Println("Running suite (" + runningSuite + ") detected. Run tests of that suite")
|
||||
if err := runSuiteTests(runningSuite, false); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if runningSuite == "" {
|
||||
log.Fatal(ErrNoRunningSuite)
|
||||
} else {
|
||||
fmt.Println("No suite provided therefore all suites will be tested")
|
||||
if err := runAllSuites(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
suiteName = runningSuite
|
||||
}
|
||||
|
||||
if err := teardownSuite(suiteName); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
},
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
}
|
||||
|
||||
// SuitesTestCmd Command for testing a suite.
|
||||
var SuitesTestCmd = &cobra.Command{
|
||||
Use: "test [suite]",
|
||||
Short: "Test a suite. Suites can be listed using the list command.",
|
||||
Run: testSuite,
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
}
|
||||
}
|
||||
|
||||
func listSuites() []string {
|
||||
|
@ -114,9 +178,9 @@ func listSuites() []string {
|
|||
}
|
||||
|
||||
func checkSuiteAvailable(suite string) error {
|
||||
suites := listSuites()
|
||||
suiteNames := listSuites()
|
||||
|
||||
for _, s := range suites {
|
||||
for _, s := range suiteNames {
|
||||
if s == suite {
|
||||
return nil
|
||||
}
|
||||
|
@ -218,38 +282,6 @@ func teardownSuite(suiteName string) error {
|
|||
return runSuiteSetupTeardown("teardown", suiteName)
|
||||
}
|
||||
|
||||
func testSuite(cmd *cobra.Command, args []string) {
|
||||
runningSuite, err := getRunningSuite()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// If suite(s) are provided as argument.
|
||||
if len(args) >= 1 {
|
||||
suiteArg := args[0]
|
||||
|
||||
if runningSuite != "" && suiteArg != runningSuite {
|
||||
log.Fatal(errors.New("Running suite (" + runningSuite + ") is different than suite(s) to be tested (" + suiteArg + "). Shutdown running suite and retry"))
|
||||
}
|
||||
|
||||
if err := runMultipleSuitesTests(strings.Split(suiteArg, ","), runningSuite == ""); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
} else {
|
||||
if runningSuite != "" {
|
||||
fmt.Println("Running suite (" + runningSuite + ") detected. Run tests of that suite")
|
||||
if err := runSuiteTests(runningSuite, false); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
} else {
|
||||
fmt.Println("No suite provided therefore all suites will be tested")
|
||||
if err := runAllSuites(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getRunningSuite() (string, error) {
|
||||
exist, err := utils.FileExists(runningSuiteFile)
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package cmd
|
||||
|
||||
// HostEntry represents an entry in /etc/hosts.
|
||||
type HostEntry struct {
|
||||
Domain string
|
||||
IP string
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package main
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
@ -9,8 +9,20 @@ import (
|
|||
"github.com/authelia/authelia/v4/internal/utils"
|
||||
)
|
||||
|
||||
// RunUnitTest run the unit tests.
|
||||
func RunUnitTest(cobraCmd *cobra.Command, args []string) {
|
||||
func newUnitTestCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "unittest",
|
||||
Short: cmdUnitTestShort,
|
||||
Long: cmdUnitTestLong,
|
||||
Example: cmdUnitTestExample,
|
||||
Args: cobra.NoArgs,
|
||||
Run: cmdUnitTestRun,
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func cmdUnitTestRun(_ *cobra.Command, _ []string) {
|
||||
log.SetLevel(log.TraceLevel)
|
||||
|
||||
if err := utils.Shell("go test -coverprofile=coverage.txt -covermode=atomic $(go list ./... | grep -v suites)").Run(); err != nil {
|
|
@ -0,0 +1,44 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newXFlagsCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "xflags",
|
||||
Short: cmdXFlagsShort,
|
||||
Long: cmdXFlagsLong,
|
||||
Example: cmdXFlagsExample,
|
||||
Args: cobra.NoArgs,
|
||||
Run: cmdXFlagsRun,
|
||||
}
|
||||
|
||||
cmd.Flags().StringP("build", "b", "0", "Sets the BuildNumber flag value")
|
||||
cmd.Flags().StringP("extra", "e", "", "Sets the BuildExtra flag value")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func cmdXFlagsRun(cobraCmd *cobra.Command, _ []string) {
|
||||
build, err := cobraCmd.Flags().GetString("build")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
extra, err := cobraCmd.Flags().GetString("extra")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
flags, err := getXFlags("", build, extra)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println(strings.Join(flags, " "))
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// Clean artifacts built and installed by authelia-scripts.
|
||||
func Clean(cobraCmd *cobra.Command, args []string) {
|
||||
log.Debug("Removing `" + OutputDir + "` directory")
|
||||
err := os.RemoveAll(OutputDir)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/authelia/authelia/v4/internal/utils"
|
||||
)
|
||||
|
||||
// ServeCmd serve Authelia with the provided configuration.
|
||||
func ServeCmd(cmd *cobra.Command, args []string) {
|
||||
log.Infof("Running Authelia with config %s...", args[0])
|
||||
execCmd := utils.CommandWithStdout(OutputDir+"/authelia", "--config", args[0])
|
||||
utils.RunCommandUntilCtrlC(execCmd)
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func init() {
|
||||
xflagsCmd.Flags().StringP("build", "b", "0", "Sets the BuildNumber flag value")
|
||||
xflagsCmd.Flags().StringP("extra", "e", "", "Sets the BuildExtra flag value")
|
||||
}
|
||||
|
||||
var xflagsCmd = &cobra.Command{
|
||||
Use: "xflags",
|
||||
Run: runXFlags,
|
||||
Short: "Generate X LDFlags for building Authelia",
|
||||
}
|
||||
|
||||
func runXFlags(cobraCmd *cobra.Command, _ []string) {
|
||||
build, err := cobraCmd.Flags().GetString("build")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
extra, err := cobraCmd.Flags().GetString("extra")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
flags, err := getXFlags("", build, extra)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println(strings.Join(flags, " "))
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package main
|
||||
|
||||
// OutputDir the output directory where the built version of Authelia is located.
|
||||
var OutputDir = "dist"
|
||||
|
||||
// DockerImageName the official name of Authelia docker image.
|
||||
var DockerImageName = "authelia/authelia"
|
||||
|
||||
// IntermediateDockerImageName local name of the docker image.
|
||||
var IntermediateDockerImageName = "authelia:dist"
|
||||
|
||||
const dockerhub = "docker.io"
|
||||
const ghcr = "ghcr.io"
|
||||
|
||||
const masterTag = "master"
|
||||
const stringFalse = "false"
|
||||
const webDirectory = "web"
|
||||
|
||||
const fmtLDFLAGSX = "-X 'github.com/authelia/authelia/v4/internal/utils.%s=%s'"
|
|
@ -5,151 +5,12 @@ package main
|
|||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/authelia/authelia/v4/internal/commands"
|
||||
"github.com/authelia/authelia/v4/internal/utils"
|
||||
"github.com/authelia/authelia/v4/cmd/authelia-scripts/cmd"
|
||||
)
|
||||
|
||||
var buildkite bool
|
||||
var logLevel string
|
||||
|
||||
// AutheliaCommandDefinition is the definition of one authelia-scripts command.
|
||||
type AutheliaCommandDefinition struct {
|
||||
Name string
|
||||
Short string
|
||||
Long string
|
||||
CommandLine string
|
||||
Args cobra.PositionalArgs
|
||||
Func func(cmd *cobra.Command, args []string)
|
||||
SubCommands []*cobra.Command
|
||||
}
|
||||
|
||||
// CobraCommands list of cobra commands.
|
||||
type CobraCommands = []*cobra.Command
|
||||
|
||||
// Commands is the list of commands of authelia-scripts.
|
||||
var Commands = []AutheliaCommandDefinition{
|
||||
{
|
||||
Name: "bootstrap",
|
||||
Short: "Prepare environment for development and testing.",
|
||||
Long: `Prepare environment for development and testing. This command prepares docker
|
||||
images and download tools like Kind for Kubernetes testing.`,
|
||||
Func: Bootstrap,
|
||||
},
|
||||
{
|
||||
Name: "build",
|
||||
Short: "Build Authelia binary and static assets",
|
||||
Func: Build,
|
||||
},
|
||||
{
|
||||
Name: "clean",
|
||||
Short: "Clean build artifacts",
|
||||
Func: Clean,
|
||||
},
|
||||
{
|
||||
Name: "docker",
|
||||
Short: "Commands related to building and publishing docker image",
|
||||
SubCommands: CobraCommands{DockerBuildCmd, DockerManifestCmd},
|
||||
},
|
||||
{
|
||||
Name: "serve [config]",
|
||||
Short: "Serve compiled version of Authelia",
|
||||
Func: ServeCmd,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
},
|
||||
{
|
||||
Name: "suites",
|
||||
Short: "Commands related to suites management",
|
||||
SubCommands: CobraCommands{
|
||||
SuitesTestCmd,
|
||||
SuitesListCmd,
|
||||
SuitesSetupCmd,
|
||||
SuitesTeardownCmd,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ci",
|
||||
Short: "Run continuous integration script",
|
||||
Func: RunCI,
|
||||
},
|
||||
{
|
||||
Name: "unittest",
|
||||
Short: "Run unit tests",
|
||||
Func: RunUnitTest,
|
||||
},
|
||||
}
|
||||
|
||||
func levelStringToLevel(level string) log.Level {
|
||||
if level == "debug" {
|
||||
return log.DebugLevel
|
||||
} else if level == "warning" {
|
||||
return log.WarnLevel
|
||||
}
|
||||
|
||||
return log.InfoLevel
|
||||
}
|
||||
|
||||
func main() {
|
||||
var rootCmd = &cobra.Command{Use: "authelia-scripts"}
|
||||
|
||||
cobraCommands := make([]*cobra.Command, 0)
|
||||
|
||||
for _, autheliaCommand := range Commands {
|
||||
var fn func(cobraCmd *cobra.Command, args []string)
|
||||
|
||||
if autheliaCommand.CommandLine != "" {
|
||||
cmdline := autheliaCommand.CommandLine
|
||||
fn = func(cobraCmd *cobra.Command, args []string) {
|
||||
cmd := utils.CommandWithStdout(cmdline, args...)
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
} else if autheliaCommand.Func != nil {
|
||||
fn = autheliaCommand.Func
|
||||
}
|
||||
|
||||
command := &cobra.Command{
|
||||
Use: autheliaCommand.Name,
|
||||
Short: autheliaCommand.Short,
|
||||
}
|
||||
|
||||
if autheliaCommand.Long != "" {
|
||||
command.Long = autheliaCommand.Long
|
||||
}
|
||||
|
||||
if fn != nil {
|
||||
command.Run = fn
|
||||
}
|
||||
|
||||
if autheliaCommand.Args != nil {
|
||||
command.Args = autheliaCommand.Args
|
||||
}
|
||||
|
||||
if autheliaCommand.SubCommands != nil {
|
||||
command.AddCommand(autheliaCommand.SubCommands...)
|
||||
}
|
||||
|
||||
cobraCommands = append(cobraCommands, command)
|
||||
}
|
||||
|
||||
cobraCommands = append(cobraCommands, commands.NewHashPasswordCmd(), commands.NewCertificatesCmd(), commands.NewRSACmd(), NewRunGenCmd(), xflagsCmd)
|
||||
|
||||
rootCmd.PersistentFlags().BoolVar(&buildkite, "buildkite", false, "Set CI flag for Buildkite")
|
||||
rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "Set the log level for the command")
|
||||
rootCmd.AddCommand(cobraCommands...)
|
||||
cobra.OnInitialize(initConfig)
|
||||
|
||||
err := rootCmd.Execute()
|
||||
|
||||
if err != nil {
|
||||
if err := cmd.NewRootCmd().Execute(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func initConfig() {
|
||||
log.SetLevel(levelStringToLevel(logLevel))
|
||||
}
|
||||
|
|
2
go.mod
2
go.mod
|
@ -46,6 +46,7 @@ require (
|
|||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dgraph-io/ristretto v0.1.0 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
|
@ -87,6 +88,7 @@ require (
|
|||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.32.1 // indirect
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/savsgio/dictpool v0.0.0-20220406081701-03de5edb2e6d // indirect
|
||||
github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d // indirect
|
||||
github.com/spf13/afero v1.6.0 // indirect
|
||||
|
|
4
go.sum
4
go.sum
|
@ -158,9 +158,11 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
|
|||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
|
@ -1185,8 +1187,10 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
|||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
github.com/rubenv/sql-migrate v0.0.0-20190212093014-1007f53448d7/go.mod h1:WS0rl9eEliYI8DPnr3TOwz4439pay+qNgzJoVya/DmY=
|
||||
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
|
|
|
@ -17,8 +17,10 @@ import (
|
|||
|
||||
func newAccessControlCommand() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "access-control",
|
||||
Short: "Helpers for the access control system",
|
||||
Use: "access-control",
|
||||
Short: cmdAutheliaAccessControlShort,
|
||||
Long: cmdAutheliaAccessControlLong,
|
||||
Example: cmdAutheliaAccessControlExample,
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
|
@ -30,13 +32,14 @@ func newAccessControlCommand() (cmd *cobra.Command) {
|
|||
|
||||
func newAccessControlCheckCommand() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "check-policy",
|
||||
Short: "Checks a request against the access control rules to determine what policy would be applied",
|
||||
Long: accessControlPolicyCheckLong,
|
||||
RunE: accessControlCheckRunE,
|
||||
Use: "check-policy",
|
||||
Short: cmdAutheliaAccessControlCheckPolicyShort,
|
||||
Long: cmdAutheliaAccessControlCheckPolicyLong,
|
||||
Example: cmdAutheliaAccessControlCheckPolicyExample,
|
||||
RunE: accessControlCheckRunE,
|
||||
}
|
||||
|
||||
cmdWithConfigFlags(cmd, false, []string{"config.yml"})
|
||||
cmdWithConfigFlags(cmd, false, []string{"configuration.yml"})
|
||||
|
||||
cmd.Flags().String("url", "", "the url of the object")
|
||||
cmd.Flags().String("method", "GET", "the HTTP method of the object")
|
||||
|
|
|
@ -11,11 +11,12 @@ import (
|
|||
|
||||
func newBuildInfoCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "build-info",
|
||||
Short: "Show the build information of Authelia",
|
||||
Long: buildLong,
|
||||
RunE: cmdBuildInfoRunE,
|
||||
Args: cobra.NoArgs,
|
||||
Use: "build-info",
|
||||
Short: cmdAutheliaBuildInfoShort,
|
||||
Long: cmdAutheliaBuildInfoLong,
|
||||
Example: cmdAutheliaBuildInfoExample,
|
||||
RunE: cmdBuildInfoRunE,
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
|
|
@ -13,12 +13,13 @@ import (
|
|||
"github.com/authelia/authelia/v4/internal/utils"
|
||||
)
|
||||
|
||||
// NewCertificatesCmd returns a new Certificates Cmd.
|
||||
func NewCertificatesCmd() (cmd *cobra.Command) {
|
||||
func newCertificatesCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "certificates",
|
||||
Short: "Commands related to certificate generation",
|
||||
Args: cobra.NoArgs,
|
||||
Use: "certificates",
|
||||
Short: cmdAutheliaCertificatesShort,
|
||||
Long: cmdAutheliaCertificatesLong,
|
||||
Example: cmdAutheliaCertificatesExample,
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().StringSlice("host", []string{}, "Comma-separated hostnames and IPs to generate a certificate for")
|
||||
|
@ -35,10 +36,12 @@ func NewCertificatesCmd() (cmd *cobra.Command) {
|
|||
|
||||
func newCertificatesGenerateCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "generate",
|
||||
Short: "Generate a self-signed certificate",
|
||||
Args: cobra.NoArgs,
|
||||
Run: cmdCertificatesGenerateRun,
|
||||
Use: "generate",
|
||||
Short: cmdAutheliaCertificatesGenerateShort,
|
||||
Long: cmdAutheliaCertificatesGenerateLong,
|
||||
Example: cmdAutheliaCertificatesGenerateExample,
|
||||
Args: cobra.NoArgs,
|
||||
Run: cmdCertificatesGenerateRun,
|
||||
}
|
||||
|
||||
cmd.Flags().String("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011")
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newCompletionCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "completion [bash|zsh|fish|powershell]",
|
||||
Short: "Generate completion script",
|
||||
Long: completionLong,
|
||||
Args: cobra.ExactValidArgs(1),
|
||||
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
|
||||
DisableFlagsInUseLine: true,
|
||||
Run: cmdCompletionRun,
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func cmdCompletionRun(cmd *cobra.Command, args []string) {
|
||||
var err error
|
||||
|
||||
switch args[0] {
|
||||
case "bash":
|
||||
err = cmd.Root().GenBashCompletion(os.Stdout)
|
||||
case "zsh":
|
||||
err = cmd.Root().GenZshCompletion(os.Stdout)
|
||||
case "fish":
|
||||
err = cmd.Root().GenFishCompletion(os.Stdout, true)
|
||||
case "powershell":
|
||||
err = cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)
|
||||
default:
|
||||
fmt.Printf("Invalid shell provided for completion command: %s\n", args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("Error generating completion: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
|
@ -4,21 +4,22 @@ import (
|
|||
"errors"
|
||||
)
|
||||
|
||||
const cmdAutheliaExample = `authelia --config /etc/authelia/config.yml --config /etc/authelia/access-control.yml
|
||||
authelia --config /etc/authelia/config.yml,/etc/authelia/access-control.yml
|
||||
authelia --config /etc/authelia/config/
|
||||
`
|
||||
const (
|
||||
fmtCmdAutheliaShort = "authelia %s"
|
||||
|
||||
const fmtAutheliaLong = `authelia %s
|
||||
fmtCmdAutheliaLong = `authelia %s
|
||||
|
||||
An open-source authentication and authorization server providing
|
||||
two-factor authentication and single sign-on (SSO) for your
|
||||
applications via a web portal.
|
||||
|
||||
Documentation is available at: https://www.authelia.com/docs
|
||||
`
|
||||
Documentation is available at: https://www.authelia.com/docs`
|
||||
|
||||
const fmtAutheliaBuild = `Last Tag: %s
|
||||
cmdAutheliaExample = `authelia --config /etc/authelia/config.yml --config /etc/authelia/access-control.yml
|
||||
authelia --config /etc/authelia/config.yml,/etc/authelia/access-control.yml
|
||||
authelia --config /etc/authelia/config/`
|
||||
|
||||
fmtAutheliaBuild = `Last Tag: %s
|
||||
State: %s
|
||||
Branch: %s
|
||||
Commit: %s
|
||||
|
@ -29,7 +30,9 @@ Build Date: %s
|
|||
Extra: %s
|
||||
`
|
||||
|
||||
const buildLong = `Show the build information of Authelia
|
||||
cmdAutheliaBuildInfoShort = "Show the build information of Authelia"
|
||||
|
||||
cmdAutheliaBuildInfoLong = `Show the build information of Authelia.
|
||||
|
||||
This outputs detailed version information about the specific version
|
||||
of the Authelia binary. This information is embedded into Authelia
|
||||
|
@ -39,48 +42,17 @@ This could be vital in debugging if you're not using a particular
|
|||
tagged build of Authelia. It's suggested to provide it along with
|
||||
your issue.
|
||||
`
|
||||
cmdAutheliaBuildInfoExample = `authelia build-info`
|
||||
|
||||
const completionLong = `To load completions:
|
||||
cmdAutheliaAccessControlShort = "Helpers for the access control system"
|
||||
|
||||
Bash:
|
||||
cmdAutheliaAccessControlLong = `Helpers for the access control system.`
|
||||
|
||||
$ source <(authelia completion bash)
|
||||
cmdAutheliaAccessControlExample = `authelia access-control --help`
|
||||
|
||||
# To load completions for each session, execute once:
|
||||
# Linux:
|
||||
$ authelia completion bash > /etc/bash_completion.d/authelia
|
||||
# macOS:
|
||||
$ authelia completion bash > /usr/local/etc/bash_completion.d/authelia
|
||||
cmdAutheliaAccessControlCheckPolicyShort = "Checks a request against the access control rules to determine what policy would be applied"
|
||||
|
||||
Zsh:
|
||||
|
||||
# If shell completion is not already enabled in your environment,
|
||||
# you will need to enable it. You can execute the following once:
|
||||
|
||||
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
|
||||
|
||||
# To load completions for each session, execute once:
|
||||
$ authelia completion zsh > "${fpath[1]}/_authelia"
|
||||
|
||||
# You will need to start a new shell for this setup to take effect.
|
||||
|
||||
fish:
|
||||
|
||||
$ authelia completion fish | source
|
||||
|
||||
# To load completions for each session, execute once:
|
||||
$ authelia completion fish > ~/.config/fish/completions/authelia.fish
|
||||
|
||||
PowerShell:
|
||||
|
||||
PS> authelia completion powershell | Out-String | Invoke-Expression
|
||||
|
||||
# To load completions for every new session, run:
|
||||
PS> authelia completion powershell > authelia.ps1
|
||||
# and source this file from your PowerShell profile.
|
||||
`
|
||||
|
||||
const accessControlPolicyCheckLong = `
|
||||
cmdAutheliaAccessControlCheckPolicyLong = `
|
||||
Checks a request against the access control rules to determine what policy would be applied.
|
||||
|
||||
Legend:
|
||||
|
@ -97,15 +69,299 @@ Notes:
|
|||
A rule that potentially matches a request will cause a redirection to occur in order to perform one-factor
|
||||
authentication. This is so Authelia can adequately determine if the rule actually matches.
|
||||
`
|
||||
cmdAutheliaAccessControlCheckPolicyExample = `authelia access-control check-policy --config config.yml --url https://example.com
|
||||
authelia access-control check-policy --config config.yml --url https://example.com --username john
|
||||
authelia access-control check-policy --config config.yml --url https://example.com --groups admin,public
|
||||
authelia access-control check-policy --config config.yml --url https://example.com --username john --method GET
|
||||
authelia access-control check-policy --config config.yml --url https://example.com --username john --method GET --verbose`
|
||||
|
||||
cmdAutheliaStorageShort = "Manage the Authelia storage"
|
||||
|
||||
cmdAutheliaStorageLong = `Manage the Authelia storage.
|
||||
|
||||
This subcommand has several methods to interact with the Authelia SQL Database. This allows doing several advanced
|
||||
operations which would be much harder to do manually.
|
||||
`
|
||||
|
||||
cmdAutheliaStorageExample = `authelia storage --help`
|
||||
|
||||
cmdAutheliaStorageEncryptionShort = "Manage storage encryption"
|
||||
|
||||
cmdAutheliaStorageEncryptionLong = `Manage storage encryption.
|
||||
|
||||
This subcommand allows management of the storage encryption.`
|
||||
|
||||
cmdAutheliaStorageEncryptionExample = `authelia storage encryption --help`
|
||||
|
||||
cmdAutheliaStorageEncryptionCheckShort = "Checks the encryption key against the database data"
|
||||
|
||||
cmdAutheliaStorageEncryptionCheckLong = `Checks the encryption key against the database data.
|
||||
|
||||
This is useful for validating all data that can be encrypted is intact.`
|
||||
|
||||
cmdAutheliaStorageEncryptionCheckExample = `authelia storage encryption check
|
||||
authelia storage encryption check --verbose
|
||||
authelia storage encryption check --verbose --config config.yml
|
||||
authelia storage encryption check --verbose --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||
|
||||
cmdAutheliaStorageEncryptionChangeKeyShort = "Changes the encryption key"
|
||||
|
||||
cmdAutheliaStorageEncryptionChangeKeyLong = `Changes the encryption key.
|
||||
|
||||
This subcommand allows you to change the encryption key of an Authelia SQL database.`
|
||||
|
||||
cmdAutheliaStorageEncryptionChangeKeyExample = `authelia storage encryption change-key --config config.yml --new-encryption-key 0e95cb49-5804-4ad9-be82-bb04a9ddecd8
|
||||
authelia storage encryption change-key --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --new-encryption-key 0e95cb49-5804-4ad9-be82-bb04a9ddecd8 --postgres.host postgres --postgres.password autheliapw`
|
||||
|
||||
cmdAutheliaStorageUserShort = "Manages user settings"
|
||||
|
||||
cmdAutheliaStorageUserLong = `Manages user settings.
|
||||
|
||||
This subcommand allows modifying and exporting user settings.`
|
||||
|
||||
cmdAutheliaStorageUserExample = `authelia storage user --help`
|
||||
|
||||
cmdAutheliaStorageUserIdentifiersShort = "Manage user opaque identifiers"
|
||||
|
||||
cmdAutheliaStorageUserIdentifiersLong = `Manage user opaque identifiers.
|
||||
|
||||
This subcommand allows performing various tasks related to the opaque identifiers for users.`
|
||||
|
||||
cmdAutheliaStorageUserIdentifiersExample = `authelia storage user identifiers --help`
|
||||
|
||||
cmdAutheliaStorageUserIdentifiersExportShort = "Export the identifiers to a YAML file"
|
||||
|
||||
cmdAutheliaStorageUserIdentifiersExportLong = `Export the identifiers to a YAML file.
|
||||
|
||||
This subcommand allows exporting the opaque identifiers for users in order to back them up.`
|
||||
|
||||
cmdAutheliaStorageUserIdentifiersExportExample = `authelia storage user identifiers export
|
||||
authelia storage user identifiers export --file export.yaml
|
||||
authelia storage user identifiers export --file export.yaml --config config.yml
|
||||
authelia storage user identifiers export --file export.yaml --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||
|
||||
cmdAutheliaStorageUserIdentifiersImportShort = "Import the identifiers from a YAML file"
|
||||
|
||||
cmdAutheliaStorageUserIdentifiersImportLong = `Import the identifiers from a YAML file.
|
||||
|
||||
This subcommand allows you to import the opaque identifiers for users from a YAML file.
|
||||
|
||||
The YAML file can either be automatically generated using the authelia storage user identifiers export command, or
|
||||
manually provided the file is in the same format.`
|
||||
|
||||
cmdAutheliaStorageUserIdentifiersImportExample = `authelia storage user identifiers import
|
||||
authelia storage user identifiers import --file export.yaml
|
||||
authelia storage user identifiers import --file export.yaml --config config.yml
|
||||
authelia storage user identifiers import --file export.yaml --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||
|
||||
cmdAutheliaStorageUserIdentifiersGenerateShort = "Generate opaque identifiers in bulk"
|
||||
|
||||
cmdAutheliaStorageUserIdentifiersGenerateLong = `Generate opaque identifiers in bulk.
|
||||
|
||||
This subcommand allows various options for generating the opaque identifies for users in bulk.`
|
||||
|
||||
cmdAutheliaStorageUserIdentifiersGenerateExample = `authelia storage user identifiers generate --users john,mary
|
||||
authelia storage user identifiers generate --users john,mary --services openid
|
||||
authelia storage user identifiers generate --users john,mary --services openid --sectors=",example.com,test.com"
|
||||
authelia storage user identifiers generate --users john,mary --services openid --sectors=",example.com,test.com" --config config.yml
|
||||
authelia storage user identifiers generate --users john,mary --services openid --sectors=",example.com,test.com" --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||
|
||||
cmdAutheliaStorageUserIdentifiersAddShort = "Add an opaque identifier for a user to the database"
|
||||
|
||||
cmdAutheliaStorageUserIdentifiersAddLong = `Add an opaque identifier for a user to the database.
|
||||
|
||||
This subcommand allows manually adding an opaque identifier for a user to the database provided it's in the correct format.`
|
||||
|
||||
cmdAutheliaStorageUserIdentifiersAddExample = `authelia storage user identifiers add john --identifier f0919359-9d15-4e15-bcba-83b41620a073
|
||||
authelia storage user identifiers add john --identifier f0919359-9d15-4e15-bcba-83b41620a073 --config config.yml
|
||||
authelia storage user identifiers add john --identifier f0919359-9d15-4e15-bcba-83b41620a073 --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||
|
||||
cmdAutheliaStorageUserTOTPShort = "Manage TOTP configurations"
|
||||
|
||||
cmdAutheliaStorageUserTOTPLong = `Manage TOTP configurations.
|
||||
|
||||
This subcommand allows deleting, exporting, and creating user TOTP configurations.`
|
||||
|
||||
cmdAutheliaStorageUserTOTPExample = `authelia storage user totp --help`
|
||||
|
||||
cmdAutheliaStorageUserTOTPGenerateShort = "Generate a TOTP configuration for a user"
|
||||
|
||||
cmdAutheliaStorageUserTOTPGenerateLong = `Generate a TOTP configuration for a user.
|
||||
|
||||
This subcommand allows generating a new TOTP configuration for a user,
|
||||
and overwriting the existing configuration if applicable.`
|
||||
|
||||
cmdAutheliaStorageUserTOTPGenerateExample = `authelia storage user totp generate john
|
||||
authelia storage user totp generate john --period 90
|
||||
authelia storage user totp generate john --digits 8
|
||||
authelia storage user totp generate john --algorithm SHA512
|
||||
authelia storage user totp generate john --algorithm SHA512 --config config.yml
|
||||
authelia storage user totp generate john --algorithm SHA512 --config config.yml --path john.png`
|
||||
|
||||
cmdAutheliaStorageUserTOTPDeleteShort = "Delete a TOTP configuration for a user"
|
||||
|
||||
cmdAutheliaStorageUserTOTPDeleteLong = `Delete a TOTP configuration for a user.
|
||||
|
||||
This subcommand allows deleting a TOTP configuration directly from the database for a given user.`
|
||||
|
||||
cmdAutheliaStorageUserTOTPDeleteExample = `authelia storage user totp delete john
|
||||
authelia storage user totp delete john --config config.yml
|
||||
authelia storage user totp delete john --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||
|
||||
cmdAutheliaStorageUserTOTPExportShort = "Perform exports of the TOTP configurations"
|
||||
|
||||
cmdAutheliaStorageUserTOTPExportLong = `Perform exports of the TOTP configurations.
|
||||
|
||||
This subcommand allows exporting TOTP configurations to various formats.`
|
||||
|
||||
cmdAutheliaStorageUserTOTPExportExample = `authelia storage user totp export --format csv
|
||||
authelia storage user totp export --format png --dir ./totp-qr
|
||||
authelia storage user totp export --format png --dir ./totp-qr --config config.yml
|
||||
authelia storage user totp export --format png --dir ./totp-qr --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||
|
||||
cmdAutheliaStorageSchemaInfoShort = "Show the storage information"
|
||||
|
||||
cmdAutheliaStorageSchemaInfoLong = `Show the storage information.
|
||||
|
||||
This subcommand shows advanced information about the storage schema useful in some diagnostic tasks.`
|
||||
|
||||
cmdAutheliaStorageSchemaInfoExample = `authelia storage schema-info
|
||||
authelia storage schema-info --config config.yml
|
||||
authelia storage schema-info --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||
|
||||
cmdAutheliaStorageMigrateShort = "Perform or list migrations"
|
||||
|
||||
cmdAutheliaStorageMigrateLong = `Perform or list migrations.
|
||||
|
||||
This subcommand handles schema migration tasks.`
|
||||
|
||||
cmdAutheliaStorageMigrateExample = `authelia storage migrate --help`
|
||||
|
||||
cmdAutheliaStorageMigrateHistoryShort = "Show migration history"
|
||||
|
||||
cmdAutheliaStorageMigrateHistoryLong = `Show migration history.
|
||||
|
||||
This subcommand allows users to list previous migrations.`
|
||||
|
||||
cmdAutheliaStorageMigrateHistoryExample = `authelia storage migrate history
|
||||
authelia storage migrate history --config config.yml
|
||||
authelia storage migrate history --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||
|
||||
cmdAutheliaStorageMigrateListUpShort = "List the up migrations available"
|
||||
|
||||
cmdAutheliaStorageMigrateListUpLong = `List the up migrations available.
|
||||
|
||||
This subcommand lists the schema migrations available in this version of Authelia which are greater than the current
|
||||
schema version of the database.`
|
||||
|
||||
cmdAutheliaStorageMigrateListUpExample = `authelia storage migrate list-up
|
||||
authelia storage migrate list-up --config config.yml
|
||||
authelia storage migrate list-up --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||
|
||||
cmdAutheliaStorageMigrateListDownShort = "List the down migrations available"
|
||||
|
||||
cmdAutheliaStorageMigrateListDownLong = `List the down migrations available.
|
||||
|
||||
This subcommand lists the schema migrations available in this version of Authelia which are less than the current
|
||||
schema version of the database.`
|
||||
|
||||
cmdAutheliaStorageMigrateListDownExample = `authelia storage migrate list-down
|
||||
authelia storage migrate list-down --config config.yml
|
||||
authelia storage migrate list-down --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||
|
||||
cmdAutheliaStorageMigrateUpShort = "Perform a migration up"
|
||||
|
||||
cmdAutheliaStorageMigrateUpLong = `Perform a migration up.
|
||||
|
||||
This subcommand performs the schema migrations available in this version of Authelia which are greater than the current
|
||||
schema version of the database. By default this will migrate up to the latest available, but you can customize this.`
|
||||
|
||||
cmdAutheliaStorageMigrateUpExample = `authelia storage migrate up
|
||||
authelia storage migrate up --config config.yml
|
||||
authelia storage migrate up --target 20 --config config.yml
|
||||
authelia storage migrate up --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||
|
||||
cmdAutheliaStorageMigrateDownShort = "Perform a migration down"
|
||||
|
||||
cmdAutheliaStorageMigrateDownLong = `Perform a migration down.
|
||||
|
||||
This subcommand performs the schema migrations available in this version of Authelia which are less than the current
|
||||
schema version of the database.`
|
||||
|
||||
cmdAutheliaStorageMigrateDownExample = `authelia storage migrate down --target 20
|
||||
authelia storage migrate down --target 20 --config config.yml
|
||||
authelia storage migrate down --target 20 --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||
|
||||
cmdAutheliaValidateConfigShort = "Check a configuration against the internal configuration validation mechanisms"
|
||||
|
||||
cmdAutheliaValidateConfigLong = `Check a configuration against the internal configuration validation mechanisms.
|
||||
|
||||
This subcommand allows validation of the YAML and Environment configurations so that a configuration can be checked
|
||||
prior to deploying it.`
|
||||
|
||||
cmdAutheliaValidateConfigExample = `authelia validate-config
|
||||
authelia validate-config --config config.yml`
|
||||
|
||||
cmdAutheliaCertificatesShort = "Commands related to certificate generation"
|
||||
|
||||
cmdAutheliaCertificatesLong = `Commands related to certificate generation.
|
||||
|
||||
This subcommand allows preforming X509 certificate tasks.`
|
||||
|
||||
cmdAutheliaCertificatesExample = `authelia certificates --help`
|
||||
|
||||
cmdAutheliaCertificatesGenerateShort = "Generate a self-signed certificate"
|
||||
|
||||
cmdAutheliaCertificatesGenerateLong = `Generate a self-signed certificate.
|
||||
|
||||
This subcommand allows generating self-signed certificates.`
|
||||
|
||||
cmdAutheliaCertificatesGenerateExample = `authelia certificates generate
|
||||
authelia certificates generate --dir ./out`
|
||||
|
||||
cmdAutheliaRSAShort = "Commands related to rsa keypair generation"
|
||||
|
||||
cmdAutheliaRSALong = `Commands related to rsa keypair generation.
|
||||
|
||||
This subcommand allows performing RSA keypair tasks.`
|
||||
|
||||
cmdAutheliaRSAExample = `authelia rsa --help`
|
||||
|
||||
cmdAutheliaRSAGenerateShort = "Generate a RSA keypair"
|
||||
|
||||
cmdAutheliaRSAGenerateLong = `Generate a RSA keypair.
|
||||
|
||||
This subcommand allows generating an RSA keypair.`
|
||||
|
||||
cmdAutheliaRSAGenerateExample = `authelia rsa generate
|
||||
authelia rsa generate --dir ./out`
|
||||
|
||||
cmdAutheliaHashPasswordShort = "Hash a password to be used in file-based users database."
|
||||
|
||||
cmdAutheliaHashPasswordLong = `Hash a password to be used in file-based users database.`
|
||||
|
||||
//nolint:gosec // This is an example.
|
||||
cmdAutheliaHashPasswordExample = `authelia hash-password -- 'mypass'
|
||||
authelia hash-password --sha512 -- 'mypass'
|
||||
authelia hash-password --iterations=4 -- 'mypass'
|
||||
authelia hash-password --memory=128 -- 'mypass'
|
||||
authelia hash-password --parallelism=1 -- 'mypass'
|
||||
authelia hash-password --key-length=64 -- 'mypass'`
|
||||
)
|
||||
|
||||
const (
|
||||
storageMigrateDirectionUp = "up"
|
||||
storageMigrateDirectionDown = "down"
|
||||
)
|
||||
|
||||
const (
|
||||
storageExportFormatCSV = "csv"
|
||||
storageExportFormatURI = "uri"
|
||||
storageExportFormatPNG = "png"
|
||||
storageTOTPExportFormatCSV = "csv"
|
||||
storageTOTPExportFormatURI = "uri"
|
||||
storageTOTPExportFormatPNG = "png"
|
||||
)
|
||||
|
||||
var (
|
||||
validStorageTOTPExportFormats = []string{storageTOTPExportFormatCSV, storageTOTPExportFormatURI, storageTOTPExportFormatPNG}
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -12,13 +12,14 @@ import (
|
|||
"github.com/authelia/authelia/v4/internal/configuration/validator"
|
||||
)
|
||||
|
||||
// NewHashPasswordCmd returns a new Hash Password Cmd.
|
||||
func NewHashPasswordCmd() (cmd *cobra.Command) {
|
||||
func newHashPasswordCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "hash-password [flags] -- <password>",
|
||||
Short: "Hash a password to be used in file-based users database. Default algorithm is argon2id.",
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
RunE: cmdHashPasswordRunE,
|
||||
Use: "hash-password [flags] -- <password>",
|
||||
Short: cmdAutheliaHashPasswordShort,
|
||||
Long: cmdAutheliaHashPasswordLong,
|
||||
Example: cmdAutheliaHashPasswordExample,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
RunE: cmdHashPasswordRunE,
|
||||
}
|
||||
|
||||
cmd.Flags().BoolP("sha512", "z", false, fmt.Sprintf("use sha512 as the algorithm (changes iterations to %d, change with -i)", schema.DefaultPasswordSHA512Configuration.Iterations))
|
||||
|
|
|
@ -23,9 +23,9 @@ func NewRootCmd() (cmd *cobra.Command) {
|
|||
|
||||
cmd = &cobra.Command{
|
||||
Use: "authelia",
|
||||
Short: fmt.Sprintf(fmtCmdAutheliaShort, version),
|
||||
Long: fmt.Sprintf(fmtCmdAutheliaLong, version),
|
||||
Example: cmdAutheliaExample,
|
||||
Short: fmt.Sprintf("authelia %s", version),
|
||||
Long: fmt.Sprintf(fmtAutheliaLong, version),
|
||||
Version: version,
|
||||
Args: cobra.NoArgs,
|
||||
PreRun: newCmdWithConfigPreRun(true, true, true),
|
||||
|
@ -36,11 +36,10 @@ func NewRootCmd() (cmd *cobra.Command) {
|
|||
|
||||
cmd.AddCommand(
|
||||
newBuildInfoCmd(),
|
||||
NewCertificatesCmd(),
|
||||
newCompletionCmd(),
|
||||
NewHashPasswordCmd(),
|
||||
newCertificatesCmd(),
|
||||
newHashPasswordCmd(),
|
||||
NewRSACmd(),
|
||||
NewStorageCmd(),
|
||||
newStorageCmd(),
|
||||
newValidateConfigCmd(),
|
||||
newAccessControlCommand(),
|
||||
)
|
||||
|
|
|
@ -13,9 +13,11 @@ import (
|
|||
// NewRSACmd returns a new RSA Cmd.
|
||||
func NewRSACmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "rsa",
|
||||
Short: "Commands related to rsa keypair generation",
|
||||
Args: cobra.NoArgs,
|
||||
Use: "rsa",
|
||||
Short: cmdAutheliaRSAShort,
|
||||
Long: cmdAutheliaRSALong,
|
||||
Example: cmdAutheliaRSAExample,
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
|
||||
cmd.AddCommand(newRSAGenerateCmd())
|
||||
|
@ -25,10 +27,12 @@ func NewRSACmd() (cmd *cobra.Command) {
|
|||
|
||||
func newRSAGenerateCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "generate",
|
||||
Short: "Generate a RSA keypair",
|
||||
Args: cobra.NoArgs,
|
||||
Run: cmdRSAGenerateRun,
|
||||
Use: "generate",
|
||||
Short: cmdAutheliaRSAGenerateShort,
|
||||
Long: cmdAutheliaRSAGenerateLong,
|
||||
Example: cmdAutheliaRSAGenerateExample,
|
||||
Args: cobra.NoArgs,
|
||||
Run: cmdRSAGenerateRun,
|
||||
}
|
||||
|
||||
cmd.Flags().StringP("dir", "d", "", "Target directory where the keypair will be stored")
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
||||
)
|
||||
|
||||
// NewStorageCmd returns a new storage *cobra.Command.
|
||||
func NewStorageCmd() (cmd *cobra.Command) {
|
||||
func newStorageCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "storage",
|
||||
Short: "Manage the Authelia storage",
|
||||
Short: cmdAutheliaStorageShort,
|
||||
Long: cmdAutheliaStorageLong,
|
||||
Example: cmdAutheliaStorageExample,
|
||||
Args: cobra.NoArgs,
|
||||
PersistentPreRunE: storagePersistentPreRunE,
|
||||
}
|
||||
|
@ -48,15 +52,61 @@ func NewStorageCmd() (cmd *cobra.Command) {
|
|||
return cmd
|
||||
}
|
||||
|
||||
func newStorageEncryptionCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "encryption",
|
||||
Short: cmdAutheliaStorageEncryptionShort,
|
||||
Long: cmdAutheliaStorageEncryptionLong,
|
||||
Example: cmdAutheliaStorageEncryptionExample,
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
newStorageEncryptionChangeKeyCmd(),
|
||||
newStorageEncryptionCheckCmd(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newStorageEncryptionCheckCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "check",
|
||||
Short: cmdAutheliaStorageEncryptionCheckShort,
|
||||
Long: cmdAutheliaStorageEncryptionCheckLong,
|
||||
Example: cmdAutheliaStorageEncryptionCheckExample,
|
||||
RunE: storageSchemaEncryptionCheckRunE,
|
||||
}
|
||||
|
||||
cmd.Flags().Bool("verbose", false, "enables verbose checking of every row of encrypted data")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newStorageEncryptionChangeKeyCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "change-key",
|
||||
Short: cmdAutheliaStorageEncryptionChangeKeyShort,
|
||||
Long: cmdAutheliaStorageEncryptionChangeKeyLong,
|
||||
Example: cmdAutheliaStorageEncryptionChangeKeyExample,
|
||||
RunE: storageSchemaEncryptionChangeKeyRunE,
|
||||
}
|
||||
|
||||
cmd.Flags().String("new-encryption-key", "", "the new key to encrypt the data with")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newStorageUserCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "user",
|
||||
Short: "Manages user settings",
|
||||
Use: "user",
|
||||
Short: cmdAutheliaStorageUserShort,
|
||||
Long: cmdAutheliaStorageUserLong,
|
||||
Example: cmdAutheliaStorageUserExample,
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
newStorageUserIdentifiersCmd(),
|
||||
newStorageTOTPCmd(),
|
||||
newStorageUserTOTPCmd(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
|
@ -64,8 +114,10 @@ func newStorageUserCmd() (cmd *cobra.Command) {
|
|||
|
||||
func newStorageUserIdentifiersCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "identifiers",
|
||||
Short: "Manages user opaque identifiers",
|
||||
Use: "identifiers",
|
||||
Short: cmdAutheliaStorageUserIdentifiersShort,
|
||||
Long: cmdAutheliaStorageUserIdentifiersLong,
|
||||
Example: cmdAutheliaStorageUserIdentifiersExample,
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
|
@ -80,9 +132,11 @@ func newStorageUserIdentifiersCmd() (cmd *cobra.Command) {
|
|||
|
||||
func newStorageUserIdentifiersExportCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "export",
|
||||
Short: "Export the identifiers to a YAML file",
|
||||
RunE: storageUserIdentifiersExport,
|
||||
Use: "export",
|
||||
Short: cmdAutheliaStorageUserIdentifiersExportShort,
|
||||
Long: cmdAutheliaStorageUserIdentifiersExportLong,
|
||||
Example: cmdAutheliaStorageUserIdentifiersExportExample,
|
||||
RunE: storageUserIdentifiersExport,
|
||||
}
|
||||
|
||||
cmd.Flags().StringP("file", "f", "user-opaque-identifiers.yml", "The file name for the YAML export")
|
||||
|
@ -92,9 +146,11 @@ func newStorageUserIdentifiersExportCmd() (cmd *cobra.Command) {
|
|||
|
||||
func newStorageUserIdentifiersImportCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "import",
|
||||
Short: "Import the identifiers from a YAML file",
|
||||
RunE: storageUserIdentifiersImport,
|
||||
Use: "import",
|
||||
Short: cmdAutheliaStorageUserIdentifiersImportShort,
|
||||
Long: cmdAutheliaStorageUserIdentifiersImportLong,
|
||||
Example: cmdAutheliaStorageUserIdentifiersImportExample,
|
||||
RunE: storageUserIdentifiersImport,
|
||||
}
|
||||
|
||||
cmd.Flags().StringP("file", "f", "user-opaque-identifiers.yml", "The file name for the YAML import")
|
||||
|
@ -104,13 +160,15 @@ func newStorageUserIdentifiersImportCmd() (cmd *cobra.Command) {
|
|||
|
||||
func newStorageUserIdentifiersGenerateCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "generate",
|
||||
Short: "Generate opaque identifiers in bulk",
|
||||
RunE: storageUserIdentifiersGenerate,
|
||||
Use: "generate",
|
||||
Short: cmdAutheliaStorageUserIdentifiersGenerateShort,
|
||||
Long: cmdAutheliaStorageUserIdentifiersGenerateLong,
|
||||
Example: cmdAutheliaStorageUserIdentifiersGenerateExample,
|
||||
RunE: storageUserIdentifiersGenerate,
|
||||
}
|
||||
|
||||
cmd.Flags().StringSlice("users", nil, "The list of users to generate the opaque identifiers for")
|
||||
cmd.Flags().StringSlice("services", []string{identifierServiceOpenIDConnect}, "The list of services to generate the opaque identifiers for, valid values are: openid")
|
||||
cmd.Flags().StringSlice("services", []string{identifierServiceOpenIDConnect}, fmt.Sprintf("The list of services to generate the opaque identifiers for, valid values are: %s", strings.Join(validIdentifierServices, ", ")))
|
||||
cmd.Flags().StringSlice("sectors", []string{""}, "The list of sectors to generate identifiers for")
|
||||
|
||||
return cmd
|
||||
|
@ -118,78 +176,46 @@ func newStorageUserIdentifiersGenerateCmd() (cmd *cobra.Command) {
|
|||
|
||||
func newStorageUserIdentifiersAddCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "add [username]",
|
||||
Short: "Add an identifiers to the database",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: storageUserIdentifiersAdd,
|
||||
Use: "add <username>",
|
||||
Short: cmdAutheliaStorageUserIdentifiersAddShort,
|
||||
Long: cmdAutheliaStorageUserIdentifiersAddLong,
|
||||
Example: cmdAutheliaStorageUserIdentifiersAddExample,
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: storageUserIdentifiersAdd,
|
||||
}
|
||||
|
||||
cmd.Flags().String("identifier", "", "The optional version 4 UUID to use, if not set a random one will be used")
|
||||
cmd.Flags().String("service", identifierServiceOpenIDConnect, "The service to add the identifier for, valid values are: openid")
|
||||
cmd.Flags().String("service", identifierServiceOpenIDConnect, fmt.Sprintf("The service to add the identifier for, valid values are: %s", strings.Join(validIdentifierServices, ", ")))
|
||||
cmd.Flags().String("sector", "", "The sector identifier to use (should usually be blank)")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newStorageEncryptionCmd() (cmd *cobra.Command) {
|
||||
func newStorageUserTOTPCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "encryption",
|
||||
Short: "Manages encryption",
|
||||
Use: "totp",
|
||||
Short: cmdAutheliaStorageUserTOTPShort,
|
||||
Long: cmdAutheliaStorageUserTOTPLong,
|
||||
Example: cmdAutheliaStorageUserTOTPExample,
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
newStorageEncryptionChangeKeyCmd(),
|
||||
newStorageEncryptionCheckCmd(),
|
||||
newStorageUserTOTPGenerateCmd(),
|
||||
newStorageUserTOTPDeleteCmd(),
|
||||
newStorageUserTOTPExportCmd(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newStorageEncryptionCheckCmd() (cmd *cobra.Command) {
|
||||
func newStorageUserTOTPGenerateCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "check",
|
||||
Short: "Checks the encryption key against the database data",
|
||||
RunE: storageSchemaEncryptionCheckRunE,
|
||||
}
|
||||
|
||||
cmd.Flags().Bool("verbose", false, "enables verbose checking of every row of encrypted data")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newStorageEncryptionChangeKeyCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "change-key",
|
||||
Short: "Changes the encryption key",
|
||||
RunE: storageSchemaEncryptionChangeKeyRunE,
|
||||
}
|
||||
|
||||
cmd.Flags().String("new-encryption-key", "", "the new key to encrypt the data with")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newStorageTOTPCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "totp",
|
||||
Short: "Manage TOTP configurations",
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
newStorageTOTPGenerateCmd(),
|
||||
newStorageTOTPDeleteCmd(),
|
||||
newStorageTOTPExportCmd(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newStorageTOTPGenerateCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "generate [username]",
|
||||
Short: "Generate a TOTP configuration for a user",
|
||||
RunE: storageTOTPGenerateRunE,
|
||||
Args: cobra.ExactArgs(1),
|
||||
Use: "generate <username>",
|
||||
Short: cmdAutheliaStorageUserTOTPGenerateShort,
|
||||
Long: cmdAutheliaStorageUserTOTPGenerateLong,
|
||||
Example: cmdAutheliaStorageUserTOTPGenerateExample,
|
||||
RunE: storageTOTPGenerateRunE,
|
||||
Args: cobra.ExactArgs(1),
|
||||
}
|
||||
|
||||
cmd.Flags().String("secret", "", "Optionally set the TOTP shared secret as base32 encoded bytes (no padding), it's recommended to not set this option unless you're restoring an TOTP config")
|
||||
|
@ -204,25 +230,29 @@ func newStorageTOTPGenerateCmd() (cmd *cobra.Command) {
|
|||
return cmd
|
||||
}
|
||||
|
||||
func newStorageTOTPDeleteCmd() (cmd *cobra.Command) {
|
||||
func newStorageUserTOTPDeleteCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "delete username",
|
||||
Short: "Delete a TOTP configuration for a user",
|
||||
RunE: storageTOTPDeleteRunE,
|
||||
Args: cobra.ExactArgs(1),
|
||||
Use: "delete <username>",
|
||||
Short: cmdAutheliaStorageUserTOTPDeleteShort,
|
||||
Long: cmdAutheliaStorageUserTOTPDeleteLong,
|
||||
Example: cmdAutheliaStorageUserTOTPDeleteExample,
|
||||
RunE: storageTOTPDeleteRunE,
|
||||
Args: cobra.ExactArgs(1),
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newStorageTOTPExportCmd() (cmd *cobra.Command) {
|
||||
func newStorageUserTOTPExportCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "export",
|
||||
Short: "Performs exports of the TOTP configurations",
|
||||
RunE: storageTOTPExportRunE,
|
||||
Use: "export",
|
||||
Short: cmdAutheliaStorageUserTOTPExportShort,
|
||||
Long: cmdAutheliaStorageUserTOTPExportLong,
|
||||
Example: cmdAutheliaStorageUserTOTPExportExample,
|
||||
RunE: storageTOTPExportRunE,
|
||||
}
|
||||
|
||||
cmd.Flags().String("format", storageExportFormatURI, "sets the output format")
|
||||
cmd.Flags().String("format", storageTOTPExportFormatURI, fmt.Sprintf("sets the output format, valid values are: %s", strings.Join(validStorageTOTPExportFormats, ", ")))
|
||||
cmd.Flags().String("dir", "", "used with the png output format to specify which new directory to save the files in")
|
||||
|
||||
return cmd
|
||||
|
@ -230,9 +260,11 @@ func newStorageTOTPExportCmd() (cmd *cobra.Command) {
|
|||
|
||||
func newStorageSchemaInfoCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "schema-info",
|
||||
Short: "Show the storage information",
|
||||
RunE: storageSchemaInfoRunE,
|
||||
Use: "schema-info",
|
||||
Short: cmdAutheliaStorageSchemaInfoShort,
|
||||
Long: cmdAutheliaStorageSchemaInfoLong,
|
||||
Example: cmdAutheliaStorageSchemaInfoExample,
|
||||
RunE: storageSchemaInfoRunE,
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
@ -241,9 +273,11 @@ func newStorageSchemaInfoCmd() (cmd *cobra.Command) {
|
|||
// NewMigrationCmd returns a new Migration Cmd.
|
||||
func newStorageMigrateCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "migrate",
|
||||
Short: "Perform or list migrations",
|
||||
Args: cobra.NoArgs,
|
||||
Use: "migrate",
|
||||
Short: cmdAutheliaStorageMigrateShort,
|
||||
Long: cmdAutheliaStorageMigrateLong,
|
||||
Example: cmdAutheliaStorageMigrateExample,
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
|
@ -257,10 +291,12 @@ func newStorageMigrateCmd() (cmd *cobra.Command) {
|
|||
|
||||
func newStorageMigrateHistoryCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "history",
|
||||
Short: "Show migration history",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: storageMigrateHistoryRunE,
|
||||
Use: "history",
|
||||
Short: cmdAutheliaStorageMigrateHistoryShort,
|
||||
Long: cmdAutheliaStorageMigrateHistoryLong,
|
||||
Example: cmdAutheliaStorageMigrateHistoryExample,
|
||||
Args: cobra.NoArgs,
|
||||
RunE: storageMigrateHistoryRunE,
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
@ -268,10 +304,12 @@ func newStorageMigrateHistoryCmd() (cmd *cobra.Command) {
|
|||
|
||||
func newStorageMigrateListUpCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "list-up",
|
||||
Short: "List the up migrations available",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: newStorageMigrateListRunE(true),
|
||||
Use: "list-up",
|
||||
Short: cmdAutheliaStorageMigrateListUpShort,
|
||||
Long: cmdAutheliaStorageMigrateListUpLong,
|
||||
Example: cmdAutheliaStorageMigrateListUpExample,
|
||||
Args: cobra.NoArgs,
|
||||
RunE: newStorageMigrateListRunE(true),
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
@ -279,10 +317,12 @@ func newStorageMigrateListUpCmd() (cmd *cobra.Command) {
|
|||
|
||||
func newStorageMigrateListDownCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "list-down",
|
||||
Short: "List the down migrations available",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: newStorageMigrateListRunE(false),
|
||||
Use: "list-down",
|
||||
Short: cmdAutheliaStorageMigrateListDownShort,
|
||||
Long: cmdAutheliaStorageMigrateListDownLong,
|
||||
Example: cmdAutheliaStorageMigrateListDownExample,
|
||||
Args: cobra.NoArgs,
|
||||
RunE: newStorageMigrateListRunE(false),
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
@ -290,10 +330,12 @@ func newStorageMigrateListDownCmd() (cmd *cobra.Command) {
|
|||
|
||||
func newStorageMigrateUpCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: storageMigrateDirectionUp,
|
||||
Short: "Perform a migration up",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: newStorageMigrationRunE(true),
|
||||
Use: storageMigrateDirectionUp,
|
||||
Short: cmdAutheliaStorageMigrateUpShort,
|
||||
Long: cmdAutheliaStorageMigrateUpLong,
|
||||
Example: cmdAutheliaStorageMigrateUpExample,
|
||||
Args: cobra.NoArgs,
|
||||
RunE: newStorageMigrationRunE(true),
|
||||
}
|
||||
|
||||
cmd.Flags().IntP("target", "t", 0, "sets the version to migrate to, by default this is the latest version")
|
||||
|
@ -303,10 +345,12 @@ func newStorageMigrateUpCmd() (cmd *cobra.Command) {
|
|||
|
||||
func newStorageMigrateDownCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: storageMigrateDirectionDown,
|
||||
Short: "Perform a migration down",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: newStorageMigrationRunE(false),
|
||||
Use: storageMigrateDirectionDown,
|
||||
Short: cmdAutheliaStorageMigrateDownShort,
|
||||
Long: cmdAutheliaStorageMigrateDownLong,
|
||||
Example: cmdAutheliaStorageMigrateDownExample,
|
||||
Args: cobra.NoArgs,
|
||||
RunE: newStorageMigrationRunE(false),
|
||||
}
|
||||
|
||||
cmd.Flags().IntP("target", "t", 0, "sets the version to migrate to")
|
||||
|
|
|
@ -351,17 +351,17 @@ func storageTOTPExportRunE(cmd *cobra.Command, args []string) (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
if page == 0 && format == storageExportFormatCSV {
|
||||
if page == 0 && format == storageTOTPExportFormatCSV {
|
||||
fmt.Printf("issuer,username,algorithm,digits,period,secret\n")
|
||||
}
|
||||
|
||||
for _, c := range configurations {
|
||||
switch format {
|
||||
case storageExportFormatCSV:
|
||||
case storageTOTPExportFormatCSV:
|
||||
fmt.Printf("%s,%s,%s,%d,%d,%s\n", c.Issuer, c.Username, c.Algorithm, c.Digits, c.Period, string(c.Secret))
|
||||
case storageExportFormatURI:
|
||||
case storageTOTPExportFormatURI:
|
||||
fmt.Println(c.URI())
|
||||
case storageExportFormatPNG:
|
||||
case storageTOTPExportFormatPNG:
|
||||
file, _ := os.Create(filepath.Join(dir, fmt.Sprintf("%s.png", c.Username)))
|
||||
|
||||
if img, err = c.Image(256, 256); err != nil {
|
||||
|
@ -385,7 +385,7 @@ func storageTOTPExportRunE(cmd *cobra.Command, args []string) (err error) {
|
|||
}
|
||||
}
|
||||
|
||||
if format == storageExportFormatPNG {
|
||||
if format == storageTOTPExportFormatPNG {
|
||||
fmt.Printf("Exported TOTP QR codes in PNG format in the '%s' directory\n", dir)
|
||||
}
|
||||
|
||||
|
@ -402,9 +402,9 @@ func storageTOTPExportGetConfigFromFlags(cmd *cobra.Command) (format, dir string
|
|||
}
|
||||
|
||||
switch format {
|
||||
case storageExportFormatCSV, storageExportFormatURI:
|
||||
case storageTOTPExportFormatCSV, storageTOTPExportFormatURI:
|
||||
break
|
||||
case storageExportFormatPNG:
|
||||
case storageTOTPExportFormatPNG:
|
||||
if dir == "" {
|
||||
dir = utils.RandomString(8, utils.AlphaNumericCharacters, false)
|
||||
}
|
||||
|
|
|
@ -10,10 +10,12 @@ import (
|
|||
|
||||
func newValidateConfigCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "validate-config",
|
||||
Short: "Check a configuration against the internal configuration validation mechanisms",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: cmdValidateConfigRunE,
|
||||
Use: "validate-config",
|
||||
Short: cmdAutheliaValidateConfigShort,
|
||||
Long: cmdAutheliaValidateConfigLong,
|
||||
Example: cmdAutheliaValidateConfigExample,
|
||||
Args: cobra.NoArgs,
|
||||
RunE: cmdValidateConfigRunE,
|
||||
}
|
||||
|
||||
cmdWithConfigFlags(cmd, false, []string{"configuration.yml"})
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
// Code generated by go generate. DO NOT EDIT.
|
||||
//
|
||||
// Run the following command to generate this file:
|
||||
// go run ./cmd/authelia-scripts gen
|
||||
// go run ./cmd/authelia-gen code keys
|
||||
//
|
||||
|
||||
package schema
|
||||
|
||||
// Keys represents the detected schema keys.
|
||||
// Keys is a list of valid schema keys detected by reflecting over a schema.Configuration struct.
|
||||
var Keys = []string{
|
||||
"theme",
|
||||
"certificates_directory",
|
||||
|
|
Loading…
Reference in New Issue