1313import org .elasticsearch .common .io .stream .Writeable ;
1414import org .elasticsearch .common .xcontent .XContentParserUtils ;
1515import org .elasticsearch .core .Nullable ;
16+ import org .elasticsearch .transport .TcpTransport ;
1617import org .elasticsearch .xcontent .ConstructingObjectParser ;
1718import org .elasticsearch .xcontent .ObjectParser ;
1819import org .elasticsearch .xcontent .ParseField ;
@@ -80,6 +81,7 @@ public String value() {
8081
8182 private final String name ;
8283 private final String id ;
84+ private final Type type ;
8385 private final Instant creation ;
8486 private final Instant expiration ;
8587 private final boolean invalidated ;
@@ -94,6 +96,7 @@ public String value() {
9496 public ApiKey (
9597 String name ,
9698 String id ,
99+ Type type ,
97100 Instant creation ,
98101 Instant expiration ,
99102 boolean invalidated ,
@@ -106,6 +109,7 @@ public ApiKey(
106109 this (
107110 name ,
108111 id ,
112+ type ,
109113 creation ,
110114 expiration ,
111115 invalidated ,
@@ -120,6 +124,7 @@ public ApiKey(
120124 private ApiKey (
121125 String name ,
122126 String id ,
127+ Type type ,
123128 Instant creation ,
124129 Instant expiration ,
125130 boolean invalidated ,
@@ -131,6 +136,7 @@ private ApiKey(
131136 ) {
132137 this .name = name ;
133138 this .id = id ;
139+ this .type = type ;
134140 // As we do not yet support the nanosecond precision when we serialize to JSON,
135141 // here creating the 'Instant' of milliseconds precision.
136142 // This Instant can then be used for date comparison.
@@ -153,6 +159,14 @@ public ApiKey(StreamInput in) throws IOException {
153159 this .name = in .readString ();
154160 }
155161 this .id = in .readString ();
162+ if (in .getTransportVersion ().onOrAfter (TransportVersion .V_8_500_001 )) {
163+ this .type = in .readEnum (Type .class );
164+ } else {
165+ // This default is safe because
166+ // 1. ApiKey objects never transfer between nodes
167+ // 2. Creating cross-cluster API keys mandates minimal node version that understands the API key type
168+ this .type = Type .REST ;
169+ }
156170 this .creation = in .readInstant ();
157171 this .expiration = in .readOptionalInstant ();
158172 this .invalidated = in .readBoolean ();
@@ -181,6 +195,10 @@ public String getName() {
181195 return name ;
182196 }
183197
198+ public Type getType () {
199+ return type ;
200+ }
201+
184202 public Instant getCreation () {
185203 return creation ;
186204 }
@@ -221,7 +239,11 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
221239 }
222240
223241 public XContentBuilder innerToXContent (XContentBuilder builder , Params params ) throws IOException {
224- builder .field ("id" , id ).field ("name" , name ).field ("creation" , creation .toEpochMilli ());
242+ builder .field ("id" , id ).field ("name" , name );
243+ if (TcpTransport .isUntrustedRemoteClusterEnabled ()) {
244+ builder .field ("type" , type .value ());
245+ }
246+ builder .field ("creation" , creation .toEpochMilli ());
225247 if (expiration != null ) {
226248 builder .field ("expiration" , expiration .toEpochMilli ());
227249 }
@@ -237,6 +259,7 @@ public XContentBuilder innerToXContent(XContentBuilder builder, Params params) t
237259 builder .endObject ();
238260 }
239261 if (limitedBy != null ) {
262+ assert type != Type .CROSS_CLUSTER ;
240263 builder .field ("limited_by" , limitedBy );
241264 }
242265 return builder ;
@@ -250,6 +273,9 @@ public void writeTo(StreamOutput out) throws IOException {
250273 out .writeString (name );
251274 }
252275 out .writeString (id );
276+ if (out .getTransportVersion ().onOrAfter (TransportVersion .V_8_500_001 )) {
277+ out .writeEnum (type );
278+ }
253279 out .writeInstant (creation );
254280 out .writeOptionalInstant (expiration );
255281 out .writeBoolean (invalidated );
@@ -266,7 +292,7 @@ public void writeTo(StreamOutput out) throws IOException {
266292
267293 @ Override
268294 public int hashCode () {
269- return Objects .hash (name , id , creation , expiration , invalidated , username , realm , metadata , roleDescriptors , limitedBy );
295+ return Objects .hash (name , id , type , creation , expiration , invalidated , username , realm , metadata , roleDescriptors , limitedBy );
270296 }
271297
272298 @ Override
@@ -283,6 +309,7 @@ public boolean equals(Object obj) {
283309 ApiKey other = (ApiKey ) obj ;
284310 return Objects .equals (name , other .name )
285311 && Objects .equals (id , other .id )
312+ && Objects .equals (type , other .type )
286313 && Objects .equals (creation , other .creation )
287314 && Objects .equals (expiration , other .expiration )
288315 && Objects .equals (invalidated , other .invalidated )
@@ -298,19 +325,22 @@ public boolean equals(Object obj) {
298325 return new ApiKey (
299326 (String ) args [0 ],
300327 (String ) args [1 ],
301- Instant .ofEpochMilli ((Long ) args [2 ]),
302- (args [3 ] == null ) ? null : Instant .ofEpochMilli ((Long ) args [3 ]),
303- (Boolean ) args [4 ],
304- (String ) args [5 ],
328+ // TODO: remove null check once TcpTransport.isUntrustedRemoteClusterEnabled() is removed
329+ args [2 ] == null ? Type .REST : (Type ) args [2 ],
330+ Instant .ofEpochMilli ((Long ) args [3 ]),
331+ (args [4 ] == null ) ? null : Instant .ofEpochMilli ((Long ) args [4 ]),
332+ (Boolean ) args [5 ],
305333 (String ) args [6 ],
306- (args [7 ] == null ) ? null : (Map <String , Object >) args [7 ],
307- (List <RoleDescriptor >) args [8 ],
308- (RoleDescriptorsIntersection ) args [9 ]
334+ (String ) args [7 ],
335+ (args [8 ] == null ) ? null : (Map <String , Object >) args [8 ],
336+ (List <RoleDescriptor >) args [9 ],
337+ (RoleDescriptorsIntersection ) args [10 ]
309338 );
310339 });
311340 static {
312341 PARSER .declareString (constructorArg (), new ParseField ("name" ));
313342 PARSER .declareString (constructorArg (), new ParseField ("id" ));
343+ PARSER .declareField (optionalConstructorArg (), Type ::fromXContent , new ParseField ("type" ), ObjectParser .ValueType .STRING );
314344 PARSER .declareLong (constructorArg (), new ParseField ("creation" ));
315345 PARSER .declareLong (optionalConstructorArg (), new ParseField ("expiration" ));
316346 PARSER .declareBoolean (constructorArg (), new ParseField ("invalidated" ));
@@ -339,6 +369,8 @@ public String toString() {
339369 + name
340370 + ", id="
341371 + id
372+ + ", type="
373+ + type .value ()
342374 + ", creation="
343375 + creation
344376 + ", expiration="
0 commit comments