1
1
package io .scalecube .security .vault ;
2
2
3
+ import static io .scalecube .utils .MaskUtil .mask ;
4
+
3
5
import com .bettercloud .vault .json .Json ;
4
6
import com .bettercloud .vault .rest .Rest ;
5
7
import com .bettercloud .vault .rest .RestException ;
6
8
import com .bettercloud .vault .rest .RestResponse ;
7
- import io .scalecube .utils .MaskUtil ;
8
9
import java .util .Map ;
10
+ import java .util .Objects ;
9
11
import java .util .StringJoiner ;
10
12
import java .util .function .BiFunction ;
11
- import java .util .function .Supplier ;
12
13
import org .slf4j .Logger ;
13
14
import org .slf4j .LoggerFactory ;
14
15
import reactor .core .Exceptions ;
15
16
import reactor .core .publisher .Mono ;
17
+ import reactor .core .scheduler .Schedulers ;
16
18
17
19
public final class VaultServiceTokenSupplier {
18
20
@@ -22,7 +24,7 @@ public final class VaultServiceTokenSupplier {
22
24
23
25
private String serviceRole ;
24
26
private String vaultAddress ;
25
- private Supplier <String > vaultTokenSupplier ;
27
+ private Mono <String > vaultTokenSupplier ;
26
28
private BiFunction <String , Map <String , String >, String > serviceTokenNameBuilder ;
27
29
28
30
public VaultServiceTokenSupplier () {}
@@ -34,6 +36,18 @@ private VaultServiceTokenSupplier(VaultServiceTokenSupplier other) {
34
36
this .serviceTokenNameBuilder = other .serviceTokenNameBuilder ;
35
37
}
36
38
39
+ private VaultServiceTokenSupplier copy () {
40
+ return new VaultServiceTokenSupplier (this );
41
+ }
42
+
43
+ private void validate () {
44
+ Objects .requireNonNull (serviceRole , "VaultServiceTokenSupplier.serviceRole" );
45
+ Objects .requireNonNull (vaultAddress , "VaultServiceTokenSupplier.vaultAddress" );
46
+ Objects .requireNonNull (vaultTokenSupplier , "VaultServiceTokenSupplier.vaultTokenSupplier" );
47
+ Objects .requireNonNull (
48
+ serviceTokenNameBuilder , "VaultServiceTokenSupplier.serviceTokenNameBuilder" );
49
+ }
50
+
37
51
/**
38
52
* Setter for serviceRole.
39
53
*
@@ -64,7 +78,7 @@ public VaultServiceTokenSupplier vaultAddress(String vaultAddress) {
64
78
* @param vaultTokenSupplier vaultTokenSupplier
65
79
* @return new instance with applied setting
66
80
*/
67
- public VaultServiceTokenSupplier vaultTokenSupplier (Supplier <String > vaultTokenSupplier ) {
81
+ public VaultServiceTokenSupplier vaultTokenSupplier (Mono <String > vaultTokenSupplier ) {
68
82
final VaultServiceTokenSupplier c = copy ();
69
83
c .vaultTokenSupplier = vaultTokenSupplier ;
70
84
return c ;
@@ -85,59 +99,72 @@ public VaultServiceTokenSupplier serviceTokenNameBuilder(
85
99
}
86
100
87
101
/**
88
- * Returns credentials as {@code Map<String, String>} for the given args .
102
+ * Obtains vault service token (aka identity token or oidc token) .
89
103
*
90
- * @param tags tags attributes
104
+ * @param tags tags attributes; along with {@code serviceRole} will be applied on {@code
105
+ * serviceTokenNameBuilder}
91
106
* @return vault service token
92
107
*/
93
- public Mono <String > getServiceToken (Map <String , String > tags ) {
94
- return Mono .fromCallable (vaultTokenSupplier ::get )
95
- .map (vaultToken -> rpcGetServiceToken (tags , vaultToken ))
96
- .doOnNext (response -> verifyOk (response .getStatus ()))
97
- .map (
98
- response ->
99
- Json .parse (new String (response .getBody ()))
100
- .asObject ()
101
- .get ("data" )
102
- .asObject ()
103
- .get ("token" )
104
- .asString ())
105
- .doOnSuccess (
106
- creds ->
107
- LOGGER .info (
108
- "[rpcGetServiceToken] Successfully obtained vault service token: {}" ,
109
- MaskUtil .mask (creds )));
108
+ public Mono <String > getToken (Map <String , String > tags ) {
109
+ return Mono .fromRunnable (this ::validate )
110
+ .then (Mono .defer (() -> vaultTokenSupplier ))
111
+ .flatMap (
112
+ vaultToken -> {
113
+ final String uri = buildServiceTokenUri (tags );
114
+ return Mono .fromCallable (() -> rpcGetToken (uri , vaultToken ))
115
+ .subscribeOn (Schedulers .boundedElastic ())
116
+ .doOnSubscribe (
117
+ s ->
118
+ LOGGER .debug (
119
+ "[getToken] Getting vault service token, uri='{}', tags={}" ,
120
+ uri ,
121
+ tags ))
122
+ .doOnSuccess (
123
+ s ->
124
+ LOGGER .debug (
125
+ "[getToken][success] uri='{}', tags={}, result: {}" ,
126
+ uri ,
127
+ tags ,
128
+ mask (s )))
129
+ .doOnError (
130
+ th ->
131
+ LOGGER .error (
132
+ "[getToken][error] uri='{}', tags={}, cause: {}" ,
133
+ uri ,
134
+ tags ,
135
+ th .toString ()));
136
+ });
110
137
}
111
138
112
- private RestResponse rpcGetServiceToken (Map <String , String > tags , String vaultToken ) {
113
- String uri = buildVaultServiceTokenUri (tags );
114
- LOGGER .info ("[rpcGetServiceToken] Getting vault service token (uri='{}')" , uri );
139
+ private String rpcGetToken (String uri , String vaultToken ) {
115
140
try {
116
- return new Rest ().header (VAULT_TOKEN_HEADER , vaultToken ).url (uri ).get ();
141
+ final RestResponse response =
142
+ new Rest ().header (VAULT_TOKEN_HEADER , vaultToken ).url (uri ).get ();
143
+
144
+ verifyOk (response .getStatus ());
145
+
146
+ return Json .parse (new String (response .getBody ()))
147
+ .asObject ()
148
+ .get ("data" )
149
+ .asObject ()
150
+ .get ("token" )
151
+ .asString ();
117
152
} catch (RestException e ) {
118
- LOGGER .error (
119
- "[rpcGetServiceToken] Failed to get vault service token (uri='{}'), cause: {}" ,
120
- uri ,
121
- e .toString ());
122
153
throw Exceptions .propagate (e );
123
154
}
124
155
}
125
156
126
157
private static void verifyOk (int status ) {
127
158
if (status != 200 ) {
128
- LOGGER .error ("[rpcGetServiceToken ] Not expected status ({}) returned" , status );
159
+ LOGGER .error ("[rpcGetToken ] Not expected status ({}) returned" , status );
129
160
throw new IllegalStateException ("Not expected status returned, status=" + status );
130
161
}
131
162
}
132
163
133
- private String buildVaultServiceTokenUri (Map <String , String > tags ) {
164
+ private String buildServiceTokenUri (Map <String , String > tags ) {
134
165
return new StringJoiner ("/" , vaultAddress , "" )
135
166
.add ("v1/identity/oidc/token" )
136
167
.add (serviceTokenNameBuilder .apply (serviceRole , tags ))
137
168
.toString ();
138
169
}
139
-
140
- private VaultServiceTokenSupplier copy () {
141
- return new VaultServiceTokenSupplier (this );
142
- }
143
170
}
0 commit comments