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

mendersoftware / reporting / 820253733

pending completion
820253733

Pull #125

gitlab-ci

GitHub
Merge pull request #124 from kjaskiewiczz/men-6405
Pull Request #125: align staging with master

11 of 20 new or added lines in 4 files covered. (55.0%)

5 existing lines in 3 files now uncovered.

2815 of 3311 relevant lines covered (85.02%)

17.51 hits per line

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

76.24
/main.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
        "fmt"
20
        "net/url"
21
        "os"
22
        "strings"
23
        "time"
24

25
        "github.com/pkg/errors"
26
        "github.com/urfave/cli"
27

28
        "github.com/mendersoftware/go-lib-micro/config"
29
        "github.com/mendersoftware/go-lib-micro/log"
30
        mlog "github.com/mendersoftware/go-lib-micro/log"
31

32
        "github.com/mendersoftware/reporting/app/indexer"
33
        "github.com/mendersoftware/reporting/app/server"
34
        "github.com/mendersoftware/reporting/client/nats"
35
        dconfig "github.com/mendersoftware/reporting/config"
36
        "github.com/mendersoftware/reporting/store"
37
        "github.com/mendersoftware/reporting/store/mongo"
38
        "github.com/mendersoftware/reporting/store/opensearch"
39
)
40

41
const (
42
        opensearchMaxWaitingTime      = 300
43
        opensearchRetryDelayInSeconds = 1
44
)
45

46
func main() {
×
47
        os.Exit(doMain(os.Args))
×
48
}
×
49

50
func doMain(args []string) int {
4✔
51
        var configPath string
4✔
52

4✔
53
        app := &cli.App{
4✔
54
                Flags: []cli.Flag{
4✔
55
                        &cli.StringFlag{
4✔
56
                                Name: "config",
4✔
57
                                Usage: "Configuration `FILE`. " +
4✔
58
                                        "Supports JSON, TOML, YAML and HCL formatted configs.",
4✔
59
                                Value:       "config.yaml",
4✔
60
                                Destination: &configPath,
4✔
61
                        },
4✔
62
                },
4✔
63
                Commands: []cli.Command{
4✔
64
                        {
4✔
65
                                Name:   "server",
4✔
66
                                Usage:  "Run the HTTP API server",
4✔
67
                                Action: cmdServer,
4✔
68
                                Flags: []cli.Flag{
4✔
69
                                        &cli.BoolFlag{
4✔
70
                                                Name:  "automigrate",
4✔
71
                                                Usage: "Run database migrations before starting.",
4✔
72
                                        },
4✔
73
                                },
4✔
74
                        },
4✔
75
                        {
4✔
76
                                Name:   "indexer",
4✔
77
                                Usage:  "Run the indexer process",
4✔
78
                                Action: cmdIndexer,
4✔
79
                                Flags: []cli.Flag{
4✔
80
                                        &cli.BoolFlag{
4✔
81
                                                Name:  "automigrate",
4✔
82
                                                Usage: "Run database migrations before starting.",
4✔
83
                                        },
4✔
84
                                },
4✔
85
                        },
4✔
86
                        {
4✔
87
                                Name:   "migrate",
4✔
88
                                Usage:  "Run the migrations",
4✔
89
                                Action: cmdMigrate,
4✔
90
                        },
4✔
91
                },
4✔
92
        }
4✔
93
        app.Usage = "Reporting"
4✔
94
        app.Action = cmdServer
4✔
95

4✔
96
        app.Before = func(args *cli.Context) error {
8✔
97
                err := config.FromConfigFile(configPath, dconfig.Defaults)
4✔
98
                if err != nil {
4✔
99
                        return cli.NewExitError(
×
100
                                fmt.Sprintf("error loading configuration: %s", err),
×
101
                                1)
×
102
                }
×
103

104
                // Enable setting config values by environment variables
105
                config.Config.SetEnvPrefix("REPORTING")
4✔
106
                config.Config.AutomaticEnv()
4✔
107
                config.Config.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
4✔
108

4✔
109
                // setup logging
4✔
110
                mlog.Setup(config.Config.GetBool(dconfig.SettingDebugLog))
4✔
111

4✔
112
                return nil
4✔
113
        }
114

115
        err := app.Run(args)
4✔
116
        if err != nil {
6✔
117
                mlog.NewEmpty().Fatal(err)
2✔
118
                return 1
2✔
119
        }
2✔
120
        return 0
×
121
}
122

123
func cmdServer(args *cli.Context) error {
1✔
124
        store, err := getStore(args)
1✔
125
        if err != nil {
1✔
126
                return err
×
127
        }
×
128
        ctx := context.Background()
1✔
129
        ds, err := getDatastore(args)
1✔
130
        if err != nil {
1✔
131
                return err
×
132
        }
×
133
        defer ds.Close(ctx)
1✔
134
        if args.Bool("automigrate") {
2✔
135
                nats, err := getNatsClient()
1✔
136
                if err != nil {
1✔
137
                        return err
×
138
                }
×
139
                ctx := context.Background()
1✔
140
                err = migrate(ctx, store, ds, nats)
1✔
141
                nats.Close()
1✔
142
                if err != nil {
1✔
UNCOV
143
                        return err
×
UNCOV
144
                }
×
145
        }
146
        return server.InitAndRun(config.Config, store, ds)
1✔
147
}
148

149
func getNatsClient() (nats.Client, error) {
4✔
150
        natsURI := config.Config.GetString(dconfig.SettingNatsURI)
4✔
151
        nats, err := nats.NewClient(natsURI)
4✔
152
        if err != nil {
4✔
153
                return nil, errors.Wrap(err, "failed to connect to nats")
×
154
        }
×
155
        return nats, nil
4✔
156
}
157

