mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-08-10 01:31:45 +00:00
203 lines
9.8 KiB
Ruby
203 lines
9.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module API
|
|
# Kubernetes Internal API
|
|
module Internal
|
|
class Kubernetes < ::API::Base
|
|
before do
|
|
authenticate_gitlab_kas_request!
|
|
end
|
|
|
|
helpers ::API::Helpers::KasHelpers
|
|
helpers ::API::Helpers::Kubernetes::AgentHelpers
|
|
|
|
namespace 'internal' do
|
|
namespace 'agents' do
|
|
namespace 'agentk' do
|
|
before do
|
|
check_agent_token
|
|
end
|
|
|
|
desc 'Gets agent info for agentk' do
|
|
detail 'Retrieves agent info for agentk for the given token'
|
|
end
|
|
route_setting :authentication, cluster_agent_token_allowed: true
|
|
get '/agent_info', feature_category: :deployment_management, urgency: :low do
|
|
project = agent.project
|
|
|
|
status 200
|
|
{
|
|
project_id: project.id,
|
|
agent_id: agent.id,
|
|
agent_name: agent.name,
|
|
gitaly_info: gitaly_info(project),
|
|
gitaly_repository: gitaly_repository(project),
|
|
default_branch: project.default_branch_or_main
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
namespace 'kubernetes' do
|
|
before do
|
|
check_agent_token
|
|
end
|
|
|
|
# TODO: Remove this endpoint once KAS points to the new endpoint - /internal/agents/agentk/agent_info
|
|
# https://gitlab.com/gitlab-org/gitlab/-/issues/550719
|
|
desc 'Gets agent info' do
|
|
detail 'Retrieves agent info for the given token'
|
|
end
|
|
route_setting :authentication, cluster_agent_token_allowed: true
|
|
get '/agent_info', feature_category: :deployment_management, urgency: :low do
|
|
project = agent.project
|
|
|
|
status 200
|
|
{
|
|
project_id: project.id,
|
|
agent_id: agent.id,
|
|
agent_name: agent.name,
|
|
gitaly_info: gitaly_info(project),
|
|
gitaly_repository: gitaly_repository(project),
|
|
default_branch: project.default_branch_or_main
|
|
}
|
|
end
|
|
|
|
desc 'Verify agent access to a project' do
|
|
detail 'Verifies if the agent (owning the token) is authorized to access the given project'
|
|
end
|
|
route_setting :authentication, cluster_agent_token_allowed: true
|
|
get '/verify_project_access', feature_category: :deployment_management, urgency: :low do
|
|
project = find_project(params[:id])
|
|
|
|
not_found! unless agent_has_access_to_project?(project)
|
|
|
|
status 204
|
|
end
|
|
end
|
|
|
|
namespace 'kubernetes/agent_configuration' do
|
|
desc 'POST agent configuration' do
|
|
detail 'Store configuration for an agent'
|
|
end
|
|
params do
|
|
requires :agent_id, type: Integer, desc: 'ID of the configured Agent'
|
|
requires :agent_config, type: JSON, desc: 'Configuration for the Agent'
|
|
end
|
|
post '/', feature_category: :deployment_management, urgency: :low do
|
|
agent = ::Clusters::Agent.find(params[:agent_id])
|
|
update_configuration(agent: agent, config: params[:agent_config])
|
|
|
|
no_content!
|
|
end
|
|
end
|
|
|
|
namespace 'kubernetes/authorize_proxy_user' do
|
|
desc 'Authorize a proxy user request'
|
|
params do
|
|
requires :agent_id, type: Integer, desc: 'ID of the agent accessed'
|
|
requires :access_type, type: String, values: %w[session_cookie personal_access_token], desc: 'The type of access key being verified.'
|
|
requires :access_key, type: String, desc: 'The authentication secret for the given access type.'
|
|
given access_type: ->(val) { val == 'session_cookie' } do
|
|
requires :csrf_token, type: String, allow_blank: false, desc: 'CSRF token that must be checked when access_type is "session_cookie", to ensure the request originates from a GitLab browsing session.'
|
|
end
|
|
end
|
|
post '/', feature_category: :deployment_management do
|
|
# Load user
|
|
user = if params[:access_type] == 'session_cookie'
|
|
retrieve_user_from_session_cookie
|
|
elsif params[:access_type] == 'personal_access_token'
|
|
retrieve_user_from_personal_access_token
|
|
end
|
|
|
|
bad_request!('Unable to get user from request data') if user.nil?
|
|
|
|
# Load agent
|
|
agent = ::Clusters::Agent.find(params[:agent_id])
|
|
unauthorized!('Feature disabled for agent') unless ::Gitlab::Kas::UserAccess.enabled?
|
|
|
|
service_response = ::Clusters::Agents::AuthorizeProxyUserService.new(user, agent).execute
|
|
render_api_error!(service_response[:message], service_response[:reason]) unless service_response.success?
|
|
|
|
service_response.payload
|
|
end
|
|
end
|
|
|
|
namespace 'kubernetes/usage_metrics' do
|
|
desc 'POST usage metrics' do
|
|
detail 'Updates usage metrics for agent'
|
|
end
|
|
params do
|
|
optional :counters, type: Hash do
|
|
optional :k8s_api_proxy_request, type: Integer, desc: 'The count to increment the k8s_api_proxy_request metric by'
|
|
optional :flux_git_push_notifications_total, type: Integer, desc: 'The count to increment the flux_git_push_notifications_total metrics by'
|
|
optional :k8s_api_proxy_requests_via_ci_access, type: Integer, desc: 'The count to increment the k8s_api_proxy_requests_via_ci_access metric by'
|
|
optional :k8s_api_proxy_requests_via_user_access, type: Integer, desc: 'The count to increment the k8s_api_proxy_requests_via_user_access metric by'
|
|
optional :k8s_api_proxy_requests_via_pat_access, type: Integer, desc: 'The count to increment the k8s_api_proxy_requests_via_pat_access metric by'
|
|
end
|
|
|
|
optional :unique_counters, type: Hash do
|
|
optional :k8s_api_proxy_requests_unique_users_via_ci_access, type: Array[Integer], desc: 'An array of users that have interacted with the CI tunnel via `ci_access`'
|
|
optional :k8s_api_proxy_requests_unique_agents_via_ci_access, type: Array[Integer], desc: 'An array of agents that have interacted with the CI tunnel via `ci_access`'
|
|
optional :k8s_api_proxy_requests_unique_users_via_user_access, type: Array[Integer], desc: 'An array of users that have interacted with the CI tunnel via `user_access`'
|
|
optional :k8s_api_proxy_requests_unique_agents_via_user_access, type: Array[Integer], desc: 'An array of agents that have interacted with the CI tunnel via `user_access`'
|
|
optional :k8s_api_proxy_requests_unique_users_via_pat_access, type: Array[Integer], desc: 'An array of users that have interacted with the CI tunnel via personal access token'
|
|
optional :k8s_api_proxy_requests_unique_agents_via_pat_access, type: Array[Integer], desc: 'An array of agents that have interacted with the CI tunnel via personal access token'
|
|
optional :flux_git_push_notified_unique_projects, type: Array[Integer], desc: 'An array of projects that have been notified to reconcile their Flux workloads'
|
|
end
|
|
end
|
|
post '/', feature_category: :deployment_management do
|
|
increment_count_events
|
|
increment_unique_events
|
|
track_unique_user_events
|
|
|
|
no_content!
|
|
rescue ArgumentError => e
|
|
bad_request!(e.message)
|
|
end
|
|
end
|
|
|
|
namespace 'kubernetes/agent_events' do
|
|
desc 'POST agent events' do
|
|
detail 'Updates agent events'
|
|
end
|
|
params do
|
|
optional :events, type: Hash, desc: 'Array of events' do
|
|
optional :k8s_api_proxy_requests_unique_users_via_ci_access, type: Array, desc: 'An array of events that have interacted with the CI tunnel via `ci_access`' do
|
|
optional :user_id, type: Integer, desc: 'User ID'
|
|
optional :project_id, type: Integer, desc: 'Project ID'
|
|
end
|
|
optional :k8s_api_proxy_requests_unique_users_via_user_access, type: Array, desc: 'An array of events that have interacted with the CI tunnel via `ci_access`' do
|
|
optional :user_id, type: Integer, desc: 'User ID'
|
|
optional :project_id, type: Integer, desc: 'Project ID'
|
|
end
|
|
optional :k8s_api_proxy_requests_unique_users_via_pat_access, type: Array, desc: 'An array of events that have interacted with the CI tunnel via `ci_access`' do
|
|
optional :user_id, type: Integer, desc: 'User ID'
|
|
optional :project_id, type: Integer, desc: 'Project ID'
|
|
end
|
|
optional :register_agent_at_kas, type: Array, desc: 'An array of events that indicate an agent has been registered' do
|
|
optional :project_id, type: Integer, desc: 'Project ID'
|
|
optional :agent_version, type: String, desc: 'Agent version'
|
|
optional :architecture, type: String, desc: 'CPU architecture of the agent'
|
|
optional :agent_id, type: Integer, desc: 'Agent ID'
|
|
optional :kubernetes_version, type: String, desc: 'Kubernetes version of the agent'
|
|
optional :extra_telemetry_data, type: Hash, desc: 'Extra telemetry data of the agent' do
|
|
optional :installation_method, type: String, desc: 'Installation method used to install the agent'
|
|
optional :helm_chart_version, type: String, desc: 'Helm Chart version used to install the agent'
|
|
end
|
|
end
|
|
end
|
|
end
|
|
post '/', feature_category: :deployment_management do
|
|
track_events
|
|
|
|
no_content!
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
API::Internal::Kubernetes.prepend_mod_with('API::Internal::Kubernetes')
|