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

mendersoftware / deployments / 920043239

pending completion
920043239

Pull #872

gitlab-ci

alfrunes
chore: Restrict tag character set

Changelog: None
Signed-off-by: Alf-Rune Siqveland <alf.rune@northern.tech>
Pull Request #872: MEN-6348: Add tags to releases

220 of 229 new or added lines in 7 files covered. (96.07%)

223 existing lines in 7 files now uncovered.

7560 of 9480 relevant lines covered (79.75%)

34.07 hits per line

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

69.5
/server.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

15
package main
16

17
import (
18
        "context"
19
        "encoding/base64"
20
        "net/http"
21
        "strings"
22
        "time"
23

24
        "github.com/ant0ine/go-json-rest/rest"
25
        "github.com/pkg/errors"
26

27
        "github.com/mendersoftware/go-lib-micro/config"
28

29
        api "github.com/mendersoftware/deployments/api/http"
30
        "github.com/mendersoftware/deployments/app"
31
        "github.com/mendersoftware/deployments/client/reporting"
32
        dconfig "github.com/mendersoftware/deployments/config"
33
        "github.com/mendersoftware/deployments/storage"
34
        "github.com/mendersoftware/deployments/storage/azblob"
35
        "github.com/mendersoftware/deployments/storage/manager"
36
        "github.com/mendersoftware/deployments/storage/s3"
37
        mstore "github.com/mendersoftware/deployments/store/mongo"
38
)
39

40
func SetupS3(ctx context.Context, defaultOptions *s3.Options) (storage.ObjectStorage, error) {
1✔
41
        c := config.Config
1✔
42

1✔
43
        // Copy / merge defaultOptions
1✔
44
        options := s3.NewOptions(defaultOptions).
1✔
45
                SetForcePathStyle(c.GetBool(dconfig.SettingAwsS3ForcePathStyle)).
1✔
46
                SetUseAccelerate(c.GetBool(dconfig.SettingAwsS3UseAccelerate))
1✔
47

1✔
48
        // Compute the buffer size
1✔
49
        bucket := c.GetString(dconfig.SettingStorageBucket)
1✔
50

1✔
51
        // The following parameters falls back on AWS_* environment if not set
1✔
52
        if c.IsSet(dconfig.SettingAwsS3Region) {
2✔
53
                options.SetRegion(c.GetString(dconfig.SettingAwsS3Region))
1✔
54
        }
1✔
55
        if c.IsSet(dconfig.SettingsAwsAuth) ||
1✔
56
                (c.IsSet(dconfig.SettingAwsAuthKeyId) &&
1✔
57
                        c.IsSet(dconfig.SettingAwsAuthSecret)) {
2✔
58
                options.SetStaticCredentials(
1✔
59
                        c.GetString(dconfig.SettingAwsAuthKeyId),
1✔
60
                        c.GetString(dconfig.SettingAwsAuthSecret),
1✔
61
                        c.GetString(dconfig.SettingAwsAuthToken),
1✔
62
                )
1✔
63
        }
1✔
64
        if c.IsSet(dconfig.SettingAwsURI) {
2✔
65
                options.SetURI(c.GetString(dconfig.SettingAwsURI))
1✔
66
        }
1✔
67
        if c.IsSet(dconfig.SettingAwsExternalURI) {
2✔
68
                options.SetExternalURI(c.GetString(dconfig.SettingAwsExternalURI))
1✔
69
        }
1✔
70
        if c.IsSet(dconfig.SettingAwsUnsignedHeaders) {
2✔
71
                options.SetUnsignedHeaders(c.GetStringSlice(dconfig.SettingAwsUnsignedHeaders))
1✔
72
        }
1✔
73

74
        storage, err := s3.New(ctx, bucket, options)
1✔
75
        return storage, err
1✔
76
}
77

78
func SetupBlobStorage(
79
        ctx context.Context,
80
        defaultOptions *azblob.Options,
UNCOV
81
) (storage.ObjectStorage, error) {
×
UNCOV
82
        c := config.Config
×
UNCOV
83

×
UNCOV
84
        // Copy / merge options
×
UNCOV
85
        options := azblob.NewOptions(defaultOptions)
×
UNCOV
86

×
UNCOV
87
        if c.IsSet(dconfig.SettingAzureConnectionString) {
×
UNCOV
88
                options.SetConnectionString(c.GetString(dconfig.SettingAzureConnectionString))
×
UNCOV
89
        } else if c.IsSet(dconfig.SettingAzureSharedKeyAccount) &&
×
UNCOV
90
                c.IsSet(dconfig.SettingAzureSharedKeyAccountKey) {
×
91
                creds := azblob.SharedKeyCredentials{
×
92
                        AccountName: c.GetString(dconfig.SettingAzureSharedKeyAccount),
×
93
                        AccountKey:  c.GetString(dconfig.SettingAzureSharedKeyAccountKey),
×
94
                }
×
95
                if c.IsSet(dconfig.SettingAzureSharedKeyURI) {
×
96
                        uri := c.GetString(dconfig.SettingAzureSharedKeyURI)
×
97
                        creds.URI = &uri
×
98
                }
×
99
                options.SetSharedKey(creds)
×
100
        }
101
        return azblob.New(ctx, c.GetString(dconfig.SettingStorageBucket), options)
×
102
}
103

