-
Notifications
You must be signed in to change notification settings - Fork 84
Expand file tree
/
Copy pathconfig.go
More file actions
191 lines (166 loc) · 5.18 KB
/
config.go
File metadata and controls
191 lines (166 loc) · 5.18 KB
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
package config
import (
"os"
"path/filepath"
"testing"
. "github.com/microsoft/go-sqlcmd/cmd/modern/sqlconfig"
"github.com/microsoft/go-sqlcmd/internal/io/file"
"github.com/microsoft/go-sqlcmd/internal/io/folder"
"github.com/microsoft/go-sqlcmd/internal/pal"
)
var config Sqlconfig
var filename string
// SetFileName sets the filename for the file that the application reads from and
// writes to. The file is created if it does not already exist, and Viper is configured
// to use the given filename.
func SetFileName(name string) {
if name == "" {
panic("name is empty")
}
filename = name
// Validate extension before creating the file
err := validateConfigFileExtension(filename)
checkErr(err)
file.CreateEmptyIfNotExists(filename)
err = configureViper(filename)
checkErr(err)
}
func SetFileNameForTest(t *testing.T) {
SetFileName(pal.FilenameInUserHomeDotDirectory(
".sqlcmd", "sqlconfig-"+t.Name()))
}
// DefaultFileName returns the default filename for the file that the application
// reads from and writes to. This is typically located in the user's home directory
// under the ".sqlcmd" directory. If an error occurs while attempting to retrieve
// the user's home directory, the function will return an empty string.
func DefaultFileName() (filename string) {
home, err := os.UserHomeDir()
if err != nil {
trace(
"Error getting user's home directory: %v, will use current directory %q as default",
err,
folder.Getwd(),
)
home = "."
}
filename = filepath.Join(home, ".sqlcmd", "sqlconfig")
return
}
// Clean resets the application's configuration by setting the Users, Contexts,
// and Endpoints fields to nil, the CurrentContext field to an empty string,
// and saving the updated configuration. This effectively resets the configuration
// to its initial state.
func Clean() {
config.Users = nil
config.Contexts = nil
config.Endpoints = nil
config.CurrentContext = ""
Save()
}
// IsEmpty returns a boolean indicating whether the application's configuration
// is empty. The configuration is considered empty if all of the following fields
// are empty or zero-valued: Users, Contexts, Endpoints, and CurrentContext.
// This function can be used to determine whether the configuration has been
// initialized or reset.
func IsEmpty() (isEmpty bool) {
if len(config.Users) == 0 &&
len(config.Contexts) == 0 &&
len(config.Endpoints) == 0 &&
config.CurrentContext == "" {
isEmpty = true
}
return
}
// AddContextWithContainer adds a new context to the application's configuration
// with the given parameters. The context is associated with a container
// identified by its container ID. If any of the required parameters (i.e. containerId,
// imageName, portNumber, username, password, contextName) are empty or
// zero-valued, the function will panic. The function also ensures that the given
// contextName and username are unique, and it encrypts the password if
// requested. The updated configuration is saved to file.
func AddContextWithContainer(
contextName string,
imageName string,
portNumber int,
containerId string,
username string,
password string,
passwordEncryption string,
) {
if containerId == "" {
panic("containerId must be provided")
}
if imageName == "" {
panic("imageName must be provided")
}
if portNumber == 0 {
panic("portNumber must be non-zero")
}
if username == "" {
panic("username must be provided")
}
if password == "" {
panic("password must be provided")
}
if contextName == "" {
panic("contextName must be provided")
}
contextName = FindUniqueContextName(contextName, username)
endPointName := FindUniqueEndpointName(contextName)
userName := username + "@" + contextName
config.CurrentContext = contextName
config.Endpoints = append(config.Endpoints, Endpoint{
AssetDetails: &AssetDetails{
ContainerDetails: &ContainerDetails{
Id: containerId,
Image: imageName},
},
EndpointDetails: EndpointDetails{
Address: "127.0.0.1",
Port: portNumber,
},
Name: endPointName,
})
config.Contexts = append(config.Contexts, Context{
ContextDetails: ContextDetails{
Endpoint: endPointName,
User: &userName,
},
Name: contextName,
})
user := User{
AuthenticationType: "basic",
BasicAuth: &BasicAuthDetails{
Username: username,
PasswordEncryption: passwordEncryption,
Password: encryptCallback(password, passwordEncryption),
},
Name: userName,
}
config.Users = append(config.Users, user)
Save()
}
// RedactedConfig function returns a Sqlconfig struct with the Users field
// having their BasicAuth password field either replaced with the decrypted
// password or the string "REDACTED", depending on the value of the raw
// parameter. This allows the caller to either get the full password or a
// redacted version, where the password is hidden.
func RedactedConfig(raw bool) (c Sqlconfig) {
c = config
for i := range c.Users {
user := c.Users[i]
if user.AuthenticationType == "basic" {
if raw {
user.BasicAuth.Password = decryptCallback(
user.BasicAuth.Password,
user.BasicAuth.PasswordEncryption,
)
} else {
user.BasicAuth.Password = "REDACTED"
}
}
}
return
}