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

mendersoftware / mender / 1066350345

09 Nov 2023 08:56AM UTC coverage: 80.217% (+0.08%) from 80.14%
1066350345

push

gitlab-ci

lluiscampos
fix: Resume downloads when the first header handler errors

This will cover the case for example when the host cannot temporary be
resolved or the handshake fails.

It is explicitly tested on an integration test.

Ticket: MEN-6671
Changelog: None

Signed-off-by: Lluis Campos <lluis.campos@northern.tech>

6 of 6 new or added lines in 1 file covered. (100.0%)

17 existing lines in 2 files now uncovered.

6958 of 8674 relevant lines covered (80.22%)

9279.1 hits per line

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

61.04
/src/mender-auth/cli/actions.cpp
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
#include <mender-auth/cli/actions.hpp>
16

17
#include <string>
18
#include <memory>
19

20
#include <api/auth.hpp>
21

22
#include <mender-auth/context.hpp>
23
#include <mender-auth/cli/keystore.hpp>
24

25
#include <common/conf.hpp>
26
#include <common/events.hpp>
27
#include <common/log.hpp>
28

29
#include <mender-auth/ipc/server.hpp>
30

31
namespace mender {
32
namespace auth {
33
namespace cli {
34

35
using namespace std;
36

37
namespace auth_client = mender::api::auth;
38
namespace events = mender::common::events;
39
namespace ipc = mender::auth::ipc;
40
namespace log = mender::common::log;
41

42
shared_ptr<MenderKeyStore> KeystoreFromConfig(
4✔
43
        const conf::MenderConfig &config, const string &passphrase) {
44
        cli::StaticKey static_key = cli::StaticKey::No;
4✔
45
        string pem_file;
46
        string ssl_engine;
47

48
        if (config.security.auth_private_key != "") {
4✔
49
                pem_file = config.security.auth_private_key;
50
                ssl_engine = config.security.ssl_engine;
×
51
                static_key = cli::StaticKey::Yes;
×
52
        } else {
53
                pem_file = config.paths.GetKeyFile();
4✔
54
                static_key = cli::StaticKey::No;
4✔
55
        }
56

57
        return make_shared<MenderKeyStore>(pem_file, ssl_engine, static_key, passphrase);
8✔
58
}
59

60
error::Error DoBootstrap(shared_ptr<MenderKeyStore> keystore, const bool force) {
4✔
61
        auto err = keystore->Load();
4✔
62
        if (err != error::NoError && err.code != MakeError(NoKeysError, "").code) {
10✔
63
                return err;
64
        }
65
        if (err != error::NoError) {
4✔
66
                log::Error("Got error loading the private key from the keystore: " + err.String());
4✔
67
        }
68
        if (err.code == MakeError(NoKeysError, "").code || force) {
8✔
69
                log::Info("Generating new RSA key");
6✔
70
                err = keystore->Generate();
3✔
71
                if (err != error::NoError) {
3✔
72
                        return err;
73
                }
74
                err = keystore->Save();
6✔
75
                if (err != error::NoError) {
76
                        return err;
77
                }
78
        }
79
        return err;
80
}
81

82
error::Error DoAuthenticate(
4✔
83
        context::MenderContext &main_context, shared_ptr<MenderKeyStore> keystore) {
84
        events::EventLoop loop;
85
        auto &config = main_context.GetConfig();
86
        if (config.servers.size() == 0) {
4✔
87
                log::Info("No server set in the configuration, skipping authentication");
6✔
88
                return error::NoError;
3✔
89
        }
90
        mender::common::events::Timer timer {loop};
2✔
91
        http::Client client {main_context.GetConfig().GetHttpClientConfig(), loop};
3✔
92
        auto err = auth_client::FetchJWTToken(
93
                client,
94
                config.servers,
1✔
95
                {keystore->KeyName(), keystore->PassPhrase(), keystore->SSLEngine()},
96
                config.paths.GetIdentityScript(),
1✔
97
                [&loop, &timer](auth_client::APIResponse resp) {
3✔
98
                        log::Info("Got Auth response");
2✔
99
                        if (resp) {
1✔
100
                                log::Info(
1✔
101
                                        "Successfully authorized with the server '" + resp.value().server_url + "'");
2✔
102
                        } else {
103
                                log::Error(resp.error().String());
×
104
                        }
105
                        timer.Cancel();
1✔
106
                        loop.Stop();
1✔
107
                },
1✔
108
                config.tenant_token);
3✔
109
        if (err != error::NoError) {
1✔
110
                return err;
×
111
        }
112
        timer.AsyncWait(chrono::seconds {30}, [&loop](error::Error err) { loop.Stop(); });
1✔
113
        loop.Run();
1✔
114
        return error::NoError;
1✔
115
}
116

117
DaemonAction::DaemonAction(shared_ptr<MenderKeyStore> keystore, const bool force_bootstrap) :
×
118
        keystore_(keystore),
119
        force_bootstrap_(force_bootstrap) {
×
120
}
×
121

122
ExpectedActionPtr DaemonAction::Create(
×
123
        const conf::MenderConfig &config, const string &passphrase, const bool force_bootstrap) {
124
        auto key_store = KeystoreFromConfig(config, passphrase);
×
125

126
        return make_shared<DaemonAction>(key_store, force_bootstrap);
×
127
}
128

129
error::Error DaemonAction::Execute(context::MenderContext &main_context) {
×
130
        auto &config = main_context.GetConfig();
131
        if (none_of(config.servers.cbegin(), config.servers.cend(), [](const string &it) {
×
132
                        return it != "";
×
133
                })) {
134
                log::Error("Cannot run in daemon mode with no server URL specified");
×
135
                return error::MakeError(error::ExitWithFailureError, "");
×
136
        }
137

138
        auto err = DoBootstrap(keystore_, force_bootstrap_);
×
139
        if (err != error::NoError) {
×
140
                log::Error("Failed to bootstrap: " + err.String());
×
141
                return error::MakeError(error::ExitWithFailureError, "");
×
142
        }
143

144
        events::EventLoop loop {};
×
145

146
        ipc::Server ipc_server {loop, config};
×
147

148
        err = ipc_server.Listen(
×
149
                {keystore_->KeyName(), keystore_->PassPhrase(), keystore_->SSLEngine()},
150
                config.paths.GetIdentityScript());
×
151
        if (err != error::NoError) {
×
152
                log::Error("Failed to start the listen loop");
×
153
                log::Error(err.String());
×
154
                return error::MakeError(error::ExitWithFailureError, "");
×
155
        }
156

157
        loop.Run();
×
158

159
        return error::NoError;
×
160
}
161

162
BootstrapAction::BootstrapAction(shared_ptr<MenderKeyStore> keystore, bool force_bootstrap) :
4✔
163
        keystore_(keystore),
164
        force_bootstrap_(force_bootstrap) {
8✔
165
}
4✔
166

167
ExpectedActionPtr BootstrapAction::Create(
4✔
168
        const conf::MenderConfig &config, const string &passphrase, bool force_bootstrap) {
169
        auto key_store = KeystoreFromConfig(config, passphrase);
4✔
170

171
        return make_shared<BootstrapAction>(key_store, force_bootstrap);
8✔
172
}
173

174
error::Error BootstrapAction::Execute(context::MenderContext &main_context) {
4✔
175
        auto err = DoBootstrap(keystore_, force_bootstrap_);
4✔
176
        if (err != error::NoError) {
4✔
UNCOV
177
                return err;
×
178
        }
179
        return DoAuthenticate(main_context, keystore_);
8✔
180
}
181

182
} // namespace cli
183
} // namespace auth
184
} // namespace mender
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