• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / deployments / 1036074718

13 Oct 2023 02:44PM UTC coverage: 78.132% (-2.8%) from 80.913%
1036074718

Pull #939

gitlab-ci

MuchoLucho
Fix: Make comment more readable for users that may end up troubleshooting
to this point

Changelog: None
Ticket: None

Signed-off-by: Luis Ramirez Vargas <luis.ramirez@northern.tech>
Pull Request #939: Fix: Make comment more readable for users

3 of 3 new or added lines in 1 file covered. (100.0%)

483 existing lines in 6 files now uncovered.

3998 of 5117 relevant lines covered (78.13%)

56.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

32.47
/config/config.go
1
// Copyright 2023 Northern.tech AS
2
//
3
//        Licensed under the Apache License, Version 2.0 (the "License");
4
//        you may not use this file except in compliance with the License.
5
//        You may obtain a copy of the License at
6
//
7
//            http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//        Unless required by applicable law or agreed to in writing, software
10
//        distributed under the License is distributed on an "AS IS" BASIS,
11
//        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//        See the License for the specific language governing permissions and
13
//        limitations under the License.
14
package config
15

16
import (
17
        "crypto/rand"
18
        "encoding/base64"
19
        "fmt"
20
        "io"
21
        "os"
22
        "strings"
23

24
        "github.com/mendersoftware/go-lib-micro/config"
25
        "github.com/mendersoftware/go-lib-micro/log"
26
        "github.com/pkg/errors"
27
)
28

