Skip to content

Commit 18ea57a

Browse files
authored
Support secrets: core part (#4389)
1 parent 418f880 commit 18ea57a

File tree

13 files changed

+292
-1
lines changed

13 files changed

+292
-1
lines changed

ydb/core/protos/counters_replication.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,5 @@ enum ETxTypes {
3434
TXTYPE_DROP_STREAM_RESULT = 8 [(TxTypeOpts) = {Name: "TxDropStreamResult"}];
3535
TXTYPE_DROP_DST_RESULT = 9 [(TxTypeOpts) = {Name: "TxDropDstResult"}];
3636
TXTYPE_ALTER_REPLICATION = 10 [(TxTypeOpts) = {Name: "TxAlterReplication"}];
37+
TXTYPE_RESOLVE_SECRET_RESULT = 11 [(TxTypeOpts) = {Name: "TxResolveSecretResult"}];
3738
}

ydb/core/protos/replication.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ option java_package = "ru.yandex.kikimr.proto";
77
message TStaticCredentials {
88
optional string User = 1;
99
optional string Password = 2 [(Ydb.sensitive) = true];
10+
optional string PasswordSecretName = 3;
1011
}
1112

1213
message TOAuthToken {
1314
optional string Token = 1 [(Ydb.sensitive) = true];
15+
optional string TokenSecretName = 2;
1416
}
1517

1618
message TConnectionParams {

ydb/core/tx/replication/controller/controller.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ STFUNC(TController::StateWork) {
5252
HFunc(TEvPrivate::TEvDropStreamResult, Handle);
5353
HFunc(TEvPrivate::TEvCreateDstResult, Handle);
5454
HFunc(TEvPrivate::TEvDropDstResult, Handle);
55+
HFunc(TEvPrivate::TEvResolveSecretResult, Handle);
5556
HFunc(TEvPrivate::TEvResolveTenantResult, Handle);
5657
HFunc(TEvPrivate::TEvUpdateTenantNodes, Handle);
5758
HFunc(TEvPrivate::TEvRunWorkers, Handle);
@@ -152,6 +153,11 @@ void TController::Handle(TEvPrivate::TEvDropDstResult::TPtr& ev, const TActorCon
152153
RunTxDropDstResult(ev, ctx);
153154
}
154155

156+
void TController::Handle(TEvPrivate::TEvResolveSecretResult::TPtr& ev, const TActorContext& ctx) {
157+
CLOG_T(ctx, "Handle " << ev->Get()->ToString());
158+
RunTxResolveSecretResult(ev, ctx);
159+
}
160+
155161
void TController::Handle(TEvPrivate::TEvResolveTenantResult::TPtr& ev, const TActorContext& ctx) {
156162
CLOG_T(ctx, "Handle " << ev->Get()->ToString());
157163

ydb/core/tx/replication/controller/controller_impl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ class TController
7575
void Handle(TEvPrivate::TEvDropStreamResult::TPtr& ev, const TActorContext& ctx);
7676
void Handle(TEvPrivate::TEvCreateDstResult::TPtr& ev, const TActorContext& ctx);
7777
void Handle(TEvPrivate::TEvDropDstResult::TPtr& ev, const TActorContext& ctx);
78+
void Handle(TEvPrivate::TEvResolveSecretResult::TPtr& ev, const TActorContext& ctx);
7879
void Handle(TEvPrivate::TEvResolveTenantResult::TPtr& ev, const TActorContext& ctx);
7980
void Handle(TEvPrivate::TEvUpdateTenantNodes::TPtr& ev, const TActorContext& ctx);
8081
void Handle(TEvPrivate::TEvRunWorkers::TPtr& ev, const TActorContext& ctx);
@@ -103,6 +104,7 @@ class TController
103104
class TTxDropStreamResult;
104105
class TTxCreateDstResult;
105106
class TTxDropDstResult;
107+
class TTxResolveSecretResult;
106108

107109
// tx runners
108110
void RunTxInitSchema(const TActorContext& ctx);
@@ -117,6 +119,7 @@ class TController
117119
void RunTxDropStreamResult(TEvPrivate::TEvDropStreamResult::TPtr& ev, const TActorContext& ctx);
118120
void RunTxCreateDstResult(TEvPrivate::TEvCreateDstResult::TPtr& ev, const TActorContext& ctx);
119121
void RunTxDropDstResult(TEvPrivate::TEvDropDstResult::TPtr& ev, const TActorContext& ctx);
122+
void RunTxResolveSecretResult(TEvPrivate::TEvResolveSecretResult::TPtr& ev, const TActorContext& ctx);
120123

121124
// other
122125
template <typename T>

ydb/core/tx/replication/controller/private_events.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,33 @@ TString TEvPrivate::TEvUpdateTenantNodes::ToString() const {
181181
<< " }";
182182
}
183183

184+
TEvPrivate::TEvResolveSecretResult::TEvResolveSecretResult(ui64 rid, const TString& secretValue)
185+
: ReplicationId(rid)
186+
, SecretValue(secretValue)
187+
, Success(true)
188+
{
189+
}
190+
191+
TEvPrivate::TEvResolveSecretResult::TEvResolveSecretResult(ui64 rid, bool success, const TString& error)
192+
: ReplicationId(rid)
193+
, Success(success)
194+
, Error(error)
195+
{
196+
Y_ABORT_UNLESS(!success);
197+
}
198+
199+
TString TEvPrivate::TEvResolveSecretResult::ToString() const {
200+
return TStringBuilder() << ToStringHeader() << " {"
201+
<< " ReplicationId: " << ReplicationId
202+
<< " Success: " << Success
203+
<< " Error: " << Error
204+
<< " }";
205+
}
206+
207+
bool TEvPrivate::TEvResolveSecretResult::IsSuccess() const {
208+
return Success;
209+
}
210+
184211
}
185212

186213
Y_DECLARE_OUT_SPEC(, NKikimr::NReplication::NController::TEvPrivate::TEvDiscoveryTargetsResult::TAddEntry, stream, value) {

ydb/core/tx/replication/controller/private_events.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct TEvPrivate {
2121
EvResolveTenantResult,
2222
EvUpdateTenantNodes,
2323
EvRunWorkers,
24+
EvResolveSecretResult,
2425

2526
EvEnd,
2627
};
@@ -129,6 +130,19 @@ struct TEvPrivate {
129130
struct TEvRunWorkers: public TEventLocal<TEvRunWorkers, EvRunWorkers> {
130131
};
131132

133+
struct TEvResolveSecretResult: public TEventLocal<TEvResolveSecretResult, EvResolveSecretResult> {
134+
const ui64 ReplicationId;
135+
const TString SecretValue;
136+
const bool Success;
137+
const TString Error;
138+
139+
explicit TEvResolveSecretResult(ui64 rid, const TString& secretValue);
140+
explicit TEvResolveSecretResult(ui64 rid, bool success, const TString& error);
141+
TString ToString() const override;
142+
143+
bool IsSuccess() const;
144+
};
145+
132146
}; // TEvPrivate
133147

134148
}

ydb/core/tx/replication/controller/replication.cpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "private_events.h"
22
#include "replication.h"
3+
#include "secret_resolver.h"
34
#include "target_discoverer.h"
45
#include "target_table.h"
56
#include "tenant_resolver.h"
@@ -18,6 +19,14 @@ namespace NKikimr::NReplication::NController {
1819
class TReplication::TImpl {
1920
friend class TReplication;
2021

22+
void ResolveSecret(const TString& secretName, const TActorContext& ctx) {
23+
if (SecretResolver) {
24+
return;
25+
}
26+
27+
SecretResolver = ctx.Register(CreateSecretResolver(ctx.SelfID, ReplicationId, PathId, secretName));
28+
}
29+
2130
template <typename... Args>
2231
ITarget* CreateTarget(ui64 id, ETargetKind kind, Args&&... args) const {
2332
switch (kind) {
@@ -95,9 +104,15 @@ class TReplication::TImpl {
95104

96105
switch (params.GetCredentialsCase()) {
97106
case NKikimrReplication::TConnectionParams::kStaticCredentials:
107+
if (!params.GetStaticCredentials().HasPassword()) {
108+
return ResolveSecret(params.GetStaticCredentials().GetPasswordSecretName(), ctx);
109+
}
98110
ydbProxy.Reset(CreateYdbProxy(params.GetEndpoint(), params.GetDatabase(), params.GetStaticCredentials()));
99111
break;
100112
case NKikimrReplication::TConnectionParams::kOAuthToken:
113+
if (!params.GetOAuthToken().HasToken()) {
114+
return ResolveSecret(params.GetOAuthToken().GetTokenSecretName(), ctx);
115+
}
101116
ydbProxy.Reset(CreateYdbProxy(params.GetEndpoint(), params.GetDatabase(), params.GetOAuthToken().GetToken()));
102117
break;
103118
default:
@@ -139,7 +154,7 @@ class TReplication::TImpl {
139154
target->Shutdown(ctx);
140155
}
141156

142-
for (auto* x : TVector<TActorId*>{&TargetDiscoverer, &TenantResolver, &YdbProxy}) {
157+
for (auto* x : TVector<TActorId*>{&SecretResolver, &TargetDiscoverer, &TenantResolver, &YdbProxy}) {
143158
if (auto actorId = std::exchange(*x, {})) {
144159
ctx.Send(actorId, new TEvents::TEvPoison());
145160
}
@@ -165,6 +180,7 @@ class TReplication::TImpl {
165180
TString Issue;
166181
ui64 NextTargetId = 1;
167182
THashMap<ui64, THolder<ITarget>> Targets;
183+
TActorId SecretResolver;
168184
TActorId YdbProxy;
169185
TActorId TenantResolver;
170186
TActorId TargetDiscoverer;
@@ -261,6 +277,20 @@ ui64 TReplication::GetNextTargetId() const {
261277
return Impl->NextTargetId;
262278
}
263279

280+
void TReplication::UpdateSecret(const TString& secretValue) {
281+
auto& params = *Impl->Config.MutableSrcConnectionParams();
282+
switch (params.GetCredentialsCase()) {
283+
case NKikimrReplication::TConnectionParams::kStaticCredentials:
284+
params.MutableStaticCredentials()->SetPassword(secretValue);
285+
break;
286+
case NKikimrReplication::TConnectionParams::kOAuthToken:
287+
params.MutableOAuthToken()->SetToken(secretValue);
288+
break;
289+
default:
290+
Y_ABORT("unreachable");
291+
}
292+
}
293+
264294
void TReplication::SetTenant(const TString& value) {
265295
Impl->Tenant = value;
266296
Impl->TenantResolver = {};

ydb/core/tx/replication/controller/replication.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ class TReplication: public TSimpleRefCount<TReplication> {
109109
void SetNextTargetId(ui64 value);
110110
ui64 GetNextTargetId() const;
111111

112+
void UpdateSecret(const TString& secretValue);
113+
112114
void SetTenant(const TString& value);
113115
const TString& GetTenant() const;
114116

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#include "logging.h"
2+
#include "private_events.h"
3+
#include "secret_resolver.h"
4+
5+
#include <ydb/core/tx/scheme_cache/scheme_cache.h>
6+
#include <ydb/library/actors/core/actor_bootstrapped.h>
7+
#include <ydb/library/actors/core/hfunc.h>
8+
#include <ydb/services/metadata/secret/fetcher.h>
9+
#include <ydb/services/metadata/secret/secret.h>
10+
#include <ydb/services/metadata/secret/snapshot.h>
11+
#include <ydb/services/metadata/service.h>
12+
13+
namespace NKikimr::NReplication::NController {
14+
15+
class TSecretResolver: public TActorBootstrapped<TSecretResolver> {
16+
static NMetadata::NFetcher::ISnapshotsFetcher::TPtr SnapshotFetcher() {
17+
return std::make_shared<NMetadata::NSecret::TSnapshotsFetcher>();
18+
}
19+
20+
void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
21+
const auto* response = ev->Get()->Request.Get();
22+
23+
Y_ABORT_UNLESS(response->ResultSet.size() == 1);
24+
const auto& entry = response->ResultSet.front();
25+
26+
LOG_T("Handle " << ev->Get()->ToString()
27+
<< ": entry# " << entry.ToString());
28+
29+
switch (entry.Status) {
30+
case NSchemeCache::TSchemeCacheNavigate::EStatus::Ok:
31+
break;
32+
default:
33+
LOG_W("Unexpected status"
34+
<< ": entry# " << entry.ToString());
35+
return Schedule(RetryInterval, new TEvents::TEvWakeup);
36+
}
37+
38+
if (!entry.SecurityObject) {
39+
return Reply(false, "Empty security object");
40+
}
41+
42+
SecretId = NMetadata::NSecret::TSecretId(entry.SecurityObject->GetOwnerSID(), SecretName);
43+
Send(NMetadata::NProvider::MakeServiceId(SelfId().NodeId()),
44+
new NMetadata::NProvider::TEvAskSnapshot(SnapshotFetcher()));
45+
}
46+
47+
void Handle(NMetadata::NProvider::TEvRefreshSubscriberData::TPtr& ev) {
48+
const auto* snapshot = ev->Get()->GetSnapshotAs<NMetadata::NSecret::TSnapshot>();
49+
50+
TString secretValue;
51+
if (!snapshot->GetSecretValue(NMetadata::NSecret::TSecretIdOrValue::BuildAsId(SecretId), secretValue)) {
52+
return Reply(false, TStringBuilder() << "Secret '" << SecretName << "' not found");
53+
}
54+
55+
Reply(secretValue);
56+
}
57+
58+
template <typename... Args>
59+
void Reply(Args&&... args) {
60+
Send(Parent, new TEvPrivate::TEvResolveSecretResult(ReplicationId, std::forward<Args>(args)...));
61+
PassAway();
62+
}
63+
64+
public:
65+
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
66+
return NKikimrServices::TActivity::REPLICATION_CONTROLLER_SECRET_RESOLVER;
67+
}
68+
69+
explicit TSecretResolver(const TActorId& parent, ui64 rid, const TPathId& pathId, const TString& secretName)
70+
: Parent(parent)
71+
, ReplicationId(rid)
72+
, PathId(pathId)
73+
, SecretName(secretName)
74+
, LogPrefix("SecretResolver", ReplicationId)
75+
{
76+
}
77+
78+
void Bootstrap() {
79+
if (!NMetadata::NProvider::TServiceOperator::IsEnabled()) {
80+
return Reply(false, "Metadata service is not active");
81+
}
82+
83+
auto request = MakeHolder<NSchemeCache::TSchemeCacheNavigate>();
84+
85+
auto& entry = request->ResultSet.emplace_back();
86+
entry.TableId = PathId;
87+
entry.RequestType = NSchemeCache::TSchemeCacheNavigate::TEntry::ERequestType::ByTableId;
88+
entry.Operation = NSchemeCache::TSchemeCacheNavigate::OpPath;
89+
entry.RedirectRequired = false;
90+
91+
Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(request.Release()));
92+
Become(&TThis::StateWork);
93+
}
94+
95+
STATEFN(StateWork) {
96+
switch (ev->GetTypeRewrite()) {
97+
hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle);
98+
hFunc(NMetadata::NProvider::TEvRefreshSubscriberData, Handle);
99+
sFunc(TEvents::TEvWakeup, Bootstrap);
100+
sFunc(TEvents::TEvPoison, PassAway);
101+
}
102+
}
103+
104+
private:
105+
const TActorId Parent;
106+
const ui64 ReplicationId;
107+
const TPathId PathId;
108+
const TString SecretName;
109+
const TActorLogPrefix LogPrefix;
110+
111+
static constexpr auto RetryInterval = TDuration::Seconds(1);
112+
NMetadata::NSecret::TSecretId SecretId;
113+
114+
}; // TSecretResolver
115+
116+
IActor* CreateSecretResolver(const TActorId& parent, ui64 rid, const TPathId& pathId, const TString& secretName) {
117+
return new TSecretResolver(parent, rid, pathId, secretName);
118+
}
119+
120+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
3+
#include <ydb/core/base/defs.h>
4+
5+
namespace NKikimr::NReplication::NController {
6+
7+
IActor* CreateSecretResolver(const TActorId& parent, ui64 rid, const TPathId& pathId, const TString& secretName);
8+
9+
}

0 commit comments

Comments
 (0)