Come posso ottenere un token di autenticazione Kubernetes da AWS EKS utilizzando AWS Java SDK v2? Un token di autenticazione che può quindi essere utilizzato per l'autenticazione con Kubernetes utilizzando un SDK Kubernetes. In altre parole, voglio ottenere un token di autenticazione da EKS da utilizzare per l'autenticazione con Kubernetes in modo da non dover creare una "configurazione kube".
In realtà ho trovato una soluzione che funziona con AWS Java SDK v1 (non v2) guardando gli esempi di codice nel seguente numero aperto . C'è anche un esempio di codice Python qui, ma non sto avendo alcun successo con AWS Java SDK v2. Il mio tentativo di farlo con AWS Java SDK v2:
public static String getAuthenticationToken(AwsCredentialsProvider awsAuth, Region awsRegion, String clusterName) {
try {
SdkHttpFullRequest requestToSign = SdkHttpFullRequest
.builder()
.method(SdkHttpMethod.GET)
.uri(new URI("https", String.format("sts.%s.amazonaws.com", awsRegion.id()), null, null))
.appendHeader("x-k8s-aws-id", clusterName)
.appendRawQueryParameter("Action", "GetCallerIdentity")
.appendRawQueryParameter("Version", "2011-06-15")
.build();
ZonedDateTime expirationDate = DateUtil.addSeconds(DateUtil.now(), 60);
Aws4PresignerParams presignerParams = Aws4PresignerParams.builder()
.awsCredentials(awsAuth.resolveCredentials())
.expirationTime(expirationDate.toInstant())
.signingName("sts")
.signingRegion(awsRegion)
.build();
SdkHttpFullRequest signedRequest = Aws4Signer.create().presign(requestToSign, presignerParams);
String encodedUrl = Base64.getUrlEncoder().withoutPadding().encodeToString(signedRequest.getUri().toString().getBytes(CharSet.UTF_8.getCharset()));
return ("k8s-aws-v1." + encodedUrl);
} catch (Exception e) {
String errorMessage = "A problem occurred generating an Eks token";
logger.error(errorMessage, e);
throw new RuntimeException(errorMessage, e);
}
}
Genera un token, ma quando uso il token nel mio client Kubernetes (l'SDK ufficiale di Kubernetes Java) ricevo una risposta "Non autorizzata" - quindi mi manca qualcosa su cui non riesco a mettere il dito ...
La versione di AWS Java SDK v1 è simile alla seguente: (Dalla questione aperta menzionata in precedenza)
Ho funzionato, ma sto lottando per ottenere qualcosa di simile al lavoro in AWS Java SDK v2.
private String generateToken(String clusterName,
Date expirationDate,
String serviceName,
String region,
AWSSecurityTokenServiceClient awsSecurityTokenServiceClient,
AWSCredentialsProvider credentialsProvider,
String scheme,
String host) throws URISyntaxException {
try {
DefaultRequest<GetCallerIdentityRequest> callerIdentityRequestDefaultRequest = new DefaultRequest<>(new GetCallerIdentityRequest(), serviceName);
URI uri = new URI(scheme, host, null, null);
callerIdentityRequestDefaultRequest.setResourcePath("/");
callerIdentityRequestDefaultRequest.setEndpoint(uri);
callerIdentityRequestDefaultRequest.setHttpMethod(HttpMethodName.GET);
callerIdentityRequestDefaultRequest.addParameter("Action", "GetCallerIdentity");
callerIdentityRequestDefaultRequest.addParameter("Version", "2011-06-15");
callerIdentityRequestDefaultRequest.addHeader("x-k8s-aws-id", clusterName);
Signer signer = SignerFactory.createSigner(SignerFactory.VERSION_FOUR_SIGNER, new SignerParams(serviceName, region));
SignerProvider signerProvider = new DefaultSignerProvider(awsSecurityTokenServiceClient, signer);
PresignerParams presignerParams = new PresignerParams(uri,
credentialsProvider,
signerProvider,
SdkClock.STANDARD);
PresignerFacade presignerFacade = new PresignerFacade(presignerParams);
URL url = presignerFacade.presign(callerIdentityRequestDefaultRequest, expirationDate);
String encodedUrl = Base64.getUrlEncoder().withoutPadding().encodeToString(url.toString().getBytes());
log.info("Token [{}]", encodedUrl);
return "k8s-aws-v1." + encodedUrl;
} catch (URISyntaxException e) {
log.error("could not generate token", e);
throw e;
}
}