#pragma once #include "config.h" #if USE_AWS_S3 # include # include # include # include # include # include # include # include namespace DB::S3 { /// In GCP metadata service can be accessed via DNS regardless of IPv4 or IPv6. static inline constexpr char GCP_METADATA_SERVICE_ENDPOINT[] = "http://metadata.google.internal"; /// getRunningAvailabilityZone returns the availability zone of the underlying compute resources where the current process runs. std::string getRunningAvailabilityZone(); std::string tryGetRunningAvailabilityZone(); class AWSEC2MetadataClient : public Aws::Internal::AWSHttpResourceClient { static constexpr char EC2_SECURITY_CREDENTIALS_RESOURCE[] = "/latest/meta-data/iam/security-credentials"; static constexpr char EC2_AVAILABILITY_ZONE_RESOURCE[] = "/latest/meta-data/placement/availability-zone"; static constexpr char EC2_IMDS_TOKEN_RESOURCE[] = "/latest/api/token"; static constexpr char EC2_IMDS_TOKEN_HEADER[] = "x-aws-ec2-metadata-token"; static constexpr char EC2_IMDS_TOKEN_TTL_DEFAULT_VALUE[] = "21600"; static constexpr char EC2_IMDS_TOKEN_TTL_HEADER[] = "x-aws-ec2-metadata-token-ttl-seconds"; public: /// See EC2MetadataClient. explicit AWSEC2MetadataClient(const Aws::Client::ClientConfiguration & client_configuration, const char * endpoint_); AWSEC2MetadataClient& operator =(const AWSEC2MetadataClient & rhs) = delete; AWSEC2MetadataClient(const AWSEC2MetadataClient & rhs) = delete; AWSEC2MetadataClient& operator =(const AWSEC2MetadataClient && rhs) = delete; AWSEC2MetadataClient(const AWSEC2MetadataClient && rhs) = delete; ~AWSEC2MetadataClient() override = default; using Aws::Internal::AWSHttpResourceClient::GetResource; virtual Aws::String GetResource(const char * resource_path) const; virtual Aws::String getDefaultCredentials() const; static Aws::String awsComputeUserAgentString(); virtual Aws::String getDefaultCredentialsSecurely() const; virtual Aws::String getCurrentRegion() const; friend String getRunningAvailabilityZone(); private: std::pair getEC2MetadataToken(const std::string & user_agent_string) const; static String getAvailabilityZoneOrException(); const Aws::String endpoint; mutable std::recursive_mutex token_mutex; mutable Aws::String token; LoggerPtr logger; }; std::shared_ptr createEC2MetadataClient(const Aws::Client::ClientConfiguration & client_configuration); class AWSEC2InstanceProfileConfigLoader : public Aws::Config::AWSProfileConfigLoader { public: explicit AWSEC2InstanceProfileConfigLoader(const std::shared_ptr & client_, bool use_secure_pull_); ~AWSEC2InstanceProfileConfigLoader() override = default; protected: bool LoadInternal() override; private: std::shared_ptr client; bool use_secure_pull; LoggerPtr logger; }; class AWSInstanceProfileCredentialsProvider : public Aws::Auth::AWSCredentialsProvider { public: /// See InstanceProfileCredentialsProvider. explicit AWSInstanceProfileCredentialsProvider(const std::shared_ptr & config_loader); Aws::Auth::AWSCredentials GetAWSCredentials() override; protected: void Reload() override; private: void refreshIfExpired(); std::shared_ptr ec2_metadata_config_loader; Int64 load_frequency_ms; LoggerPtr logger; }; class AwsAuthSTSAssumeRoleWebIdentityCredentialsProvider : public Aws::Auth::AWSCredentialsProvider { /// See STSAssumeRoleWebIdentityCredentialsProvider. public: explicit AwsAuthSTSAssumeRoleWebIdentityCredentialsProvider( DB::S3::PocoHTTPClientConfiguration & aws_client_configuration, uint64_t expiration_window_seconds_); Aws::Auth::AWSCredentials GetAWSCredentials() override; protected: void Reload() override; private: void refreshIfExpired(); std::unique_ptr client; Aws::Auth::AWSCredentials credentials; Aws::String role_arn; Aws::String token_file; Aws::String session_name; Aws::String token; bool initialized = false; LoggerPtr logger; uint64_t expiration_window_seconds; }; class SSOCredentialsProvider : public Aws::Auth::AWSCredentialsProvider { public: SSOCredentialsProvider(DB::S3::PocoHTTPClientConfiguration aws_client_configuration_, uint64_t expiration_window_seconds_); Aws::Auth::AWSCredentials GetAWSCredentials() override; private: Aws::UniquePtr client; Aws::Auth::AWSCredentials credentials; // Profile description variables Aws::String profile_to_use; // The AWS account ID that temporary AWS credentials are resolved for. Aws::String sso_account_id; // The AWS region where the SSO directory for the given sso_start_url is hosted. // This is independent of the general region configuration and MUST NOT be conflated. Aws::String sso_region; // The expiration time of the accessToken. Aws::Utils::DateTime expires_at; // The SSO Token Provider Aws::Auth::SSOBearerTokenProvider bearer_token_provider; DB::S3::PocoHTTPClientConfiguration aws_client_configuration; uint64_t expiration_window_seconds; LoggerPtr logger; void Reload() override; void refreshIfExpired(); Aws::String loadAccessTokenFile(const Aws::String & sso_access_token_path); }; struct CredentialsConfiguration { bool use_environment_credentials = false; bool use_insecure_imds_request = false; uint64_t expiration_window_seconds = DEFAULT_EXPIRATION_WINDOW_SECONDS; bool no_sign_request = false; }; class S3CredentialsProviderChain : public Aws::Auth::AWSCredentialsProviderChain { public: S3CredentialsProviderChain( const DB::S3::PocoHTTPClientConfiguration & configuration, const Aws::Auth::AWSCredentials & credentials, CredentialsConfiguration credentials_configuration); }; } #else # include namespace DB { namespace S3 { std::string getRunningAvailabilityZone(); std::string tryGetRunningAvailabilityZone(); } } #endif