29
const (
30
        EnvProd = "prod"
31
        EnvDev  = "dev"
32

33
        SettingHttps            = "https"
34
        SettingHttpsCertificate = SettingHttps + ".certificate"
35
        SettingHttpsKey         = SettingHttps + ".key"
36

37
        SettingListen        = "listen"
38
        SettingListenDefault = ":8080"
39

40
        SettingStorage = "storage"
41

42
        SettingDefaultStorage             = SettingStorage + ".default"
43
        SettingDefaultStorageDefault      = "aws"
44
        SettingStorageBucket              = SettingStorage + ".bucket"
45
        SettingStorageBucketDefault       = "mender-artifact-storage"
46
        SettingStorageMaxImageSize        = SettingStorage + ".max_image_size"
47
        SettingStorageMaxImageSizeDefault = 10 * 1024 * 1024 * 1024 // 10 GiB
48

49
        SettingStorageProxyURI = SettingStorage + ".proxy_uri"
50

51
        SettingStorageEnableDirectUpload        = SettingStorage + ".enable_direct_upload"
52
        SettingStorageEnableDirectUploadDefault = false
53

54
        SettingStorageDirectUploadSkipVerify        = SettingStorage + ".direct_upload_skip_verify"
55
        SettingStorageDirectUploadSkipVerifyDefault = false
56

57
        SettingsStorageDownloadExpireSeconds        = SettingStorage + ".download_expire_seconds"
58
        SettingsStorageDownloadExpireSecondsDefault = 900
59
        SettingsStorageUploadExpireSeconds          = SettingStorage + ".upload_expire_seconds"
60
        SettingsStorageUploadExpireSecondsDefault   = 3600
61

62
        SettingsAws                       = "aws"
63
        SettingAwsS3Region                = SettingsAws + ".region"
64
        SettingAwsS3RegionDefault         = "us-east-1"
65
        SettingAwsS3ForcePathStyle        = SettingsAws + ".force_path_style"
66
        SettingAwsS3ForcePathStyleDefault = true
67
        SettingAwsS3UseAccelerate         = SettingsAws + ".use_accelerate"
68
        SettingAwsS3UseAccelerateDefault  = false
69
        SettingAwsURI                     = SettingsAws + ".uri"
70
        SettingAwsExternalURI             = SettingsAws + ".external_uri"
71
        SettingAwsUnsignedHeaders         = SettingsAws + ".unsigned_headers"
72
        SettingAwsUnsignedHeadersDefault  = "Accept-Encoding"
73

74
        SettingsAwsTagArtifact        = SettingsAws + ".tag_artifact"
75
        SettingsAwsTagArtifactDefault = false
76

77
        SettingsAwsAuth      = SettingsAws + ".auth"
78
        SettingAwsAuthKeyId  = SettingsAwsAuth + ".key"
79
        SettingAwsAuthSecret = SettingsAwsAuth + ".secret"
80
        SettingAwsAuthToken  = SettingsAwsAuth + ".token"
81

82
        SettingAzure                    = "azure"
83
        SettingAzureAuth                = SettingAzure + ".auth"
84
        SettingAzureConnectionString    = SettingAzureAuth + ".connection_string"
85
        SettingAzureSharedKey           = SettingAzureAuth + ".shared_key"
86
        SettingAzureSharedKeyAccount    = SettingAzureSharedKey + ".account_name"
87
        SettingAzureSharedKeyAccountKey = SettingAzureSharedKey + ".account_key"
88
        SettingAzureSharedKeyURI        = SettingAzureSharedKey + ".uri"
89

90
        SettingMongo        = "mongo-url"
91
        SettingMongoDefault = "mongodb://mongo-deployments:27017"
92

93
        SettingDbSSL        = "mongo_ssl"
94
        SettingDbSSLDefault = false
95

96
        SettingDbSSLSkipVerify        = "mongo_ssl_skipverify"
97
        SettingDbSSLSkipVerifyDefault = false
98

99
        SettingDbUsername = "mongo_username"
100
        SettingDbPassword = "mongo_password"
101

102
        SettingWorkflows        = "mender-workflows"
103
        SettingWorkflowsDefault = "http://mender-workflows-server:8080"
104

105
        SettingMiddleware        = "middleware"
106
        SettingMiddlewareDefault = EnvProd
107

108
        SettingInventoryAddr        = "inventory_addr"
109
        SettingInventoryAddrDefault = "http://mender-inventory:8080"
110

111
        SettingReportingAddr        = "reporting_addr"
112
        SettingReportingAddrDefault = ""
113

114
        SettingInventoryTimeout        = "inventory_timeout"
115
        SettingInventoryTimeoutDefault = 10
116

117
        // SettingPresignAlgorithm sets the algorithm used for signing
118
        // downloadable URLs. This option is currently ignored.
119
        SettingPresignAlgorithm        = "presign.algorithm"
120
        SettingPresignAlgorithmDefault = "HMAC256"
121

122
        // SettingPresignSecret sets the secret for generating signed url.
123
        // For HMAC type of algorithms the value must be a base64 encoded
124
        // secret. For public key signatures, the value must be a path to
125
        // the private key (not yet supported).
126
        SettingPresignSecret        = "presign.secret"
127
        SettingPresignSecretDefault = ""
128

129
        // SettingPresignExpireSeconds sets the amount of seconds it takes for
130
        // the signed URL to expire.
131
        SettingPresignExpireSeconds        = "presign.expire_seconds"
132
        SettingPresignExpireSecondsDefault = 900
133

134
        // SettingPresignHost sets the URL hostname (pointing to the gateway)
135
        // for the generated URL. If the configuration option is left blank
136
        // (default), it will try to use the X-Forwarded-Host header forwarded
137
        // by the proxy.
138
        SettingPresignHost        = "presign.url_hostname"
139
        SettingPresignHostDefault = ""
140

141
        // SettingPresignURLScheme sets the URL scheme used for generating the
142
        // pre-signed url.
143
        SettingPresignScheme        = "presign.url_scheme"
144
        SettingPresignSchemeDefault = "https"
145
)
146

147
const (
148
        StorageTypeAWS   = "aws"
149
        StorageTypeAzure = "azure"
150
)
151

152
const (
153
        deprecatedSettingAwsS3Bucket               = SettingsAws + ".bucket"
154
        deprecatedSettingAwsS3MaxImageSize         = SettingsAws + ".max_image_size"
155
        deprecatedSettingsAwsDownloadExpireSeconds = SettingsAws + ".download_expire_seconds"
156
        deprecatedSettingsAwsUploadExpireSeconds   = SettingsAws + ".upload_expire_seconds"
157
)
158