104
func SetupObjectStorage(ctx context.Context) (objManager storage.ObjectStorage, err error) {
1✔
105
        c := config.Config
1✔
106

1✔
107
        // Calculate s3 multipart buffer size: the minimum buffer size that
1✔
108
        // covers the maximum image size aligned to multiple of 5MiB.
1✔
109
        maxImageSize := c.GetInt64(dconfig.SettingStorageMaxImageSize)
1✔
110
        bufferSize := (((maxImageSize - 1) /
1✔
111
                (s3.MultipartMaxParts * s3.MultipartMinSize)) + 1) *
1✔
112
                s3.MultipartMinSize
1✔
113
        var (
1✔
114
                s3Options = s3.NewOptions().
1✔
115
                                SetContentType(app.ArtifactContentType).
1✔
116
                                SetBufferSize(int(bufferSize))
1✔
117
                azOptions = azblob.NewOptions().
1✔
118
                                SetContentType(app.ArtifactContentType)
1✔
119
        )
1✔
120
        var defaultStorage storage.ObjectStorage
1✔
121
        switch defType := c.GetString(dconfig.SettingDefaultStorage); defType {
1✔
122
        case dconfig.StorageTypeAWS:
1✔
123
                defaultStorage, err = SetupS3(ctx, s3Options)
1✔
UNCOV
124
        case dconfig.StorageTypeAzure:
×
UNCOV
125
                defaultStorage, err = SetupBlobStorage(ctx, azOptions)
×
UNCOV
126
        default:
×
UNCOV
127
                err = errors.Errorf(
×
UNCOV
128
                        `storage type must be one of %q or %q, received value %q`,
×
UNCOV
129
                        dconfig.StorageTypeAWS, dconfig.StorageTypeAzure, defType,
×
UNCOV
130
                )
×
131
        }
132
        if err != nil {
1✔
UNCOV
133
                return nil, err
×
UNCOV
134
        }
×
135
        return manager.New(ctx, defaultStorage, s3Options, azOptions)
1✔
136
}
137

138
func RunServer(ctx context.Context) error {
1✔
139
        c := config.Config
1✔
140
        dbClient, err := mstore.NewMongoClient(ctx, c)
1✔
141
        if err != nil {
1✔
UNCOV
142
                return err
×
UNCOV
143
        }
×
144
        defer func() {
1✔
UNCOV
145
                _ = dbClient.Disconnect(context.Background())
×
146
        }()
×
147

148
        ds := mstore.NewDataStoreMongoWithClient(dbClient)
1✔
149

1✔
150
        // Storage Layer
1✔
151
        objStore, err := SetupObjectStorage(ctx)
1✔
152
        if err != nil {
1✔
UNCOV
153
                return errors.WithMessage(err, "main: failed to setup storage client")
×
UNCOV
154
        }
×
155

156
        app := app.NewDeployments(ds, objStore)
1✔
157
        if addr := c.GetString(dconfig.SettingReportingAddr); addr != "" {
2✔
158
                c := reporting.NewClient(addr)
1✔
159
                app = app.WithReporting(c)
1✔
160
        }
1✔
161

162
        // Setup API Router configuration
163
        base64Repl := strings.NewReplacer("-", "+", "_", "/", "=", "")
1✔
164
        expireSec := c.GetDuration(dconfig.SettingPresignExpireSeconds)
1✔
165
        apiConf := api.NewConfig().
1✔
166
                SetPresignExpire(time.Second * expireSec).
1✔
167
                SetPresignHostname(c.GetString(dconfig.SettingPresignHost)).
1✔
168
                SetPresignScheme(c.GetString(dconfig.SettingPresignScheme)).
1✔
169
                SetMaxImageSize(c.GetInt64(dconfig.SettingStorageMaxImageSize)).
1✔
170
                SetEnableDirectUpload(c.GetBool(dconfig.SettingStorageEnableDirectUpload)).
1✔
171
                SetEnableDirectUploadSkipVerify(c.GetBool(dconfig.SettingStorageDirectUploadSkipVerify))
1✔
172
        if key, err := base64.RawStdEncoding.DecodeString(
1✔
173
                base64Repl.Replace(
1✔
174
                        c.GetString(dconfig.SettingPresignSecret),
1✔
175
                ),
1✔
176
        ); err == nil {
2✔
177
                apiConf.SetPresignSecret(key)
1✔
178
        }
1✔
179
        router, err := api.NewRouter(ctx, app, ds, apiConf)
1✔
180
        if err != nil {
1✔
UNCOV
181
                return err
×
UNCOV
182
        }
×
183

184
        api := rest.NewApi()
1✔
185
        SetupMiddleware(c, api)
1✔
186
        api.SetApp(router)
1✔
187

1✔
188
        listen := c.GetString(dconfig.SettingListen)
1✔
189

1✔
190
        if c.IsSet(dconfig.SettingHttps) {
1✔
UNCOV
191

×
UNCOV
192
                cert := c.GetString(dconfig.SettingHttpsCertificate)
×
UNCOV
193
                key := c.GetString(dconfig.SettingHttpsKey)
×
UNCOV
194

×
UNCOV
195
                return http.ListenAndServeTLS(listen, cert, key, api.MakeHandler())
×
UNCOV
196
        }
×
197

198
        return http.ListenAndServe(listen, api.MakeHandler())
1✔
199
}
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