diff options
Diffstat (limited to 'lib/api/helpers/kubernetes/agent_helpers.rb')
-rw-r--r-- | lib/api/helpers/kubernetes/agent_helpers.rb | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/lib/api/helpers/kubernetes/agent_helpers.rb b/lib/api/helpers/kubernetes/agent_helpers.rb new file mode 100644 index 00000000000..50a8c2a5aed --- /dev/null +++ b/lib/api/helpers/kubernetes/agent_helpers.rb @@ -0,0 +1,119 @@ +# frozen_string_literal: true + +module API + module Helpers + module Kubernetes + module AgentHelpers + include Gitlab::Utils::StrongMemoize + + def authenticate_gitlab_kas_request! + render_api_error!('KAS JWT authentication invalid', 401) unless Gitlab::Kas.verify_api_request(headers) + end + + def agent_token + cluster_agent_token_from_authorization_token + end + strong_memoize_attr :agent_token + + def agent + agent_token.agent + end + strong_memoize_attr :agent + + def gitaly_info(project) + gitaly_features = Feature::Gitaly.server_feature_flags + + Gitlab::GitalyClient.connection_data(project.repository_storage).merge(features: gitaly_features) + end + + def gitaly_repository(project) + project.repository.gitaly_repository.to_h + end + + def check_feature_enabled + not_found!('Internal API not found') unless Feature.enabled?(:kubernetes_agent_internal_api, type: :ops) + end + + def check_agent_token + unauthorized! unless agent_token + + ::Clusters::AgentTokens::TrackUsageService.new(agent_token).execute + end + + def agent_has_access_to_project?(project) + Guest.can?(:download_code, project) || agent.has_access_to?(project) + end + + def increment_unique_events + events = params[:unique_counters]&.slice( + :agent_users_using_ci_tunnel, + :k8s_api_proxy_requests_unique_users_via_ci_access, :k8s_api_proxy_requests_unique_agents_via_ci_access, + :k8s_api_proxy_requests_unique_users_via_user_access, :k8s_api_proxy_requests_unique_agents_via_user_access, + :k8s_api_proxy_requests_unique_users_via_pat_access, :k8s_api_proxy_requests_unique_agents_via_pat_access, + :flux_git_push_notified_unique_projects + ) + + events&.each do |event, entity_ids| + increment_unique_values(event, entity_ids) + end + end + + def increment_count_events + events = params[:counters]&.slice( + :gitops_sync, :k8s_api_proxy_request, :flux_git_push_notifications_total, + :k8s_api_proxy_requests_via_ci_access, :k8s_api_proxy_requests_via_user_access, + :k8s_api_proxy_requests_via_pat_access + ) + + Gitlab::UsageDataCounters::KubernetesAgentCounter.increment_event_counts(events) + end + + def update_configuration(agent:, config:) + ::Clusters::Agents::Authorizations::CiAccess::RefreshService.new(agent, config: config).execute + ::Clusters::Agents::Authorizations::UserAccess::RefreshService.new(agent, config: config).execute + end + + def retrieve_user_from_session_cookie + # Load session + public_session_id_string = + begin + Gitlab::Kas::UserAccess.decrypt_public_session_id(params[:access_key]) + rescue StandardError + bad_request!('Invalid access_key') + end + + session_id = Rack::Session::SessionId.new(public_session_id_string) + session = ActiveSession.sessions_from_ids([session_id.private_id]).first + unauthorized!('Invalid session') unless session + + # CSRF check + unless ::Gitlab::Kas::UserAccess.valid_authenticity_token?(session.symbolize_keys, params[:csrf_token]) + unauthorized!('CSRF token does not match') + end + + # Load user + user = Warden::SessionSerializer.new('rack.session' => session).fetch(:user) + unauthorized!('Invalid user in session') unless user + user + end + + def retrieve_user_from_personal_access_token + return unless access_token.present? + + validate_access_token!(scopes: [Gitlab::Auth::K8S_PROXY_SCOPE]) + + ::PersonalAccessTokens::LastUsedService.new(access_token).execute + + access_token.user || raise(UnauthorizedError) + end + + def access_token + return unless params[:access_key].present? + + PersonalAccessToken.find_by_token(params[:access_key]) + end + strong_memoize_attr :access_token + end + end + end +end |