in pkg/controller/remotecluster/apikey.go [25:115]
func reconcileAPIKeys(
ctx context.Context,
c k8s.Client,
activeAPIKeys esclient.CrossClusterAPIKeyList, // all the API Keys in the reconciled/local cluster
remoteServerES *esv1.Elasticsearch, // the Elasticsearch cluster being reconciled, where the API keys must be created/invalidated
remoteClientES *esv1.Elasticsearch, // the remote Elasticsearch cluster which is going to act as the client, where the API keys are going to be stored in the keystore Secret
remoteClusterRefs []esv1.RemoteCluster, // the expected API keys for that client cluster
esClient esclient.Client, // ES client for the reconciled cluster which is going to act as the server
keystoreProvider *keystore.Provider,
) *reconciler.Results {
log := ulog.FromContext(ctx).WithValues(
"remote_server_namespace", remoteServerES.Namespace,
"remote_server_name", remoteServerES.Name,
"remote_client_namespace", remoteClientES.Namespace,
"remote_client_name", remoteClientES.Name,
)
results := &reconciler.Results{}
// clientClusterAPIKeyStore is used to reconcile encoded API keys in the client cluster, to inject new API keys
// or to delete the ones which are no longer needed.
clientClusterAPIKeyStore, err := keystoreProvider.ForCluster(ctx, log, remoteClientES)
if err != nil {
return results.WithError(err)
}
// Maintain a list of the expected API keys for that specific client cluster, to detect the ones which are no longer expected in the reconciled cluster.
expectedKeysInRemoteServerES := sets.New[string]()
// Same for the aliases
expectedAliases := sets.New[string]()
activeAPIKeysNames := activeAPIKeys.KeyNames()
for _, remoteClusterRef := range remoteClusterRefs {
apiKeyName := fmt.Sprintf("eck-%s-%s-%s", remoteClientES.Namespace, remoteClientES.Name, remoteClusterRef.Name)
expectedKeysInRemoteServerES.Insert(apiKeyName)
expectedAliases.Insert(remoteClusterRef.Name)
if remoteClusterRef.APIKey == nil {
if activeAPIKeysNames.Has(apiKeyName) {
// We found an API key for that client cluster while it is not expected to have one.
// It may happen when the user switched back from API keys to the legacy remote cluster.
log.Info("Invalidating API key as remote cluster is not configured to use it", "alias", remoteClusterRef.Name)
if err := esClient.InvalidateCrossClusterAPIKey(ctx, apiKeyName); err != nil {
return results.WithError(err)
}
}
continue
}
// Attempt to get an existing API Key with that key name.
activeAPIKey := activeAPIKeys.GetActiveKeyWithName(apiKeyName)
expectedHash := hash.HashObject(remoteClusterRef.APIKey)
if activeAPIKey == nil {
if err := createAPIKey(ctx, log, remoteClusterRef, apiKeyName, esClient, remoteClientES, expectedHash, clientClusterAPIKeyStore, remoteServerES); err != nil {
return results.WithError(err)
}
} else {
// If an API key already exists ensure that the access field is the expected one using the hash
if err := maybeUpdateAPIKey(ctx, log, esClient, clientClusterAPIKeyStore, remoteClusterRef, activeAPIKey, apiKeyName, remoteClientES, expectedHash); err != nil {
return results.WithError(err)
}
}
}
// Get all the active API keys which have been created for that client cluster.
activeAPIKeysForClientCluster, err := activeAPIKeys.ForCluster(remoteClientES.Namespace, remoteClientES.Name)
if err != nil {
return results.WithError(err)
}
// Invalidate all the keys related to that local cluster which are not expected.
for keyName := range activeAPIKeysForClientCluster.KeyNames() {
if !expectedKeysInRemoteServerES.Has(keyName) {
// Unexpected key, let's invalidate it.
log.Info("Invalidating unexpected API key", "key", keyName)
if err := esClient.InvalidateCrossClusterAPIKey(ctx, keyName); err != nil {
return results.WithError(err)
}
}
}
// Delete all the keys in the keystore which are not expected.
aliases := clientClusterAPIKeyStore.ForCluster(remoteServerES.Namespace, remoteServerES.Name)
for existingAlias := range aliases {
if expectedAliases.Has(existingAlias) {
continue
}
clientClusterAPIKeyStore.Delete(existingAlias)
}
// Save the generated keys in the keystore.
if err := clientClusterAPIKeyStore.Save(ctx, c, remoteClientES); err != nil {
return err
}
return nil
}