userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
secdist.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/storages/secdist/secdist.hpp
4
/// @brief @copybrief storages::secdist::SecdistConfig
5
6
#
include
<
any
>
7
#
include
<
chrono
>
8
#
include
<
cstdint
>
9
#
include
<
functional
>
10
#
include
<
optional
>
11
#
include
<
stdexcept
>
12
#
include
<
string
>
13
#
include
<
string_view
>
14
#
include
<
typeindex
>
15
#
include
<
vector
>
16
17
#
include
<
userver
/
concurrent
/
async_event_source
.
hpp
>
18
#
include
<
userver
/
engine
/
task
/
task_processor_fwd
.
hpp
>
19
#
include
<
userver
/
formats
/
json
/
value
.
hpp
>
20
#
include
<
userver
/
rcu
/
rcu
.
hpp
>
21
#
include
<
userver
/
storages
/
secdist
/
provider
.
hpp
>
22
#
include
<
userver
/
utils
/
fast_pimpl
.
hpp
>
23
24
USERVER_NAMESPACE_BEGIN
25
26
/// Credentials storage
27
namespace
storages::
secdist
{
28
29
class
SecdistConfig;
30
31
namespace
detail {
32
33
template
<
typename
T>
34
class
SecdistModule
final
{
35
public
:
36
static
const
T& Get(
const
SecdistConfig& config);
37
static
std::any Factory(
const
formats::
json
::
Value
& data) {
return
T(data); }
38
39
private
:
40
static
std::size_t index;
41
};
42
43
}
// namespace detail
44
45
/// Secdist file format
46
enum
class
SecdistFormat
{
47
kJson,
48
kYaml,
49
kYamlConfig,
50
};
51
52
/// @ingroup userver_clients
53
///
54
/// @brief Client to retrieve credentials from the components::Secdist.
55
///
56
/// ## Example usage:
57
///
58
/// Declare a type that would work with the credentials:
59
///
60
/// @snippet storages/secdist/secdist_test.cpp UserPasswords
61
///
62
/// Fill the components::Secdist `config` from file with the secure data:
63
///
64
/// @snippet storages/secdist/secdist_test.cpp Secdist Usage Sample - json
65
///
66
/// Retrieve SecdistConfig from components::Secdist and get the type from it:
67
///
68
/// @snippet storages/secdist/secdist_test.cpp Secdist Usage Sample - SecdistConfig
69
///
70
/// Json with secure data can also be loaded from environment variable with name defined in `environment_secrets_key`.
71
/// Sample variable value: `{"user-passwords":{"username":"password","another username":"another password"}}`.
72
/// It has the same format as data from file.
73
/// If both sources are presented, data from environment variable will be merged with data from file
74
/// (json objects will be merged, duplicate fields of other types will be overridden by data from environment variable).
75
class
SecdistConfig
final
{
76
public
:
77
struct
Settings
{
78
SecdistProvider
* provider{
nullptr
};
79
std::chrono::milliseconds update_period{std::chrono::milliseconds::zero()};
80
};
81
82
SecdistConfig();
83
explicit
SecdistConfig(
const
Settings
& settings);
84
85
template
<
typename
T>
86
static
std::size_t Register(std::function<std::any(
const
formats::
json
::
Value
&)>&& factory) {
87
return
Register(std::move(factory));
88
}
89
90
template
<
typename
T>
91
const
T& Get()
const
{
92
return
detail::SecdistModule<T>::Get(*
this
);
93
}
94
95
private
:
96
void
Init(
const
formats::
json
::
Value
& doc);
97
98
static
std::size_t Register(std::function<std::any(
const
formats::
json
::
Value
&)>&& factory);
99
const
std::any& Get(
const
std::type_index& type, std::size_t index)
const
;
100
101
template
<
typename
T>
102
friend
class
detail::SecdistModule;
103
104
std::vector<std::any> configs_;
105
};
106
107
/// @ingroup userver_clients
108
///
109
/// @brief Client to retrieve credentials from the components::Secdist and to
110
/// subscribe to their updates.
111
class
Secdist
final
{
112
public
:
113
explicit
Secdist(SecdistConfig::
Settings
settings);
114
~Secdist();
115
116
/// Returns secdist data loaded on service start.
117
/// Does not support secdist updating during service work.
118
const
storages::
secdist
::SecdistConfig&
Get
()
const
;
119
120
/// Returns fresh secdist data (from last update).
121
/// Supports secdist updating during service work.
122
rcu
::
ReadablePtr
<storages::
secdist
::SecdistConfig>
GetSnapshot
()
const
;
123
124
/// Subscribes to secdist updates using a member function, named
125
/// `OnSecdistUpdate` by convention. Also immediately invokes the function
126
/// with the current secdist data.
127
template
<
typename
Class>
128
concurrent
::AsyncEventSubscriberScope
UpdateAndListen
(
129
Class* obj,
130
std::string_view name,
131
void
(Class::*func)(
const
storages::
secdist
::SecdistConfig& secdist)
132
);
133
134
bool
IsPeriodicUpdateEnabled()
const
noexcept
;
135
136
private
:
137
using
EventSource =
concurrent
::
AsyncEventSource
<
const
SecdistConfig&>;
138
139
concurrent
::AsyncEventSubscriberScope DoUpdateAndListen(
140
concurrent
::FunctionId id,
141
std::string_view name,
142
EventSource::Function&& func
143
);
144
145
class
Impl;
146
utils
::FastPimpl<Impl, 1280, 16> impl_;
147
};
148
149
template
<
typename
Class>
150
concurrent
::AsyncEventSubscriberScope Secdist::
UpdateAndListen
(
151
Class* obj,
152
std::string_view name,
153
void
(Class::*func)(
const
storages::
secdist
::SecdistConfig& secdist)
154
) {
155
return
DoUpdateAndListen(
concurrent
::FunctionId(obj), name, [obj, func](
const
SecdistConfig& config) {
156
(obj->*func)(config);
157
});
158
}
159
160
namespace
detail {
161
162
template
<
typename
T>
163
const
T& SecdistModule<T>::Get(
const
SecdistConfig& config) {
164
return
std::any_cast<
const
T&>(config.Get(
typeid
(T), index));
165
}
166
167
template
<
typename
T>
168
std::size_t SecdistModule<T>::index = SecdistConfig::Register<T>(&SecdistModule<T>::Factory);
169
170
}
// namespace detail
171
172
}
// namespace storages::secdist
173
174
USERVER_NAMESPACE_END
userver
storages
secdist
secdist.hpp
Generated on
for userver by
Doxygen
1.17.0