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

mendersoftware / deviceauth / 857655394

pending completion
857655394

Pull #644

gitlab-ci

Krzysztof Jaskiewicz
chore: reduce cyclomatic complexity of VerifyToken method
Pull Request #644: feat: handle device check-in time

106 of 160 new or added lines in 3 files covered. (66.25%)

99 existing lines in 3 files now uncovered.

4627 of 5519 relevant lines covered (83.84%)

46.04 hits per line

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

70.13
/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
package main
15

16
import (
17
        "context"
18
        "fmt"
19
        "os"
20

21
        "github.com/mendersoftware/go-lib-micro/config"
22
        "github.com/mendersoftware/go-lib-micro/log"
23
        "github.com/pkg/errors"
24
        "github.com/urfave/cli"
25

26
        cinv "github.com/mendersoftware/deviceauth/client/inventory"
27
        "github.com/mendersoftware/deviceauth/client/orchestrator"
28
        "github.com/mendersoftware/deviceauth/client/tenant"
29
        "github.com/mendersoftware/deviceauth/cmd"
30
        dconfig "github.com/mendersoftware/deviceauth/config"
31
        "github.com/mendersoftware/deviceauth/store/mongo"
32
)
33

UNCOV
34
func main() {
×
UNCOV
35
        doMain(os.Args)
×
UNCOV
36
}
×
37

