• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In
Build has been set to done!

mendersoftware / deployments / 876611228

pending completion
876611228

push

gitlab-ci

GitHub
Merge pull request #864 from merlin-northern/men_6474_skip_verify_flag

65 of 70 new or added lines in 4 files covered. (92.86%)

512 existing lines in 6 files now uncovered.

7094 of 8937 relevant lines covered (79.38%)

69.35 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
        SettingStorageEnableDirectUpload        = SettingStorage + ".enable_direct_upload"
50
        SettingStorageEnableDirectUploadDefault = false
51

52
        SettingStorageDirectUploadSkipVerify        = SettingStorage + ".direct_upload_skip_verify"
53
        SettingStorageDirectUploadSkipVerifyDefault = false
54

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

60
        SettingsAws                       = "aws"
61
        SettingAwsS3Region                = SettingsAws + ".region"
62
        SettingAwsS3RegionDefault         = "us-east-1"
63
        SettingAwsS3ForcePathStyle        = SettingsAws + ".force_path_style"
64
        SettingAwsS3ForcePathStyleDefault = true
65
        SettingAwsS3UseAccelerate         = SettingsAws + ".use_accelerate"
66
        SettingAwsS3UseAccelerateDefault  = false
67
        SettingAwsURI                     = SettingsAws + ".uri"
68
        SettingAwsExternalURI             = SettingsAws + ".external_uri"
69
        SettingsAwsTagArtifact            = SettingsAws + ".tag_artifact"
70
        SettingsAwsTagArtifactDefault     = false
71

72
        SettingsAwsAuth      = SettingsAws + ".auth"
73
        SettingAwsAuthKeyId  = SettingsAwsAuth + ".key"
74
        SettingAwsAuthSecret = SettingsAwsAuth + ".secret"
75
        SettingAwsAuthToken  = SettingsAwsAuth + ".token"
76

77
        SettingAzure                    = "azure"
78
        SettingAzureAuth                = SettingAzure + ".auth"
79
        SettingAzureConnectionString    = SettingAzureAuth + ".connection_string"
80
        SettingAzureSharedKey           = SettingAzureAuth + ".shared_key"
81
        SettingAzureSharedKeyAccount    = SettingAzureSharedKey + ".account_name"
82
        SettingAzureSharedKeyAccountKey = SettingAzureSharedKey + ".account_key"
83
        SettingAzureSharedKeyURI        = SettingAzureSharedKey + ".uri"
84

85
        SettingMongo        = "mongo-url"
86
        SettingMongoDefault = "mongodb://mongo-deployments:27017"
87

88
        SettingDbSSL        = "mongo_ssl"
89
        SettingDbSSLDefault = false
90

91
        SettingDbSSLSkipVerify        = "mongo_ssl_skipverify"
92
        SettingDbSSLSkipVerifyDefault = false
93

94
        SettingDbUsername = "mongo_username"
95
        SettingDbPassword = "mongo_password"
96

97
        SettingWorkflows        = "mender-workflows"
98
        SettingWorkflowsDefault = "http://mender-workflows-server:8080"
99

100
        SettingMiddleware        = "middleware"
101
        SettingMiddlewareDefault = EnvProd
102

103
        SettingInventoryAddr        = "inventory_addr"
104
        SettingInventoryAddrDefault = "http://mender-inventory:8080"
105

106
        SettingReportingAddr        = "reporting_addr"
107
        SettingReportingAddrDefault = ""
108

109
        SettingInventoryTimeout        = "inventory_timeout"
110
        SettingInventoryTimeoutDefault = 10
111

112
        // SettingPresignAlgorithm sets the algorithm used for signing
113
        // downloadable URLs. This option is currently ignored.
114
        SettingPresignAlgorithm        = "presign.algorithm"
115
        SettingPresignAlgorithmDefault = "HMAC256"
116

117
        // SettingPresignSecret sets the secret for generating signed url.
118
        // For HMAC type of algorithms the value must be a base64 encoded
119
        // secret. For public key signatures, the value must be a path to
120
        // the private key (not yet supported).
121
        SettingPresignSecret        = "presign.secret"
122
        SettingPresignSecretDefault = ""
123

124
        // SettingPresignExpireSeconds sets the amount of seconds it takes for
125
        // the signed URL to expire.
126
        SettingPresignExpireSeconds        = "presign.expire_seconds"
127
        SettingPresignExpireSecondsDefault = 900
128

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

136
        // SettingPresignURLScheme sets the URL scheme used for generating the
137
        // pre-signed url.
138
        SettingPresignScheme        = "presign.url_scheme"
139
        SettingPresignSchemeDefault = "https"
140
)
141

142
const (
143
        StorageTypeAWS   = "aws"
144
        StorageTypeAzure = "azure"
145
)
146

147
const (
148
        deprecatedSettingAwsS3Bucket               = SettingsAws + ".bucket"
149
        deprecatedSettingAwsS3MaxImageSize         = SettingsAws + ".max_image_size"
150
        deprecatedSettingsAwsDownloadExpireSeconds = SettingsAws + ".download_expire_seconds"
151
        deprecatedSettingsAwsUploadExpireSeconds   = SettingsAws + ".upload_expire_seconds"
152
)
153

