Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/services/clusters/aws')
-rw-r--r--app/services/clusters/aws/authorize_role_service.rb74
-rw-r--r--app/services/clusters/aws/fetch_credentials_service.rb80
-rw-r--r--app/services/clusters/aws/finalize_creation_service.rb139
-rw-r--r--app/services/clusters/aws/provision_service.rb85
-rw-r--r--app/services/clusters/aws/verify_provision_status_service.rb50
5 files changed, 0 insertions, 428 deletions
diff --git a/app/services/clusters/aws/authorize_role_service.rb b/app/services/clusters/aws/authorize_role_service.rb
deleted file mode 100644
index 7ca20289bf7..00000000000
--- a/app/services/clusters/aws/authorize_role_service.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-# frozen_string_literal: true
-
-module Clusters
- module Aws
- class AuthorizeRoleService
- attr_reader :user
-
- Response = Struct.new(:status, :body)
-
- ERRORS = [
- ActiveRecord::RecordInvalid,
- ActiveRecord::RecordNotFound,
- Clusters::Aws::FetchCredentialsService::MissingRoleError,
- ::Aws::Errors::MissingCredentialsError,
- ::Aws::STS::Errors::ServiceError
- ].freeze
-
- def initialize(user, params:)
- @user = user
- @role_arn = params[:role_arn]
- @region = params[:region]
- end
-
- def execute
- ensure_role_exists!
- update_role_arn!
-
- Response.new(:ok, credentials)
- rescue *ERRORS => e
- Gitlab::ErrorTracking.track_exception(e)
-
- Response.new(:unprocessable_entity, response_details(e))
- end
-
- private
-
- attr_reader :role, :role_arn, :region
-
- def ensure_role_exists!
- @role = ::Aws::Role.find_by_user_id!(user.id)
- end
-
- def update_role_arn!
- role.update!(role_arn: role_arn, region: region)
- end
-
- def credentials
- Clusters::Aws::FetchCredentialsService.new(role).execute
- end
-
- def response_details(exception)
- message =
- case exception
- when ::Aws::STS::Errors::AccessDenied
- _("Access denied: %{error}") % { error: exception.message }
- when ::Aws::STS::Errors::ServiceError
- _("AWS service error: %{error}") % { error: exception.message }
- when ActiveRecord::RecordNotFound
- _("Error: Unable to find AWS role for current user")
- when ActiveRecord::RecordInvalid
- exception.message
- when Clusters::Aws::FetchCredentialsService::MissingRoleError
- _("Error: No AWS provision role found for user")
- when ::Aws::Errors::MissingCredentialsError
- _("Error: No AWS credentials were supplied")
- else
- _('An error occurred while authorizing your role')
- end
-
- { message: message }.compact
- end
- end
- end
-end
diff --git a/app/services/clusters/aws/fetch_credentials_service.rb b/app/services/clusters/aws/fetch_credentials_service.rb
deleted file mode 100644
index e38852c7ec7..00000000000
--- a/app/services/clusters/aws/fetch_credentials_service.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-# frozen_string_literal: true
-
-module Clusters
- module Aws
- class FetchCredentialsService
- attr_reader :provision_role
-
- MissingRoleError = Class.new(StandardError)
-
- def initialize(provision_role, provider: nil)
- @provision_role = provision_role
- @provider = provider
- @region = provider&.region || provision_role&.region || Clusters::Providers::Aws::DEFAULT_REGION
- end
-
- def execute
- raise MissingRoleError, 'AWS provisioning role not configured' unless provision_role.present?
-
- ::Aws::AssumeRoleCredentials.new(
- client: client,
- role_arn: provision_role.role_arn,
- role_session_name: session_name,
- external_id: provision_role.role_external_id,
- policy: session_policy
- ).credentials
- end
-
- private
-
- attr_reader :provider, :region
-
- def client
- ::Aws::STS::Client.new(**client_args)
- end
-
- def client_args
- { region: region, credentials: gitlab_credentials }.compact
- end
-
- def gitlab_credentials
- # These are not needed for IAM instance profiles
- return unless access_key_id.present? && secret_access_key.present?
-
- ::Aws::Credentials.new(access_key_id, secret_access_key)
- end
-
- def access_key_id
- Gitlab::CurrentSettings.eks_access_key_id
- end
-
- def secret_access_key
- Gitlab::CurrentSettings.eks_secret_access_key
- end
-
- ##
- # If we haven't created a provider record yet,
- # we restrict ourselves to read-only access so
- # that we can safely expose credentials to the
- # frontend (to be used when populating the
- # creation form).
- def session_policy
- if provider.nil?
- File.read(read_only_policy)
- end
- end
-
- def read_only_policy
- Rails.root.join('vendor', 'aws', 'iam', "eks_cluster_read_only_policy.json")
- end
-
- def session_name
- if provider.present?
- "gitlab-eks-cluster-#{provider.cluster_id}-user-#{provision_role.user_id}"
- else
- "gitlab-eks-autofill-user-#{provision_role.user_id}"
- end
- end
- end
- end
-end
diff --git a/app/services/clusters/aws/finalize_creation_service.rb b/app/services/clusters/aws/finalize_creation_service.rb
deleted file mode 100644
index 54f07e1d44c..00000000000
--- a/app/services/clusters/aws/finalize_creation_service.rb
+++ /dev/null
@@ -1,139 +0,0 @@
-# frozen_string_literal: true
-
-module Clusters
- module Aws
- class FinalizeCreationService
- include Gitlab::Utils::StrongMemoize
-
- attr_reader :provider
-
- delegate :cluster, to: :provider
-
- def execute(provider)
- @provider = provider
-
- configure_provider
- create_gitlab_service_account!
- configure_platform_kubernetes
- configure_node_authentication!
-
- cluster.save!
- rescue ::Aws::CloudFormation::Errors::ServiceError => e
- log_service_error(e.class.name, provider.id, e.message)
- provider.make_errored!(s_('ClusterIntegration|Failed to fetch CloudFormation stack: %{message}') % { message: e.message })
- rescue Kubeclient::HttpError => e
- log_service_error(e.class.name, provider.id, e.message)
- provider.make_errored!(s_('ClusterIntegration|Failed to run Kubeclient: %{message}') % { message: e.message })
- rescue ActiveRecord::RecordInvalid => e
- log_service_error(e.class.name, provider.id, e.message)
- provider.make_errored!(s_('ClusterIntegration|Failed to configure EKS provider: %{message}') % { message: e.message })
- end
-
- private
-
- def create_gitlab_service_account!
- Clusters::Kubernetes::CreateOrUpdateServiceAccountService.gitlab_creator(
- kube_client,
- rbac: true
- ).execute
- end
-
- def configure_provider
- provider.status_event = :make_created
- end
-
- def configure_platform_kubernetes
- cluster.build_platform_kubernetes(
- api_url: cluster_endpoint,
- ca_cert: cluster_certificate,
- token: request_kubernetes_token)
- end
-
- def request_kubernetes_token
- Clusters::Kubernetes::FetchKubernetesTokenService.new(
- kube_client,
- Clusters::Kubernetes::GITLAB_ADMIN_TOKEN_NAME,
- Clusters::Kubernetes::GITLAB_SERVICE_ACCOUNT_NAMESPACE
- ).execute
- end
-
- def kube_client
- @kube_client ||= build_kube_client!(
- cluster_endpoint,
- cluster_certificate
- )
- end
-
- def build_kube_client!(api_url, ca_pem)
- raise "Incomplete settings" unless api_url
-
- Gitlab::Kubernetes::KubeClient.new(
- api_url,
- auth_options: kubeclient_auth_options,
- ssl_options: kubeclient_ssl_options(ca_pem),
- http_proxy_uri: ENV['http_proxy']
- )
- end
-
- def kubeclient_auth_options
- { bearer_token: Kubeclient::AmazonEksCredentials.token(provider.credentials, cluster.name) }
- end
-
- def kubeclient_ssl_options(ca_pem)
- opts = { verify_ssl: OpenSSL::SSL::VERIFY_PEER }
-
- if ca_pem.present?
- opts[:cert_store] = OpenSSL::X509::Store.new
- opts[:cert_store].add_cert(OpenSSL::X509::Certificate.new(ca_pem))
- end
-
- opts
- end
-
- def cluster_stack
- @cluster_stack ||= provider.api_client.describe_stacks(stack_name: provider.cluster.name).stacks.first
- end
-
- def stack_output_value(key)
- cluster_stack.outputs.detect { |output| output.output_key == key }.output_value
- end
-
- def node_instance_role_arn
- stack_output_value('NodeInstanceRole')
- end
-
- def cluster_endpoint
- strong_memoize(:cluster_endpoint) do
- stack_output_value('ClusterEndpoint')
- end
- end
-
- def cluster_certificate
- strong_memoize(:cluster_certificate) do
- Base64.decode64(stack_output_value('ClusterCertificate'))
- end
- end
-
- def configure_node_authentication!
- kube_client.create_config_map(node_authentication_config)
- end
-
- def node_authentication_config
- Gitlab::Kubernetes::ConfigMaps::AwsNodeAuth.new(node_instance_role_arn).generate
- end
-
- def logger
- @logger ||= Gitlab::Kubernetes::Logger.build
- end
-
- def log_service_error(exception, provider_id, message)
- logger.error(
- exception: exception.class.name,
- service: self.class.name,
- provider_id: provider_id,
- message: message
- )
- end
- end
- end
-end
diff --git a/app/services/clusters/aws/provision_service.rb b/app/services/clusters/aws/provision_service.rb
deleted file mode 100644
index b454a7a5f59..00000000000
--- a/app/services/clusters/aws/provision_service.rb
+++ /dev/null
@@ -1,85 +0,0 @@
-# frozen_string_literal: true
-
-module Clusters
- module Aws
- class ProvisionService
- attr_reader :provider
-
- def execute(provider)
- @provider = provider
-
- configure_provider_credentials
- provision_cluster
-
- if provider.make_creating
- WaitForClusterCreationWorker.perform_in(
- Clusters::Aws::VerifyProvisionStatusService::INITIAL_INTERVAL,
- provider.cluster_id
- )
- else
- provider.make_errored!("Failed to update provider record; #{provider.errors.full_messages}")
- end
- rescue Clusters::Aws::FetchCredentialsService::MissingRoleError
- provider.make_errored!('Amazon role is not configured')
- rescue ::Aws::Errors::MissingCredentialsError
- provider.make_errored!('Amazon credentials are not configured')
- rescue ::Aws::STS::Errors::ServiceError => e
- provider.make_errored!("Amazon authentication failed; #{e.message}")
- rescue ::Aws::CloudFormation::Errors::ServiceError => e
- provider.make_errored!("Amazon CloudFormation request failed; #{e.message}")
- end
-
- private
-
- def provision_role
- provider.created_by_user&.aws_role
- end
-
- def credentials
- @credentials ||= Clusters::Aws::FetchCredentialsService.new(
- provision_role,
- provider: provider
- ).execute
- end
-
- def configure_provider_credentials
- provider.update!(
- access_key_id: credentials.access_key_id,
- secret_access_key: credentials.secret_access_key,
- session_token: credentials.session_token
- )
- end
-
- def provision_cluster
- provider.api_client.create_stack(
- stack_name: provider.cluster.name,
- template_body: stack_template,
- parameters: parameters,
- capabilities: ["CAPABILITY_IAM"]
- )
- end
-
- def parameters
- [
- parameter('ClusterName', provider.cluster.name),
- parameter('ClusterRole', provider.role_arn),
- parameter('KubernetesVersion', provider.kubernetes_version),
- parameter('ClusterControlPlaneSecurityGroup', provider.security_group_id),
- parameter('VpcId', provider.vpc_id),
- parameter('Subnets', provider.subnet_ids.join(',')),
- parameter('NodeAutoScalingGroupDesiredCapacity', provider.num_nodes.to_s),
- parameter('NodeInstanceType', provider.instance_type),
- parameter('KeyName', provider.key_name)
- ]
- end
-
- def parameter(key, value)
- { parameter_key: key, parameter_value: value }
- end
-
- def stack_template
- File.read(Rails.root.join('vendor', 'aws', 'cloudformation', 'eks_cluster.yaml'))
- end
- end
- end
-end
diff --git a/app/services/clusters/aws/verify_provision_status_service.rb b/app/services/clusters/aws/verify_provision_status_service.rb
deleted file mode 100644
index 99532662bc4..00000000000
--- a/app/services/clusters/aws/verify_provision_status_service.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-# frozen_string_literal: true
-
-module Clusters
- module Aws
- class VerifyProvisionStatusService
- attr_reader :provider
-
- INITIAL_INTERVAL = 5.minutes
- POLL_INTERVAL = 1.minute
- TIMEOUT = 30.minutes
-
- def execute(provider)
- @provider = provider
-
- case cluster_stack.stack_status
- when 'CREATE_IN_PROGRESS'
- continue_creation
- when 'CREATE_COMPLETE'
- finalize_creation
- else
- provider.make_errored!("Unexpected status; #{cluster_stack.stack_status}")
- end
- rescue ::Aws::CloudFormation::Errors::ServiceError => e
- provider.make_errored!("Amazon CloudFormation request failed; #{e.message}")
- end
-
- private
-
- def cluster_stack
- @cluster_stack ||= provider.api_client.describe_stacks(stack_name: provider.cluster.name).stacks.first
- end
-
- def continue_creation
- if timeout_threshold.future?
- WaitForClusterCreationWorker.perform_in(POLL_INTERVAL, provider.cluster_id)
- else
- provider.make_errored!(_('Kubernetes cluster creation time exceeds timeout; %{timeout}') % { timeout: TIMEOUT })
- end
- end
-
- def timeout_threshold
- cluster_stack.creation_time + TIMEOUT
- end
-
- def finalize_creation
- Clusters::Aws::FinalizeCreationService.new.execute(provider)
- end
- end
- end
-end