158
func cmdIndexer(args *cli.Context) error {
3✔
159
        store, err := getStore(args)
3✔
160
        if err != nil {
3✔
161
                return err
×
162
        }
×
163
        nats, err := getNatsClient()
3✔
164
        if err != nil {
3✔
165
                return err
×
166
        }
×
167
        defer nats.Close()
3✔
168
        ctx := context.Background()
3✔
169
        ds, err := getDatastore(args)
3✔
170
        if err != nil {
3✔
171
                return err
×
172
        }
×
173
        defer ds.Close(ctx)
3✔
174
        if args.Bool("automigrate") {
6✔
175
                err = migrate(ctx, store, ds, nats)
3✔
176
                if err != nil {
5✔
177
                        return err
2✔
178
                }
2✔
179

180
        }
181
        return indexer.InitAndRun(config.Config, store, ds, nats)
1✔
182
}
183

184
func cmdMigrate(args *cli.Context) error {
×
185
        ctx := context.Background()
×
186
        store, err := getStore(args)
×
187
        if err != nil {
×
188
                return err
×
189
        }
×
190
        ds, err := getDatastore(args)
×
191
        if err != nil {
×
192
                return err
×
193
        }
×
194
        nats, err := getNatsClient()
×
195
        if err != nil {
×
196
                return err
×
197
        }
×
198
        return migrate(ctx, store, ds, nats)
×
199
}
200

201
func migrate(ctx context.Context, store store.Store, ds store.DataStore, nats nats.Client) error {
4✔
202
        err := store.Migrate(ctx)
4✔
203
        if err != nil {
6✔
204
                return err
2✔
205
        }
2✔
206
        err = ds.Migrate(ctx, mongo.DbVersion, true)
2✔
207
        if err != nil {
2✔
208
                return err
×
209
        }
×
210
        dur := config.Config.GetString(dconfig.SettingNatsSubscriberDurable)
2✔
211
        stream := config.Config.GetString(dconfig.SettingNatsStreamName)
2✔
212
        topic := config.Config.GetString(dconfig.SettingNatsSubscriberTopic)
2✔
213
        sub := stream + "." + topic
2✔
214
        return nats.Migrate(ctx, sub, dur, true)
2✔
215
}
216

217
func getStore(args *cli.Context) (store.Store, error) {
4✔
218
        addresses := config.Config.GetStringSlice(dconfig.SettingOpenSearchAddresses)
4✔
219
        devicesIndexName := config.Config.GetString(dconfig.SettingOpenSearchDevicesIndexName)
4✔
220
        devicesIndexShards := config.Config.GetInt(dconfig.SettingOpenSearchDevicesIndexShards)
4✔
221
        devicesIndexReplicas := config.Config.GetInt(
4✔
222
                dconfig.SettingOpenSearchDevicesIndexReplicas)
4✔
223
        deploymentsIndexName := config.Config.GetString(dconfig.SettingOpenSearchDeploymentsIndexName)
4✔
224
        deploymentsIndexShards := config.Config.GetInt(dconfig.SettingOpenSearchDeploymentsIndexShards)
4✔
225
        deploymentsIndexReplicas := config.Config.GetInt(
4✔
226
                dconfig.SettingOpenSearchDeploymentsIndexReplicas)
4✔
227
        store, err := opensearch.NewStore(
4✔
228
                opensearch.WithServerAddresses(addresses),
4✔
229
                opensearch.WithDevicesIndexName(devicesIndexName),
4✔
230
                opensearch.WithDevicesIndexShards(devicesIndexShards),
4✔
231
                opensearch.WithDevicesIndexReplicas(devicesIndexReplicas),
4✔
232
                opensearch.WithDeploymentsIndexName(deploymentsIndexName),
4✔
233
                opensearch.WithDeploymentsIndexShards(deploymentsIndexShards),
4✔
234
                opensearch.WithDeploymentsIndexReplicas(deploymentsIndexReplicas),
4✔
235
        )
4✔
236
        if err != nil {
4✔
237
                return nil, err
×
238
        }
×
239
        ctx := context.Background()
4✔
240
        l := log.FromContext(ctx)
4✔
241
        for i := 0; i < opensearchMaxWaitingTime; i++ {
122✔
242
                err = store.Ping(ctx)
118✔
243
                if err == nil {
122✔
244
                        break
4✔
245
                }
246
                l.Warn(err)
114✔
247
                time.Sleep(opensearchRetryDelayInSeconds * time.Second)
114✔
248
        }
249
        if err != nil {
4✔
250
                l.Error(err)
×
251
                return nil, err
×
252
        }
×
253
        l.Info("successfully connected to OpenSearch")
4✔
254
        return store, nil
4✔
255
}
256

257
func getDatastore(args *cli.Context) (store.DataStore, error) {
4✔
258
        mgoURL, err := url.Parse(config.Config.GetString(dconfig.SettingMongo))
4✔
259
        if err != nil {
4✔
260
                return nil, err
×
261
        }
×
262

263
        storeConfig := mongo.MongoStoreConfig{
4✔
264
                MongoURL:      mgoURL,
4✔
265
                SSL:           config.Config.GetBool(dconfig.SettingDbSSL),
4✔
266
                SSLSkipVerify: config.Config.GetBool(dconfig.SettingDbSSLSkipVerify),
4✔
267
                Username:      config.Config.GetString(dconfig.SettingDbUsername),
4✔
268
                Password:      config.Config.GetString(dconfig.SettingDbPassword),
4✔
269
                DbName:        mongo.DbName,
4✔
270
        }
4✔
271

4✔
272
        return mongo.NewMongoStore(context.Background(), storeConfig)
4✔
273
}
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