38
func doMain(args []string) {
1✔
39
        var configPath string
1✔
40
        var debug bool
1✔
41

1✔
42
        app := cli.NewApp()
1✔
43
        app.Usage = "Device Authentication Service"
1✔
44

1✔
45
        app.Flags = []cli.Flag{
1✔
46
                cli.StringFlag{
1✔
47
                        Name: "config",
1✔
48
                        Usage: "Configuration `FILE`." +
1✔
49
                                " Supports JSON, TOML, YAML and HCL formatted configs.",
1✔
50
                        Destination: &configPath,
1✔
51
                },
1✔
52
                cli.BoolFlag{
1✔
53
                        Name:  "dev",
1✔
54
                        Usage: "Use development setup",
1✔
55
                },
1✔
56
                cli.BoolFlag{
1✔
57
                        Name:        "debug",
1✔
58
                        Usage:       "Enable debug logging",
1✔
59
                        Destination: &debug,
1✔
60
                },
1✔
61
        }
1✔
62

1✔
63
        app.Commands = []cli.Command{
1✔
64
                {
1✔
65
                        Name:  "server",
1✔
66
                        Usage: "Run the service as a server",
1✔
67
                        Flags: []cli.Flag{
1✔
68
                                cli.BoolFlag{
1✔
69
                                        Name:  "automigrate",
1✔
70
                                        Usage: "Run database migrations before starting.",
1✔
71
                                },
1✔
72
                        },
1✔
73

1✔
74
                        Action: cmdServer,
1✔
75
                },
1✔
76
                {
1✔
77
                        Name:  "migrate",
1✔
78
                        Usage: "Run migrations and exit",
1✔
79
                        Flags: []cli.Flag{
1✔
80
                                cli.StringFlag{
1✔
81
                                        Name:  "tenant",
1✔
82
                                        Usage: "Tenant ID (optional).",
1✔
83
                                },
1✔
84
                                cli.BoolFlag{
1✔
85
                                        Name:  "list-tenants",
1✔
86
                                        Usage: "List Tenant IDs. Not performing migrations.",
1✔
87
                                },
1✔
88
                        },
1✔
89

1✔
90
                        Action: cmdMigrate,
1✔
91
                },
1✔
92
                {
1✔
93
                        Name:  "propagate-inventory-statuses",
1✔
94
                        Usage: "Push device statuses to inventory",
1✔
95
                        Flags: []cli.Flag{
1✔
96
                                cli.StringFlag{
1✔
97
                                        Name:  "tenant_id",
1✔
98
                                        Usage: "Tenant ID (optional) - propagate for just a single tenant.",
1✔
99
                                },
1✔
100
                                cli.StringFlag{
1✔
101
                                        Name:  "force-set-migration",
1✔
102
                                        Usage: "Migration version to be stored in migration_info collection.",
1✔
103
                                },
1✔
104
                                cli.BoolFlag{
1✔
105
                                        Name: "dry-run",
1✔
106
                                        Usage: "Do not perform any inventory modifications," +
1✔
107
                                                " just scan and print devices.",
1✔
108
                                },
1✔
109
                        },
1✔
110

1✔
111
                        Action: cmdPropagateStatusesInventory,
1✔
112
                },
1✔
113
                {
1✔
114
                        Name:  "propagate-inventory-id-data",
1✔
115
                        Usage: "Push device id_data to inventory",
1✔
116
                        Flags: []cli.Flag{
1✔
117
                                cli.StringFlag{
1✔
118
                                        Name:  "tenant_id",
1✔
119
                                        Usage: "Tenant ID (optional) - propagate for just a single tenant.",
1✔
120
                                },
1✔
121
                                cli.BoolFlag{
1✔
122
                                        Name: "dry-run",
1✔
123
                                        Usage: "Do not perform any inventory modifications," +
1✔
124
                                                " just scan and print devices.",
1✔
125
                                },
1✔
126
                        },
1✔
127

1✔
128
                        Action: cmdPropagateIdDataInventory,
1✔
129
                },
1✔
130
                {
1✔
131
                        Name:  "propagate-reporting",
1✔
132
                        Usage: "Trigger a reindex of all the devices in the reporting services ",
1✔
133
                        Flags: []cli.Flag{
1✔
134
                                cli.StringFlag{
1✔
135
                                        Name:  "tenant_id",
1✔
136
                                        Usage: "Tenant ID (optional) - propagate for just a single tenant.",
1✔
137
                                },
1✔
138
                                cli.BoolFlag{
1✔
139
                                        Name: "dry-run",
1✔
140
                                        Usage: "Do not perform any inventory modifications," +
1✔
141
                                                " just scan and print devices.",
1✔
142
                                },
1✔
143
                        },
1✔
144

1✔
145
                        Action: cmdPropagateReporting,
1✔
146
                },
1✔
147
                {
1✔
148
                        Name:  "maintenance",
1✔
149
                        Usage: "Run maintenance operations and exit",
1✔
150
                        Flags: []cli.Flag{
1✔
151
                                cli.BoolFlag{
1✔
152
                                        Name:  "decommissioning-cleanup",
1✔
153
                                        Usage: "Cleanup devauth database from leftovers after failed decommissioning",
1✔
154
                                },
1✔
155
                                cli.StringFlag{
1✔
156
                                        Name:  "tenant",
1✔
157
                                        Usage: "Tenant ID (optional).",
1✔
158
                                },
1✔
159
                                cli.BoolFlag{
1✔
160
                                        Name: "dry-run",
1✔
161
                                        Usage: "Do not perform any modifications and serves" +
1✔
162
                                                " only as a way to inspect changes and detect if any are necessary",
1✔
163
                                },
1✔
164
                        },
1✔
165

1✔
166
                        Action: cmdMaintenance,
1✔
167
                }, {
1✔
168
                        Name:  "check-device-limits",
1✔
169
                        Usage: "Warn users if user is approaching device limit",
1✔
170
                        Description: "Loops through all tenant databases and " +
1✔
171
                                "checks if the number of devices is over a " +
1✔
172
                                "threshold of the allowed limit and sends an " +
1✔
173
                                "email asking the user to upgrade or decomission" +
1✔
174
                                "unused devices.",
1✔
175
                        Flags: []cli.Flag{
1✔
176
                                cli.Float64Flag{
1✔
177
                                        Name:  "threshold, t",
1✔
178
                                        Value: 90.0,
1✔
179
                                        Usage: "Threshold in percent (%) of " +
1✔
180
                                                "device limit that trigger " +
1✔
181
                                                "email event.",
1✔
182
                                },
1✔
183
                        },
1✔
184
                        Action: cmdCheckDeviceLimits,
1✔
185
                },
1✔
186
        }
1✔
187

1✔
188
        app.Action = cmdServer
1✔
189
        app.Before = func(args *cli.Context) error {
2✔
190
                log.Setup(debug)
1✔
191

1✔
192
                err := config.FromConfigFile(configPath, dconfig.Defaults)
1✔
193
                if err != nil {
1✔
UNCOV
194
                        return cli.NewExitError(
×
UNCOV
195
                                fmt.Sprintf("error loading configuration: %s", err),
×
UNCOV
196
                                1)
×
UNCOV
197
                }
×
198

199
                // Enable setting config values by environment variables
200
                config.Config.SetEnvPrefix("DEVICEAUTH")
1✔
201
                config.Config.AutomaticEnv()
1✔
202

1✔
203
                return nil
1✔
204
        }
205

206
        _ = app.Run(args)
1✔
207
}
208

