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

mendersoftware / mender-server / 1495380963

14 Oct 2024 03:35PM UTC coverage: 70.373% (-2.5%) from 72.904%
1495380963

Pull #101

gitlab-ci

mineralsfree
feat: tenant list added

Ticket: MEN-7568
Changelog: None

Signed-off-by: Mikita Pilinka <mikita.pilinka@northern.tech>
Pull Request #101: feat: tenant list added

4406 of 6391 branches covered (68.94%)

Branch coverage included in aggregate %.

88 of 183 new or added lines in 10 files covered. (48.09%)

2623 existing lines in 65 files now uncovered.

36673 of 51982 relevant lines covered (70.55%)

31.07 hits per line

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

0.0
/backend/services/deployments/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/pkg/errors"
25

26
        "github.com/mendersoftware/mender-server/pkg/config"
27
        "github.com/mendersoftware/mender-server/pkg/log"
28
)
29

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

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

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

41
        SettingStorage = "storage"
42

43
        SettingDefaultStorage                = SettingStorage + ".default"
44
        SettingDefaultStorageDefault         = "aws"
45
        SettingStorageBucket                 = SettingStorage + ".bucket"
46
        SettingStorageBucketDefault          = "mender-artifact-storage"
47
        SettingStorageMaxImageSize           = SettingStorage + ".max_image_size"
48
        SettingStorageMaxImageSizeDefault    = 10 * 1024 * 1024 * 1024 // 10 GiB
49
        SettingStorageMaxGenerateSize        = SettingStorage + ".max_generate_data_size"
50
        SettingStorageMaxGenerateSizeDefault = 512 * 1024 * 1024 // 512 MiB
51

52
        SettingStorageProxyURI = SettingStorage + ".proxy_uri"
53

54
        SettingStorageEnableDirectUpload        = SettingStorage + ".enable_direct_upload"
55
        SettingStorageEnableDirectUploadDefault = false
56

57
        SettingStorageDirectUploadSkipVerify        = SettingStorage + ".direct_upload_skip_verify"
58
        SettingStorageDirectUploadSkipVerifyDefault = false
59

60
        SettingsStorageDownloadExpireSeconds        = SettingStorage + ".download_expire_seconds"
61
        SettingsStorageDownloadExpireSecondsDefault = 900
62
        SettingsStorageUploadExpireSeconds          = SettingStorage + ".upload_expire_seconds"
63
        SettingsStorageUploadExpireSecondsDefault   = 3600
64

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

77
        SettingsAwsTagArtifact        = SettingsAws + ".tag_artifact"
78
        SettingsAwsTagArtifactDefault = false
79

80
        SettingsAwsAuth      = SettingsAws + ".auth"
81
        SettingAwsAuthKeyId  = SettingsAwsAuth + ".key"
82
        SettingAwsAuthSecret = SettingsAwsAuth + ".secret"
83
        SettingAwsAuthToken  = SettingsAwsAuth + ".token"
84

85
        SettingAzure                    = "azure"
86
        SettingAzureAuth                = SettingAzure + ".auth"
87
        SettingAzureConnectionString    = SettingAzureAuth + ".connection_string"
88
        SettingAzureSharedKey           = SettingAzureAuth + ".shared_key"
89
        SettingAzureSharedKeyAccount    = SettingAzureSharedKey + ".account_name"
90
        SettingAzureSharedKeyAccountKey = SettingAzureSharedKey + ".account_key"
91
        SettingAzureSharedKeyURI        = SettingAzureSharedKey + ".uri"
92

93
        SettingMongo        = "mongo-url"
94
        SettingMongoDefault = "mongodb://mongo-deployments:27017"
95

96
        SettingDbSSL        = "mongo_ssl"
97
        SettingDbSSLDefault = false
98

99
        SettingDbSSLSkipVerify        = "mongo_ssl_skipverify"
100
        SettingDbSSLSkipVerifyDefault = false
101

102
        SettingDbUsername = "mongo_username"
103
        SettingDbPassword = "mongo_password"
104

105
        SettingWorkflows        = "mender-workflows"
106
        SettingWorkflowsDefault = "http://mender-workflows-server:8080"
107

108
        SettingMiddleware        = "middleware"