154
// ValidateAwsAuth validates configuration of SettingsAwsAuth section if provided.
155
func ValidateAwsAuth(c config.Reader) error {
1✔
156

1✔
157
        if c.IsSet(SettingsAwsAuth) {
1✔
UNCOV
158
                required := []string{SettingAwsAuthKeyId, SettingAwsAuthSecret}
×
UNCOV
159
                for _, key := range required {
×
UNCOV
160
                        if !c.IsSet(key) {
×
161
                                return MissingOptionError(key)
×
162
                        }
×
163

164
                        if c.GetString(key) == "" {
×
165
                                return MissingOptionError(key)
×
UNCOV
166
                        }
×
167
                }
168
        }
169

170
        return nil
1✔
171
}
172

173
// ValidateHttps validates configuration of SettingHttps section if provided.
174
func ValidateHttps(c config.Reader) error {
1✔
175

1✔
176
        if c.IsSet(SettingHttps) {
1✔
UNCOV
177
                required := []string{SettingHttpsCertificate, SettingHttpsKey}
×
UNCOV
178
                for _, key := range required {
×
UNCOV
179
                        if !c.IsSet(key) {
×
180
                                return MissingOptionError(key)
×
181
                        }
×
182

183
                        value := c.GetString(key)
×
184
                        if value == "" {
×
UNCOV
185
                                return MissingOptionError(key)
×
186
                        }
×
187

188
                        if _, err := os.Stat(value); err != nil {
×
189
                                return err
×
UNCOV
190
                        }
×
191
                }
192
        }
193

194
        return nil
1✔
195
}
196

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

208
// Generate error with missing required option message.
UNCOV
209
func MissingOptionError(option string) error {
×
UNCOV
210
        return fmt.Errorf("Required option: '%s'", option)
×
UNCOV
211
}
×
212

213
func applyAliases() {
1✔
214
        for _, alias := range Aliases {
2✔
215
                if config.Config.IsSet(alias.Alias) {
1✔
UNCOV
216
                        config.Config.Set(alias.Key, config.Config.Get(alias.Alias))
×
UNCOV
217
                }
×
218
        }
219
}
220

221
func Setup(configPath string) error {
1✔
222
        err := config.FromConfigFile(configPath, Defaults)
1✔
223
        if err != nil {
1✔
UNCOV
224
                return fmt.Errorf("error loading configuration: %s", err)
×
UNCOV
225
        }
×
226

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

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

272
        Defaults = []config.Default{
273
                {Key: SettingListen, Value: SettingListenDefault},
274
                {Key: SettingDefaultStorage, Value: SettingDefaultStorageDefault},
275
                {Key: SettingAwsS3Region, Value: SettingAwsS3RegionDefault},
276
                {Key: SettingStorageBucket, Value: SettingStorageBucketDefault},
277
                {Key: SettingStorageDirectUploadSkipVerify,
278
                        Value: SettingStorageDirectUploadSkipVerifyDefault},
279
                {Key: SettingStorageEnableDirectUpload, Value: SettingStorageEnableDirectUploadDefault},
280
                {Key: SettingAwsS3ForcePathStyle, Value: SettingAwsS3ForcePathStyleDefault},
281
                {Key: SettingAwsS3UseAccelerate, Value: SettingAwsS3UseAccelerateDefault},
282
                {Key: SettingStorageMaxImageSize, Value: SettingStorageMaxImageSizeDefault},
283
                {Key: SettingsStorageDownloadExpireSeconds,
284
                        Value: SettingsStorageDownloadExpireSecondsDefault},
285
                {Key: SettingsStorageUploadExpireSeconds, Value: SettingsStorageUploadExpireSecondsDefault},
286
                {Key: SettingMongo, Value: SettingMongoDefault},
287
                {Key: SettingDbSSL, Value: SettingDbSSLDefault},
288
                {Key: SettingDbSSLSkipVerify, Value: SettingDbSSLSkipVerifyDefault},
289
                {Key: SettingWorkflows, Value: SettingWorkflowsDefault},
290
                {Key: SettingsAwsTagArtifact, Value: SettingsAwsTagArtifactDefault},
291
                {Key: SettingInventoryAddr, Value: SettingInventoryAddrDefault},
292
                {Key: SettingReportingAddr, Value: SettingReportingAddrDefault},
293
                {Key: SettingInventoryTimeout, Value: SettingInventoryTimeoutDefault},
294
                {Key: SettingPresignAlgorithm, Value: SettingPresignAlgorithmDefault},
295
                {Key: SettingPresignSecret, Value: SettingPresignSecretDefault},
296
                {Key: SettingPresignExpireSeconds, Value: SettingPresignExpireSecondsDefault},
297
                {Key: SettingPresignHost, Value: SettingPresignHostDefault},
298
                {Key: SettingPresignScheme, Value: SettingPresignSchemeDefault},
299
        }
300
)
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