Skip to content

Commit

Permalink
Merge pull request #258 from documize/startup-config
Browse files Browse the repository at this point in the history
Support for documize.conf files
  • Loading branch information
sauls8t committed Apr 29, 2019
2 parents 4255291 + b971c52 commit 9a53958
Show file tree
Hide file tree
Showing 32 changed files with 4,963 additions and 1,262 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,4 @@ bower.json.ember-try
package.json.ember-try
embed/bindata_assetfs.go
dmz-backup*.zip
*.conf
9 changes: 9 additions & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2545,3 +2545,27 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


https://github.com/BurntSushi

The MIT License (MIT)

Copyright (c) 2013 TOML authors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
108 changes: 108 additions & 0 deletions core/env/command_line.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Copyright 2016 Documize Inc. <[email protected]>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <[email protected]>.
//
// https://documize.com

// Package env provides runtime, server level setup and configuration
package env

import (
"flag"
"fmt"
"os"
"sort"
"strings"
"sync"
)

// prefix provides the prefix for all environment variables
const prefix = "DOCUMIZE"
const goInit = "(default)"

var flagList progFlags
var cliMutex sync.Mutex

type flagItem struct {
target *string
name, setter, value string
required bool
}

type progFlags struct {
items []flagItem
}

// Len is part of sort.Interface.
func (v *progFlags) Len() int {
return len(v.items)
}

// Swap is part of sort.Interface.
func (v *progFlags) Swap(i, j int) {
v.items[i], v.items[j] = v.items[j], v.items[i]
}

// Less is part of sort.Interface.
func (v *progFlags) Less(i, j int) bool {
return v.items[i].name < v.items[j].name
}

// register prepares flag for subsequent parsing
func register(target *string, name string, required bool, usage string) {
cliMutex.Lock()
defer cliMutex.Unlock()

name = strings.ToLower(strings.TrimSpace(name))
setter := prefix + strings.ToUpper(name)

value := os.Getenv(setter)
if value == "" {
value = *target // use the Go initialized value
setter = goInit
}

flag.StringVar(target, name, value, usage)
flagList.items = append(flagList.items, flagItem{target: target, name: name, required: required, value: value, setter: setter})
}

// parse loads flags from OS environment and command line switches
func parse(doFirst string) (ok bool) {
cliMutex.Lock()
defer cliMutex.Unlock()

flag.Parse()
sort.Sort(&flagList)

for pass := 1; pass <= 2; pass++ {
for vi, v := range flagList.items {
if (pass == 1 && v.name == doFirst) || (pass == 2 && v.name != doFirst) {
if v.value != *(v.target) || (v.value != "" && *(v.target) == "") {
flagList.items[vi].setter = "-" + v.name // v is a local copy, not the underlying data
}
if v.required {
if *(v.target) == "" {
fmt.Fprintln(os.Stderr)
fmt.Fprintln(os.Stderr, "In order to run", os.Args[0], "the following must be provided:")
for _, vv := range flagList.items {
if vv.required {
fmt.Fprintf(os.Stderr, "* setting from environment variable '%s' or flag '-%s' or an application setting '%s', current value: '%s' set by '%s'\n",
prefix+strings.ToUpper(vv.name), vv.name, vv.name, *(vv.target), vv.setter)
}
}
fmt.Fprintln(os.Stderr)
flag.Usage()
return false
}
}
}
}
}

return true
}
147 changes: 20 additions & 127 deletions core/env/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,152 +12,45 @@
// Package env provides runtime, server level setup and configuration
package env

import (
"flag"
"fmt"
"os"
"sort"
"strings"
"sync"
)

// Flags provides access to environment and command line switches for this program.
type Flags struct {
DBType string // database type
DBConn string // database connection string
Salt string // the salt string used to encode JWT tokens
DBType string // database type
SSLCertFile string // (optional) name of SSL certificate PEM file
SSLKeyFile string // (optional) name of SSL key PEM file
HTTPPort string // (optional) HTTP or HTTPS port
ForceHTTPPort2SSL string // (optional) HTTP that should be redirected to HTTPS
SSLCertFile string // (optional) name of SSL certificate PEM file
SSLKeyFile string // (optional) name of SSL key PEM file
SiteMode string // (optional) if 1 then serve offline web page
Location string // reserved
ConfigSource string // tells us if configuration info was obtained from command line or config file
}

// SSLEnabled returns true if both cert and key were provided at runtime.
func (f *Flags) SSLEnabled() bool {
return f.SSLCertFile != "" && f.SSLKeyFile != ""
}

type flagItem struct {
target *string
name, setter, value string
required bool
}

type progFlags struct {
items []flagItem
}

// Len is part of sort.Interface.
func (v *progFlags) Len() int {
return len(v.items)
}

// Swap is part of sort.Interface.
func (v *progFlags) Swap(i, j int) {
v.items[i], v.items[j] = v.items[j], v.items[i]
}

// Less is part of sort.Interface.
func (v *progFlags) Less(i, j int) bool {
return v.items[i].name < v.items[j].name
// ConfigToml represents configuration file that contains all flags as per above.
type ConfigToml struct {
HTTP httpConfig `toml:"http"`
Database databaseConfig `toml:"database"`
Install installConfig `toml:"install"`
}

// prefix provides the prefix for all environment variables
const prefix = "DOCUMIZE"
const goInit = "(default)"

var flagList progFlags
var loadMutex sync.Mutex

// ParseFlags loads command line and OS environment variables required by the program to function.
func ParseFlags() (f Flags, ok bool) {
ok = true
var dbConn, dbType, jwtKey, siteMode, port, certFile, keyFile, forcePort2SSL, location string

register(&jwtKey, "salt", false, "the salt string used to encode JWT tokens, if not set a random value will be generated")
register(&certFile, "cert", false, "the cert.pem file used for https")
register(&keyFile, "key", false, "the key.pem file used for https")
register(&port, "port", false, "http/https port number")
register(&forcePort2SSL, "forcesslport", false, "redirect given http port number to TLS")
register(&siteMode, "offline", false, "set to '1' for OFFLINE mode")
register(&dbType, "dbtype", true, "specify the database provider: mysql|percona|mariadb|postgresql|sqlserver")
register(&dbConn, "db", true, `'database specific connection string for example "user:password@tcp(localhost:3306)/dbname"`)
register(&location, "location", false, `reserved`)

if !parse("db") {
ok = false
}

f.DBType = strings.ToLower(dbType)
f.DBConn = dbConn
f.ForceHTTPPort2SSL = forcePort2SSL
f.HTTPPort = port
f.Salt = jwtKey
f.SiteMode = siteMode
f.SSLCertFile = certFile
f.SSLKeyFile = keyFile

// reserved
if len(location) == 0 {
location = "selfhost"
}
f.Location = strings.ToLower(location)

return f, ok
type httpConfig struct {
Port int
ForceSSLPort int
Cert string
Key string
}

// register prepares flag for subsequent parsing
func register(target *string, name string, required bool, usage string) {
loadMutex.Lock()
defer loadMutex.Unlock()

name = strings.ToLower(strings.TrimSpace(name))
setter := prefix + strings.ToUpper(name)

value := os.Getenv(setter)
if value == "" {
value = *target // use the Go initialized value
setter = goInit
}

flag.StringVar(target, name, value, usage)
flagList.items = append(flagList.items, flagItem{target: target, name: name, required: required, value: value, setter: setter})
type databaseConfig struct {
Type string
Connection string
Salt string
}

// parse loads flags from OS environment and command line switches
func parse(doFirst string) (ok bool) {
loadMutex.Lock()
defer loadMutex.Unlock()

flag.Parse()
sort.Sort(&flagList)

for pass := 1; pass <= 2; pass++ {
for vi, v := range flagList.items {
if (pass == 1 && v.name == doFirst) || (pass == 2 && v.name != doFirst) {
if v.value != *(v.target) || (v.value != "" && *(v.target) == "") {
flagList.items[vi].setter = "-" + v.name // v is a local copy, not the underlying data
}
if v.required {
if *(v.target) == "" {
fmt.Fprintln(os.Stderr)
fmt.Fprintln(os.Stderr, "In order to run", os.Args[0], "the following must be provided:")
for _, vv := range flagList.items {
if vv.required {
fmt.Fprintf(os.Stderr, "* setting from environment variable '%s' or flag '-%s' or an application setting '%s', current value: '%s' set by '%s'\n",
prefix+strings.ToUpper(vv.name), vv.name, vv.name, *(vv.target), vv.setter)
}
}
fmt.Fprintln(os.Stderr)
flag.Usage()
return false
}
}
}
}
}

return true
type installConfig struct {
Location string
}
Loading

0 comments on commit 9a53958

Please sign in to comment.