1# frozen_string_literal: true 2 3module Clusters 4 module Aws 5 class FetchCredentialsService 6 attr_reader :provision_role 7 8 MissingRoleError = Class.new(StandardError) 9 10 def initialize(provision_role, provider: nil) 11 @provision_role = provision_role 12 @provider = provider 13 @region = provider&.region || provision_role&.region || Clusters::Providers::Aws::DEFAULT_REGION 14 end 15 16 def execute 17 raise MissingRoleError, 'AWS provisioning role not configured' unless provision_role.present? 18 19 ::Aws::AssumeRoleCredentials.new( 20 client: client, 21 role_arn: provision_role.role_arn, 22 role_session_name: session_name, 23 external_id: provision_role.role_external_id, 24 policy: session_policy 25 ).credentials 26 end 27 28 private 29 30 attr_reader :provider, :region 31 32 def client 33 ::Aws::STS::Client.new(**client_args) 34 end 35 36 def client_args 37 { region: region, credentials: gitlab_credentials }.compact 38 end 39 40 def gitlab_credentials 41 # These are not needed for IAM instance profiles 42 return unless access_key_id.present? && secret_access_key.present? 43 44 ::Aws::Credentials.new(access_key_id, secret_access_key) 45 end 46 47 def access_key_id 48 Gitlab::CurrentSettings.eks_access_key_id 49 end 50 51 def secret_access_key 52 Gitlab::CurrentSettings.eks_secret_access_key 53 end 54 55 ## 56 # If we haven't created a provider record yet, 57 # we restrict ourselves to read-only access so 58 # that we can safely expose credentials to the 59 # frontend (to be used when populating the 60 # creation form). 61 def session_policy 62 if provider.nil? 63 File.read(read_only_policy) 64 end 65 end 66 67 def read_only_policy 68 Rails.root.join('vendor', 'aws', 'iam', "eks_cluster_read_only_policy.json") 69 end 70 71 def session_name 72 if provider.present? 73 "gitlab-eks-cluster-#{provider.cluster_id}-user-#{provision_role.user_id}" 74 else 75 "gitlab-eks-autofill-user-#{provision_role.user_id}" 76 end 77 end 78 end 79 end 80end 81