1
#include "source/extensions/common/aws/credentials_provider.h"
2

            
3
#include "source/common/common/lock_guard.h"
4

            
5
namespace Envoy {
6
namespace Extensions {
7
namespace Common {
8
namespace Aws {
9

            
10
92
Credentials CredentialsProviderChain::chainGetCredentials() {
11
94
  for (auto& provider : providers_) {
12
94
    const auto credentials = provider->getCredentials();
13
94
    if (credentials.hasCredentials()) {
14
87
      return credentials;
15
87
    }
16
94
  }
17

            
18
5
  ENVOY_LOG(debug, "No AWS credentials found, using anonymous credentials");
19
5
  return Credentials();
20
92
}
21

            
22
void CredentialsProviderChain::storeSubscription(
23
84
    CredentialSubscriberCallbacksHandlePtr subscription) {
24
84
  subscriber_handles_.push_back(std::move(subscription));
25
84
}
26

            
27
// Determine if we have a provider that is pending, based on priority ordering in the chain.
28
// Ignore any non-pending providers that have no credentials for us.
29

            
30
44
bool CredentialsProviderChain::chainProvidersPending() {
31
50
  for (auto& provider : providers_) {
32
50
    if (provider->credentialsPending()) {
33
6
      ENVOY_LOG(debug, "Provider {} is still pending", provider->providerName());
34
6
      return true;
35
6
    }
36
44
    if (provider->getCredentials().hasCredentials()) {
37
36
      ENVOY_LOG(debug, "Provider {} has credentials", provider->providerName());
38
36
      break;
39
38
    } else {
40
8
      ENVOY_LOG(debug, "Provider {} has blank credentials, continuing through chain",
41
8
                provider->providerName());
42
8
    }
43
44
  }
44
38
  return false;
45
44
}
46

            
47
bool CredentialsProviderChain::addCallbackIfChainCredentialsPending(
48
39
    CredentialsPendingCallback&& cb) {
49
39
  if (!chainProvidersPending()) {
50
36
    return false;
51
36
  }
52
3
  if (cb) {
53
2
    ENVOY_LOG(debug, "Adding credentials pending callback to queue");
54
2
    Thread::LockGuard guard(mu_);
55
2
    credential_pending_callbacks_.push_back(std::move(cb));
56
2
    ENVOY_LOG(debug, "We have {} pending callbacks", credential_pending_callbacks_.size());
57
2
  }
58
3
  return true;
59
39
}
60

            
61
5
void CredentialsProviderChain::onCredentialUpdate() {
62
5
  if (chainProvidersPending()) {
63
3
    return;
64
3
  }
65

            
66
2
  std::vector<CredentialsPendingCallback> callbacks_copy;
67

            
68
2
  {
69
2
    Thread::LockGuard guard(mu_);
70
2
    callbacks_copy = credential_pending_callbacks_;
71
2
    credential_pending_callbacks_.clear();
72
2
  }
73

            
74
2
  ENVOY_LOG(debug, "Notifying {} credential callbacks", callbacks_copy.size());
75

            
76
  // Call all of our callbacks to unblock pending requests
77
2
  for (const auto& cb : callbacks_copy) {
78
2
    cb();
79
2
  }
80
2
}
81

            
82
} // namespace Aws
83
} // namespace Common
84
} // namespace Extensions
85
} // namespace Envoy