209
func cmdServer(args *cli.Context) error {
1✔
210
        devSetup := args.GlobalBool("dev")
1✔
211

1✔
212
        l := log.New(log.Ctx{})
1✔
213

1✔
214
        if devSetup {
1✔
UNCOV
215
                l.Infof("setting up development configuration")
×
UNCOV
216
                config.Config.Set(dconfig.SettingMiddleware, EnvDev)
×
UNCOV
217
        }
×
218

219
        db, err := mongo.NewDataStoreMongo(makeDataStoreConfig())
1✔
220
        if err != nil {
1✔
UNCOV
221
                return cli.NewExitError(
×
UNCOV
222
                        fmt.Sprintf("failed to connect to db: %v", err),
×
UNCOV
223
                        2)
×
UNCOV
224
        }
×
225

226
        if args.Bool("automigrate") {
2✔
227
                db = db.WithAutomigrate().(*mongo.DataStoreMongo)
1✔
228
        }
1✔
229

230
        if config.Config.Get(dconfig.SettingTenantAdmAddr) != "" {
2✔
231
                db = db.WithMultitenant()
1✔
232
        }
1✔
233

234
        ctx := context.Background()
1✔
235
        err = db.Migrate(ctx, mongo.DbVersion)
1✔
236
        if err != nil {
1✔
UNCOV
237
                return cli.NewExitError(
×
UNCOV
238
                        fmt.Sprintf("failed to run migrations: %v", err),
×
UNCOV
239
                        3)
×
UNCOV
240
        }
×
241

242
        l.Print("Device Authentication Service starting up")
1✔
243

1✔
244
        err = RunServer(config.Config)
1✔
245
        if err != nil {
1✔
UNCOV
246
                return cli.NewExitError(err.Error(), 4)
×
247
        }
×
248

249
        return nil
×
250
}
251

252
func cmdMigrate(args *cli.Context) error {
1✔
253
        err := cmd.Migrate(config.Config, args.String("tenant"), args.Bool("list-tenants"))
1✔
254
        if err != nil {
1✔
UNCOV
255
                return cli.NewExitError(err, 5)
×
256
        }
×
257
        return nil
1✔
258
}
259

UNCOV
260
func cmdMaintenance(args *cli.Context) error {
×
UNCOV
261
        err := cmd.Maintenance(
×
UNCOV
262
                args.Bool("decommissioning-cleanup"),
×
UNCOV
263
                args.String("tenant"),
×
UNCOV
264
                args.Bool("dry-run"),
×
265
        )
×
266
        if err != nil {
×
UNCOV
267
                return cli.NewExitError(err, 6)
×
UNCOV
268
        }
×
UNCOV
269
        return nil
×
270
}
271

272
func cmdPropagateStatusesInventory(args *cli.Context) error {
×
273
        db, err := mongo.NewDataStoreMongo(makeDataStoreConfig())
×
274
        if err != nil {
×
275
                return err
×
276
        }
×
277

278
        inv := config.Config.GetString(dconfig.SettingInventoryAddr)
×
279
        c := cinv.NewClient(inv, false)
×
UNCOV
280

×
UNCOV
281
        err = cmd.PropagateStatusesInventory(db,
×
282
                c,
×
283
                args.String("tenant_id"),
×
284
                args.String("force-set-migration"),
×
285
                args.Bool("dry-run"))
×
286
        if err != nil {
×
UNCOV
287
                return cli.NewExitError(err, 7)
×
288
        }
×
289
        return nil
×
290
}
291

