Commit 7e079330 authored by Dylan Griffith's avatar Dylan Griffith

Merge branch 'add-agent-token-status' into 'master'

Add revoked status to cluster agent tokens

See merge request gitlab-org/gitlab!76505
parents 45235f88 28384244
...@@ -44,6 +44,11 @@ module Types ...@@ -44,6 +44,11 @@ module Types
null: true, null: true,
description: 'Name given to the token.' description: 'Name given to the token.'
field :status,
GraphQL::Types::String,
null: true,
description: 'Current status of the token.'
def cluster_agent def cluster_agent
Gitlab::Graphql::Loaders::BatchModelLoader.new(::Clusters::Agent, object.agent_id).find Gitlab::Graphql::Loaders::BatchModelLoader.new(::Clusters::Agent, object.agent_id).find
end end
......
...@@ -36,8 +36,8 @@ module Clusters ...@@ -36,8 +36,8 @@ module Clusters
requested_project == project requested_project == project
end end
def active? def connected?
agent_tokens.where("last_used_at > ?", INACTIVE_AFTER.ago).exists? agent_tokens.active.where("last_used_at > ?", INACTIVE_AFTER.ago).exists?
end end
end end
end end
...@@ -23,13 +23,18 @@ module Clusters ...@@ -23,13 +23,18 @@ module Clusters
scope :order_last_used_at_desc, -> { order(::Gitlab::Database.nulls_last_order('last_used_at', 'DESC')) } scope :order_last_used_at_desc, -> { order(::Gitlab::Database.nulls_last_order('last_used_at', 'DESC')) }
enum status: {
active: 0,
revoked: 1
}
def track_usage def track_usage
track_values = { last_used_at: Time.current.utc } track_values = { last_used_at: Time.current.utc }
cache_attributes(track_values) cache_attributes(track_values)
if can_update_track_values? if can_update_track_values?
log_activity_event!(track_values[:last_used_at]) unless agent.active? log_activity_event!(track_values[:last_used_at]) unless agent.connected?
# Use update_column so updated_at is skipped # Use update_column so updated_at is skipped
update_columns(track_values) update_columns(track_values)
......
# frozen_string_literal: true
class AddStatusToClusterAgentTokens < Gitlab::Database::Migration[1.0]
def change
add_column :cluster_agent_tokens, :status, :smallint, null: false, default: 0
end
end
907fafc18fa515fff8f716f6464263ccc8a9b6e5ead36f30b05089100fd71b6b
\ No newline at end of file
...@@ -12384,6 +12384,7 @@ CREATE TABLE cluster_agent_tokens ( ...@@ -12384,6 +12384,7 @@ CREATE TABLE cluster_agent_tokens (
description text, description text,
name text, name text,
last_used_at timestamp with time zone, last_used_at timestamp with time zone,
status smallint DEFAULT 0 NOT NULL,
CONSTRAINT check_0fb634d04d CHECK ((name IS NOT NULL)), CONSTRAINT check_0fb634d04d CHECK ((name IS NOT NULL)),
CONSTRAINT check_2b79dbb315 CHECK ((char_length(name) <= 255)), CONSTRAINT check_2b79dbb315 CHECK ((char_length(name) <= 255)),
CONSTRAINT check_4e4ec5070a CHECK ((char_length(description) <= 1024)), CONSTRAINT check_4e4ec5070a CHECK ((char_length(description) <= 1024)),
...@@ -8960,6 +8960,7 @@ GitLab CI/CD configuration template. ...@@ -8960,6 +8960,7 @@ GitLab CI/CD configuration template.
| <a id="clusteragenttokenid"></a>`id` | [`ClustersAgentTokenID!`](#clustersagenttokenid) | Global ID of the token. | | <a id="clusteragenttokenid"></a>`id` | [`ClustersAgentTokenID!`](#clustersagenttokenid) | Global ID of the token. |
| <a id="clusteragenttokenlastusedat"></a>`lastUsedAt` | [`Time`](#time) | Timestamp the token was last used. | | <a id="clusteragenttokenlastusedat"></a>`lastUsedAt` | [`Time`](#time) | Timestamp the token was last used. |
| <a id="clusteragenttokenname"></a>`name` | [`String`](#string) | Name given to the token. | | <a id="clusteragenttokenname"></a>`name` | [`String`](#string) | Name given to the token. |
| <a id="clusteragenttokenstatus"></a>`status` | [`String`](#string) | Current status of the token. |
### `CodeCoverageActivity` ### `CodeCoverageActivity`
...@@ -165,7 +165,7 @@ module Gitlab ...@@ -165,7 +165,7 @@ module Gitlab
authorization_token, _options = token_and_options(current_request) authorization_token, _options = token_and_options(current_request)
::Clusters::AgentToken.find_by_token(authorization_token) ::Clusters::AgentToken.active.find_by_token(authorization_token)
end end
def find_runner_from_token def find_runner_from_token
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe GitlabSchema.types['ClusterAgentToken'] do RSpec.describe GitlabSchema.types['ClusterAgentToken'] do
let(:fields) { %i[cluster_agent created_at created_by_user description id last_used_at name] } let(:fields) { %i[cluster_agent created_at created_by_user description id last_used_at name status] }
it { expect(described_class.graphql_name).to eq('ClusterAgentToken') } it { expect(described_class.graphql_name).to eq('ClusterAgentToken') }
......
...@@ -939,21 +939,19 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -939,21 +939,19 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end end
describe '#cluster_agent_token_from_authorization_token' do describe '#cluster_agent_token_from_authorization_token' do
let_it_be(:agent_token, freeze: true) { create(:cluster_agent_token) } let_it_be(:agent_token) { create(:cluster_agent_token) }
subject { cluster_agent_token_from_authorization_token }
context 'when route_setting is empty' do context 'when route_setting is empty' do
it 'returns nil' do it { is_expected.to be_nil }
expect(cluster_agent_token_from_authorization_token).to be_nil
end
end end
context 'when route_setting allows cluster agent token' do context 'when route_setting allows cluster agent token' do
let(:route_authentication_setting) { { cluster_agent_token_allowed: true } } let(:route_authentication_setting) { { cluster_agent_token_allowed: true } }
context 'Authorization header is empty' do context 'Authorization header is empty' do
it 'returns nil' do it { is_expected.to be_nil }
expect(cluster_agent_token_from_authorization_token).to be_nil
end
end end
context 'Authorization header is incorrect' do context 'Authorization header is incorrect' do
...@@ -961,9 +959,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -961,9 +959,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
request.headers['Authorization'] = 'Bearer ABCD' request.headers['Authorization'] = 'Bearer ABCD'
end end
it 'returns nil' do it { is_expected.to be_nil }
expect(cluster_agent_token_from_authorization_token).to be_nil
end
end end
context 'Authorization header is malformed' do context 'Authorization header is malformed' do
...@@ -971,9 +967,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -971,9 +967,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
request.headers['Authorization'] = 'Bearer' request.headers['Authorization'] = 'Bearer'
end end
it 'returns nil' do it { is_expected.to be_nil }
expect(cluster_agent_token_from_authorization_token).to be_nil
end
end end
context 'Authorization header matches agent token' do context 'Authorization header matches agent token' do
...@@ -981,8 +975,14 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -981,8 +975,14 @@ RSpec.describe Gitlab::Auth::AuthFinders do
request.headers['Authorization'] = "Bearer #{agent_token.token}" request.headers['Authorization'] = "Bearer #{agent_token.token}"
end end
it 'returns the agent token' do it { is_expected.to eq(agent_token) }
expect(cluster_agent_token_from_authorization_token).to eq(agent_token)
context 'agent token has been revoked' do
before do
agent_token.revoked!
end
it { is_expected.to be_nil }
end end
end end
end end
......
...@@ -76,12 +76,12 @@ RSpec.describe Clusters::Agent do ...@@ -76,12 +76,12 @@ RSpec.describe Clusters::Agent do
end end
end end
describe '#active?' do describe '#connected?' do
let_it_be(:agent) { create(:cluster_agent) } let_it_be(:agent) { create(:cluster_agent) }
let!(:token) { create(:cluster_agent_token, agent: agent, last_used_at: last_used_at) } let!(:token) { create(:cluster_agent_token, agent: agent, last_used_at: last_used_at) }
subject { agent.active? } subject { agent.connected? }
context 'agent has never connected' do context 'agent has never connected' do
let(:last_used_at) { nil } let(:last_used_at) { nil }
...@@ -99,6 +99,14 @@ RSpec.describe Clusters::Agent do ...@@ -99,6 +99,14 @@ RSpec.describe Clusters::Agent do
let(:last_used_at) { 2.minutes.ago } let(:last_used_at) { 2.minutes.ago }
it { is_expected.to be_truthy } it { is_expected.to be_truthy }
context 'agent token has been revoked' do
before do
token.revoked!
end
it { is_expected.to be_falsey }
end
end end
context 'agent has multiple tokens' do context 'agent has multiple tokens' do
......
...@@ -9,6 +9,8 @@ RSpec.describe Clusters::AgentToken do ...@@ -9,6 +9,8 @@ RSpec.describe Clusters::AgentToken do
it { is_expected.to validate_length_of(:name).is_at_most(255) } it { is_expected.to validate_length_of(:name).is_at_most(255) }
it { is_expected.to validate_presence_of(:name) } it { is_expected.to validate_presence_of(:name) }
it_behaves_like 'having unique enum values'
describe 'scopes' do describe 'scopes' do
describe '.order_last_used_at_desc' do describe '.order_last_used_at_desc' do
let_it_be(:token_1) { create(:cluster_agent_token, last_used_at: 7.days.ago) } let_it_be(:token_1) { create(:cluster_agent_token, last_used_at: 7.days.ago) }
...@@ -76,9 +78,9 @@ RSpec.describe Clusters::AgentToken do ...@@ -76,9 +78,9 @@ RSpec.describe Clusters::AgentToken do
end end
end end
context 'agent is inactive' do context 'agent is not connected' do
before do before do
allow(agent).to receive(:active?).and_return(false) allow(agent).to receive(:connected?).and_return(false)
end end
it 'creates an activity event' do it 'creates an activity event' do
...@@ -94,9 +96,9 @@ RSpec.describe Clusters::AgentToken do ...@@ -94,9 +96,9 @@ RSpec.describe Clusters::AgentToken do
end end
end end
context 'agent is active' do context 'agent is connected' do
before do before do
allow(agent).to receive(:active?).and_return(true) allow(agent).to receive(:connected?).and_return(true)
end end
it 'does not create an activity event' do it 'does not create an activity event' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment