-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconfigure.go
147 lines (127 loc) · 4.44 KB
/
configure.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package cmd
import (
"encoding/hex"
"fmt"
"io/ioutil"
"net/http"
"path"
"strings"
homedir "github.com/mitchellh/go-homedir"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"golang.org/x/crypto/sha3"
)
// The NATS URL passed in from command-line
var natsURL string
// The NATS cluster ID passed in from command-line
var natsClusterID string
// Path to CA certificate path (useful for self-signed CAs)
var natsCaCert string
// The URL or filepath to file
var keyFile string
// A known fingerprint in hex format
var knownFingerprint string
// Whether standard uuid format channel names should be used instead of the short names
var useLongName bool
// Whether the current config file should be overwritten
var forceWrite bool
// Shake256MinBytesRequired is our minimum bytes required for input to SHAKE-256
const Shake256MinBytesRequired = 64
func generateFingerprint(keyFile string) string {
hash := make([]byte, FingerprintByteLength)
var inputBytes []byte
var err error
if keyFile == "" {
return ""
}
if strings.HasPrefix(keyFile, "http://") || strings.HasPrefix(keyFile, "https://") {
// Read keyfile from url
resp, err := http.Get(keyFile)
if err != nil {
errorExit(err.Error())
}
if resp.StatusCode != http.StatusOK {
errMsg := fmt.Sprintf("Keyfile url not OK - Status code %d was returned from GET %s", resp.StatusCode, keyFile)
errorExit(errMsg)
}
defer resp.Body.Close()
inputBytes, err = ioutil.ReadAll(resp.Body)
if err != nil {
errorExit(err.Error())
}
} else {
// Read keyfile from local file
inputBytes, err = ioutil.ReadFile(keyFile)
if err != nil {
errorExit(err.Error())
}
}
// Generate the fingerprint
inputBytesLen := len(inputBytes)
if inputBytesLen < Shake256MinBytesRequired {
errMsg := fmt.Sprintf("Bad keyfile provided - At least %d bytes required but got %d byte(s).", Shake256MinBytesRequired, inputBytesLen)
errorExit(errMsg)
}
sha3.ShakeSum256(hash, inputBytes)
return hex.EncodeToString(hash)
}
func init() {
rootCmd.AddCommand(configureCmd)
configureCmd.PersistentFlags().StringVar(&natsURL, "nats-url", "", "(advanced) NATS server url")
configureCmd.PersistentFlags().StringVar(&natsClusterID, "nats-cluster", "", "(advanced) NATS cluster id")
configureCmd.PersistentFlags().StringVar(&natsCaCert, "nats-cacert", "", "(advanced) Local path to CA certificate used by NATS server")
configureCmd.PersistentFlags().StringVar(&keyFile, "keyfile", "", "URL or local path to keyfile (at least 64 bytes is required)")
configureCmd.PersistentFlags().StringVar(&knownFingerprint, "fingerprint", "", "(advanced) If you know the fingerprint you want to use (SHAKE-256 hex), you can set it directly instead of using --keyfile")
configureCmd.PersistentFlags().BoolVar(&useLongName, "long-names", false, "Use standard uuid format for channel names ")
configureCmd.PersistentFlags().BoolVar(&forceWrite, "overwrite", false, "Overwrite current configuration")
}
var configureCmd = &cobra.Command{
Use: "configure",
Short: "Configure Convey",
Run: ConfigureCommandFunc,
}
// ConfigureCommandFunc is a handler for the configure command
func ConfigureCommandFunc(cmd *cobra.Command, args []string) {
var fingerprint string
if knownFingerprint != "" {
if keyFile != "" {
errorExit("Specify either --fingerprint OR --keyfile, not both.")
}
if IsValidFingerprint(knownFingerprint) {
fingerprint = knownFingerprint
} else {
errorExit(InvalidFingerprintMsg)
}
} else {
fingerprint = generateFingerprint(keyFile)
}
// Set config passed on the arguments passed in
viper.Set(configKeyFingerprint, fingerprint)
viper.Set(configKeyNatsURL, natsURL)
viper.Set(configKeyNatsClusterID, natsClusterID)
viper.Set(configKeyUseLongName, useLongName)
viper.Set(configKeyNatsCACert, natsCaCert)
// If a config file is found, read it in.
configFileExists := false
if err := viper.ReadInConfig(); err == nil {
configFileExists = true
}
// If config file doesn't exist and it hasn't been set in viper, set it
if !configFileExists && viper.ConfigFileUsed() == "" {
home, err := homedir.Dir()
if err != nil {
errorExit(err.Error())
}
viper.SetConfigFile(path.Join(home, ".convey.yaml"))
}
configFilePath := viper.ConfigFileUsed()
if forceWrite || !configFileExists {
err := viper.WriteConfigAs(configFilePath)
if err != nil {
errorExit(err.Error())
}
} else {
msg := fmt.Sprintf("Config file exists. Use --overwrite to overwrite the config file at %s", configFilePath)
errorExit(msg)
}
}