109
        SettingMiddlewareDefault = EnvProd
110

111
        SettingInventoryAddr        = "inventory_addr"
112
        SettingInventoryAddrDefault = "http://mender-inventory:8080"
113

114
        SettingReportingAddr        = "reporting_addr"
115
        SettingReportingAddrDefault = ""
116

117
        SettingInventoryTimeout        = "inventory_timeout"
118
        SettingInventoryTimeoutDefault = 10
119

120
        // SettingPresignAlgorithm sets the algorithm used for signing
121
        // downloadable URLs. This option is currently ignored.
122
        SettingPresignAlgorithm        = "presign.algorithm"
123
        SettingPresignAlgorithmDefault = "HMAC256"
124

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

132
        // SettingPresignExpireSeconds sets the amount of seconds it takes for
133
        // the signed URL to expire.
134
        SettingPresignExpireSeconds        = "presign.expire_seconds"
135
        SettingPresignExpireSecondsDefault = 900
136

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

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

149
        // SettingDisableNewReleasesFeature is a flag that turns off the new API end-points
150
        // related to releases; helpful in performing long-running maintenance and data
151
        // migrations on the artifacts and releases collections.
152
        SettingDisableNewReleasesFeature        = "disable_new_releases_feature"
153
        SettingDisableNewReleasesFeatureDefault = false
154
)
155

156
const (
157
        StorageTypeAWS   = "aws"
158
        StorageTypeAzure = "azure"
159
)
160

161
const (
162
        deprecatedSettingAwsS3Bucket               = SettingsAws + ".bucket"
163
        deprecatedSettingAwsS3MaxImageSize         = SettingsAws + ".max_image_size"
164
        deprecatedSettingsAwsDownloadExpireSeconds = SettingsAws + ".download_expire_seconds"
165
        deprecatedSettingsAwsUploadExpireSeconds   = SettingsAws + ".upload_expire_seconds"
166
)
167

168
// ValidateAwsAuth validates configuration of SettingsAwsAuth section if provided.
UNCOV
169
func ValidateAwsAuth(c config.Reader) error {
×
UNCOV
170

×
UNCOV
171
        if c.IsSet(SettingsAwsAuth) {
×
172
                required := []string{SettingAwsAuthKeyId, SettingAwsAuthSecret}
×
173
                for _, key := range required {
×
174
                        if !c.IsSet(key) {
×
175
                                return MissingOptionError(key)
×
176
                        }
×
177

178
                        if c.GetString(key) == "" {
×
179
                                return MissingOptionError(key)
×
180
                        }
×
181
                }
182
        }
183

UNCOV
184
        return nil
×
185
}
186

187
// ValidateHttps validates configuration of SettingHttps section if provided.
UNCOV
188
func ValidateHttps(c config.Reader) error {
×
UNCOV
189

×
UNCOV
190
        if c.IsSet(SettingHttps) {
×
191
                required := []string{SettingHttpsCertificate, SettingHttpsKey}
×
192
                for _, key := range required {
×
193
                        if !c.IsSet(key) {
×
194
                                return MissingOptionError(key)
×
195
                        }
×
196

197
                        value := c.GetString(key)
×
198
                        if value == "" {
×
199
                                return MissingOptionError(key)
×
200
                        }
×
201

202
                        if _, err := os.Stat(value); err != nil {
×
203
                                return err
×
204
                        }
×
205
                }
206
        }
207

UNCOV
208
        return nil
×
209
}
210

UNCOV
211
func ValidateStorage(c config.Reader) error {
×
UNCOV
212
        svc := c.GetString(SettingDefaultStorage)
×
UNCOV
213
        if svc != StorageTypeAWS && svc != StorageTypeAzure {
×
214
                return fmt.Errorf(
×
215
                        `setting "%s" (%s) must be one of "aws" or "azure"`,
×
216
                        SettingDefaultStorage, svc,
×
217
                )
×
218
        }
×
UNCOV
219
        return nil
×
220
}
221

222
// Generate error with missing required option message.
223
func MissingOptionError(option string) error {
×
224
        return fmt.Errorf("Required option: '%s'", option)
×
225
}
×
226