292
func cmdPropagateIdDataInventory(args *cli.Context) error {
×
293
        db, err := mongo.NewDataStoreMongo(makeDataStoreConfig())
×
294
        if err != nil {
×
295
                return err
×
296
        }
×
297

298
        inv := config.Config.GetString(dconfig.SettingInventoryAddr)
×
299
        c := cinv.NewClient(inv, false)
×
UNCOV
300

×
UNCOV
301
        err = cmd.PropagateIdDataInventory(db,
×
302
                c,
×
303
                args.String("tenant_id"),
×
304
                args.Bool("dry-run"))
×
305
        if err != nil {
×
306
                return cli.NewExitError(err, 7)
×
UNCOV
307
        }
×
308
        return nil
×
309
}
310

311
func cmdPropagateReporting(args *cli.Context) error {
×
312
        if !config.Config.GetBool(dconfig.SettingEnableReporting) {
×
313
                return cli.NewExitError(errors.New("reporting support not enabled"), 1)
×
314
        }
×
315

316
        db, err := mongo.NewDataStoreMongo(makeDataStoreConfig())
×
317
        if err != nil {
×
318
                return err
×
UNCOV
319
        }
×
320

321
        wflows := orchestrator.NewClient(orchestrator.Config{
×
322
                OrchestratorAddr: config.Config.GetString(
×
323
                        dconfig.SettingOrchestratorAddr,
×
324
                ),
×
UNCOV
325
        })
×
326

×
327
        err = cmd.PropagateReporting(
×
328
                db,
×
329
                wflows,
×
UNCOV
330
                args.String("tenant_id"),
×
331
                args.Bool("dry-run"),
×
332
        )
×
333
        if err != nil {
×
334
                return cli.NewExitError(err, 7)
×
335
        }
×
336
        return nil
×
337
}
338

339
func makeDataStoreConfig() mongo.DataStoreMongoConfig {
1✔
340
        return mongo.DataStoreMongoConfig{
1✔
341
                ConnectionString: config.Config.GetString(dconfig.SettingDb),
1✔
342

1✔
343
                SSL:           config.Config.GetBool(dconfig.SettingDbSSL),
1✔
344
                SSLSkipVerify: config.Config.GetBool(dconfig.SettingDbSSLSkipVerify),
1✔
345

1✔
346
                Username: config.Config.GetString(dconfig.SettingDbUsername),
1✔
347
                Password: config.Config.GetString(dconfig.SettingDbPassword),
1✔
348
        }
1✔
349

1✔
350
}
1✔
351

352
func cmdCheckDeviceLimits(args *cli.Context) error {
1✔
353
        mgoConf := makeDataStoreConfig()
1✔
354
        ds, err := mongo.NewDataStoreMongo(mgoConf)
1✔
355
        if err != nil {
1✔
UNCOV
356
                return errors.Wrap(err, "cmd: failed to initialize DataStore client")
×
UNCOV
357
        }
×
358
        // Initialize tenantadm and workflows clients.
359
        tadm := tenant.NewClient(tenant.Config{
1✔
360
                TenantAdmAddr: config.Config.GetString(
1✔
361
                        dconfig.SettingTenantAdmAddr,
1✔
362
                ),
1✔
363
        })
1✔
364
        wflows := orchestrator.NewClient(orchestrator.Config{
1✔
365
                OrchestratorAddr: config.Config.GetString(
1✔
366
                        dconfig.SettingOrchestratorAddr,
1✔
367
                ),
1✔
368
        })
1✔
369
        return cmd.CheckDeviceLimits(
1✔
370
                args.Float64("threshold"),
1✔
371
                ds, tadm, wflows,
1✔
372
        )
1✔
373
}
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