159
// ValidateAwsAuth validates configuration of SettingsAwsAuth section if provided.
160
func ValidateAwsAuth(c config.Reader) error {
1✔
161

1✔
162
        if c.IsSet(SettingsAwsAuth) {
1✔
UNCOV
163
                required := []string{SettingAwsAuthKeyId, SettingAwsAuthSecret}
×
UNCOV
164
                for _, key := range required {
×
UNCOV
165
                        if !c.IsSet(key) {
×
UNCOV
166
                                return MissingOptionError(key)
×
UNCOV
167
                        }
×
168

169
                        if c.GetString(key) == "" {
×
170
                                return MissingOptionError(key)
×
171
                        }
×
172
                }
173
        }
174

175
        return nil
1✔
176
}
177

178
// ValidateHttps validates configuration of SettingHttps section if provided.
179
func ValidateHttps(c config.Reader) error {
1✔
180

1✔
181
        if c.IsSet(SettingHttps) {
1✔
UNCOV
182
                required := []string{SettingHttpsCertificate, SettingHttpsKey}
×
UNCOV
183
                for _, key := range required {
×
UNCOV
184
                        if !c.IsSet(key) {
×
UNCOV
185
                                return MissingOptionError(key)
×
UNCOV
186
                        }
×
187

188
                        value := c.GetString(key)
×
189
                        if value == "" {
×
190
                                return MissingOptionError(key)
×
191
                        }
×
192

UNCOV
193
                        if _, err := os.Stat(value); err != nil {
×
194
                                return err
×
195
                        }
×
196
                }
197
        }
198

199
        return nil
1✔
200
}
201

202
func ValidateStorage(c config.Reader) error {
1✔
203
        svc := c.GetString(SettingDefaultStorage)
1✔
204
        if svc != StorageTypeAWS && svc != StorageTypeAzure {
1✔
UNCOV
205
                return fmt.Errorf(
×
UNCOV
206
                        `setting "%s" (%s) must be one of "aws" or "azure"`,
×
UNCOV
207
                        SettingDefaultStorage, svc,
×
UNCOV
208
                )
×
UNCOV
209
        }
×
210
        return nil
1✔
211
}
212

213
// Generate error with missing required option message.
214
func MissingOptionError(option string) error {
×
215
        return fmt.Errorf("Required option: '%s'", option)
×
UNCOV
216
}
×
217

218
func applyAliases() {
1✔
219
        for _, alias := range Aliases {
2✔
220
                if config.Config.IsSet(alias.Alias) {
1✔
221
                        config.Config.Set(alias.Key, config.Config.Get(alias.Alias))
×
222
                }
×
223
        }
224
}
225

226
func Setup(configPath string) error {
1✔
227
        err := config.FromConfigFile(configPath, Defaults)
1✔
228
        if err != nil {
1✔
UNCOV
229
                return fmt.Errorf("error loading configuration: %s", err)
×
UNCOV
230
        }
×
231

232
        // Enable setting config values by environment variables
233
        config.Config.SetEnvPrefix("DEPLOYMENTS")
1✔
234
        config.Config.AutomaticEnv()
1✔
235
        config.Config.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
1✔
236
        if err := config.ValidateConfig(config.Config, Validators...); err != nil {
1✔
UNCOV
237
                return errors.WithMessage(err, "config: error validating configuration")
×
UNCOV
238
        }
×
239
        if config.Config.Get(SettingPresignSecret) == "" {
1✔
UNCOV
240
                log.NewEmpty().Warnf("'%s' not configured. Generating a random secret.",
×
UNCOV
241
                        SettingPresignSecret,
×
UNCOV
242
                )
×
243
                var buf [32]byte
×
244
                n, err := io.ReadFull(rand.Reader, buf[:])
×
UNCOV
245
                if err != nil {
×
246
                        return errors.WithMessagef(err,
×
247
                                "failed to generate '%s'",
×
248
                                SettingPresignSecret,
×
249
                        )
×
250
                } else if n == 0 {
×
251
                        return errors.Errorf(
×
252
                                "failed to generate '%s'",
×
253
                                SettingPresignSecret,
×
254
                        )
×
255
                }
×
256
                secret := base64.StdEncoding.EncodeToString(buf[:n])
×
257
                config.Config.Set(SettingPresignSecret, secret)
×
258
        }
259
        applyAliases()
1✔
260
        return nil
1✔
261
}
262