UNCOV
227
func applyAliases() {
×
UNCOV
228
        for _, alias := range Aliases {
×
UNCOV
229
                if config.Config.IsSet(alias.Alias) {
×
230
                        config.Config.Set(alias.Key, config.Config.Get(alias.Alias))
×
231
                }
×
232
        }
233
}
234

UNCOV
235
func Setup(configPath string) error {
×
UNCOV
236
        err := config.FromConfigFile(configPath, Defaults)
×
UNCOV
237
        if err != nil {
×
238
                return fmt.Errorf("error loading configuration: %s", err)
×
239
        }
×
240

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

272
var (
273
        Validators = []config.Validator{ValidateAwsAuth, ValidateHttps, ValidateStorage}
274
        // Aliases for deprecated configuration names to preserve backward compatibility.
275
        Aliases = []struct {
276
                Key   string
277
                Alias string
278
        }{
279
                {Key: SettingStorageBucket, Alias: deprecatedSettingAwsS3Bucket},
280
                {Key: SettingsStorageDownloadExpireSeconds,
281
                        Alias: deprecatedSettingsAwsDownloadExpireSeconds},
282
                {Key: SettingsStorageUploadExpireSeconds, Alias: deprecatedSettingsAwsUploadExpireSeconds},
283
                {Key: SettingStorageMaxImageSize, Alias: deprecatedSettingAwsS3MaxImageSize},
284
        }
285

286
        Defaults = []config.Default{
287
                {Key: SettingListen, Value: SettingListenDefault},
288
                {Key: SettingDefaultStorage, Value: SettingDefaultStorageDefault},
289
                {Key: SettingAwsS3Region, Value: SettingAwsS3RegionDefault},
290
                {Key: SettingStorageBucket, Value: SettingStorageBucketDefault},
291
                {Key: SettingStorageDirectUploadSkipVerify,
292
                        Value: SettingStorageDirectUploadSkipVerifyDefault},
293
                {Key: SettingStorageEnableDirectUpload, Value: SettingStorageEnableDirectUploadDefault},
294
                {Key: SettingAwsS3ForcePathStyle, Value: SettingAwsS3ForcePathStyleDefault},
295
                {Key: SettingAwsS3UseAccelerate, Value: SettingAwsS3UseAccelerateDefault},
296
                {Key: SettingAwsUnsignedHeaders, Value: SettingAwsUnsignedHeadersDefault},
297
                {Key: SettingStorageMaxImageSize, Value: SettingStorageMaxImageSizeDefault},
298
                {Key: SettingStorageMaxGenerateSize, Value: SettingStorageMaxGenerateSizeDefault},
299
                {Key: SettingsStorageDownloadExpireSeconds,
300
                        Value: SettingsStorageDownloadExpireSecondsDefault},
301
                {Key: SettingsStorageUploadExpireSeconds, Value: SettingsStorageUploadExpireSecondsDefault},
302
                {Key: SettingMongo, Value: SettingMongoDefault},
303
                {Key: SettingDbSSL, Value: SettingDbSSLDefault},
304
                {Key: SettingDbSSLSkipVerify, Value: SettingDbSSLSkipVerifyDefault},
305
                {Key: SettingWorkflows, Value: SettingWorkflowsDefault},
306
                {Key: SettingsAwsTagArtifact, Value: SettingsAwsTagArtifactDefault},
307
                {Key: SettingInventoryAddr, Value: SettingInventoryAddrDefault},
308
                {Key: SettingReportingAddr, Value: SettingReportingAddrDefault},
309
                {Key: SettingInventoryTimeout, Value: SettingInventoryTimeoutDefault},
310
                {Key: SettingPresignAlgorithm, Value: SettingPresignAlgorithmDefault},
311
                {Key: SettingPresignSecret, Value: SettingPresignSecretDefault},
312
                {Key: SettingPresignExpireSeconds, Value: SettingPresignExpireSecondsDefault},
313
                {Key: SettingPresignHost, Value: SettingPresignHostDefault},
314
                {Key: SettingPresignScheme, Value: SettingPresignSchemeDefault},
315
                {Key: SettingDisableNewReleasesFeature, Value: SettingDisableNewReleasesFeatureDefault},
316
        }
317
)
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