263
var (
264
        Validators = []config.Validator{ValidateAwsAuth, ValidateHttps, ValidateStorage}
265
        // Aliases for deprecated configuration names to preserve backward compatibility.
266
        Aliases = []struct {
267
                Key   string
268
                Alias string
269
        }{
270
                {Key: SettingStorageBucket, Alias: deprecatedSettingAwsS3Bucket},
271
                {Key: SettingsStorageDownloadExpireSeconds,
272
                        Alias: deprecatedSettingsAwsDownloadExpireSeconds},
273
                {Key: SettingsStorageUploadExpireSeconds, Alias: deprecatedSettingsAwsUploadExpireSeconds},
274
                {Key: SettingStorageMaxImageSize, Alias: deprecatedSettingAwsS3MaxImageSize},
275
        }
276

277
        Defaults = []config.Default{
278
                {Key: SettingListen, Value: SettingListenDefault},
279
                {Key: SettingDefaultStorage, Value: SettingDefaultStorageDefault},
280
                {Key: SettingAwsS3Region, Value: SettingAwsS3RegionDefault},
281
                {Key: SettingStorageBucket, Value: SettingStorageBucketDefault},
282
                {Key: SettingStorageDirectUploadSkipVerify,
283
                        Value: SettingStorageDirectUploadSkipVerifyDefault},
284
                {Key: SettingStorageEnableDirectUpload, Value: SettingStorageEnableDirectUploadDefault},
285
                {Key: SettingAwsS3ForcePathStyle, Value: SettingAwsS3ForcePathStyleDefault},
286
                {Key: SettingAwsS3UseAccelerate, Value: SettingAwsS3UseAccelerateDefault},
287
                {Key: SettingAwsUnsignedHeaders, Value: SettingAwsUnsignedHeadersDefault},
288
                {Key: SettingStorageMaxImageSize, Value: SettingStorageMaxImageSizeDefault},
289
                {Key: SettingsStorageDownloadExpireSeconds,
290
                        Value: SettingsStorageDownloadExpireSecondsDefault},
291
                {Key: SettingsStorageUploadExpireSeconds, Value: SettingsStorageUploadExpireSecondsDefault},
292
                {Key: SettingMongo, Value: SettingMongoDefault},
293
                {Key: SettingDbSSL, Value: SettingDbSSLDefault},
294
                {Key: SettingDbSSLSkipVerify, Value: SettingDbSSLSkipVerifyDefault},
295
                {Key: SettingWorkflows, Value: SettingWorkflowsDefault},
296
                {Key: SettingsAwsTagArtifact, Value: SettingsAwsTagArtifactDefault},
297
                {Key: SettingInventoryAddr, Value: SettingInventoryAddrDefault},
298
                {Key: SettingReportingAddr, Value: SettingReportingAddrDefault},
299
                {Key: SettingInventoryTimeout, Value: SettingInventoryTimeoutDefault},
300
                {Key: SettingPresignAlgorithm, Value: SettingPresignAlgorithmDefault},
301
                {Key: SettingPresignSecret, Value: SettingPresignSecretDefault},
302
                {Key: SettingPresignExpireSeconds, Value: SettingPresignExpireSecondsDefault},
303
                {Key: SettingPresignHost, Value: SettingPresignHostDefault},
304
                {Key: SettingPresignScheme, Value: SettingPresignSchemeDefault},
305
        }
306
)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc