Commit 7c8110e7 authored by Emily Ring's avatar Emily Ring Committed by Tiger Watson

Add name field for cluster agent token

Added cluster agent token name field to database and GraphQL
Updated associated docs and tests
parent dbe5012f
......@@ -13,5 +13,6 @@ module Clusters
before_save :ensure_token
validates :description, length: { maximum: 1024 }
validates :name, presence: true, length: { maximum: 255 }, on: :create
end
end
---
title: Add name field to cluster agent token
merge_request: 53920
author:
type: changed
# frozen_string_literal: true
class AddNameFieldToClusterAgentToken < ActiveRecord::Migration[6.0]
DOWNTIME = false
# rubocop:disable Migration/AddLimitToTextColumns
# limit is added in LimitClusterTokenSize
def change
add_column :cluster_agent_tokens, :name, :text
end
# rubocop:enable Migration/AddLimitToTextColumns
end
# frozen_string_literal: true
class LimitClusterTokenSize < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_text_limit :cluster_agent_tokens, :name, 255
end
def down
remove_text_limit :cluster_agent_tokens, :name
end
end
964e9f88018b2ab72fd370f6a8dccde218cfd4ffa3ccedf4f142ab341f5e858f
\ No newline at end of file
526174bd42327e0212b15ffbad99541887de1dec35cc4c592d4f02065026b3ca
\ No newline at end of file
......@@ -11029,6 +11029,8 @@ CREATE TABLE cluster_agent_tokens (
token_encrypted text NOT NULL,
created_by_user_id bigint,
description text,
name text,
CONSTRAINT check_2b79dbb315 CHECK ((char_length(name) <= 255)),
CONSTRAINT check_4e4ec5070a CHECK ((char_length(description) <= 1024)),
CONSTRAINT check_c60daed227 CHECK ((char_length(token_encrypted) <= 255))
);
......@@ -865,6 +865,7 @@ Autogenerated return type of ClusterAgentDelete.
| `createdByUser` | User | The user who created the token. |
| `description` | String | Description of the token. |
| `id` | ClustersAgentTokenID! | Global ID of the token. |
| `name` | String | Name given to the token. |
### ClusterAgentTokenCreatePayload
......
......@@ -205,7 +205,13 @@ the Agent in subsequent steps. You can create an Agent record either:
}
mutation createToken {
clusterAgentTokenCreate(input: { clusterAgentId: <cluster-agent-id-taken-from-the-previous-mutation> }) {
clusterAgentTokenCreate(
input: {
clusterAgentId: "<cluster-agent-id-taken-from-the-previous-mutation>"
description: "<optional-description-of-token>"
name: "<required-name-given-to-token>"
}
) {
secret # This is the value you need to use on the next step
token {
createdAt
......@@ -459,7 +465,7 @@ There are several components that work in concert for the Agent to generate the
- One or more network policies through any of these options:
- Use the [Container Network Policy editor](../../application_security/threat_monitoring/index.md#container-network-policy-editor) to create and manage policies.
- Use an [AutoDevOps](../../application_security/threat_monitoring/index.md#container-network-policy-management) configuration.
- Add the required labels and annotations to existing network policies.
- Add the required labels and annotations to existing network policies.
- Use a configuration repository to inform the Agent through a `config.yaml` file, which
repositories can synchronize with. This repository might be the same, or a separate GitLab
project.
......
......@@ -20,6 +20,11 @@ module Mutations
required: false,
description: 'Description of the token.'
argument :name,
GraphQL::STRING_TYPE,
required: true,
description: 'Name of the token.'
field :secret,
GraphQL::STRING_TYPE,
null: true,
......
......@@ -34,6 +34,11 @@ module Types
null: false,
description: 'Global ID of the token.'
field :name,
GraphQL::STRING_TYPE,
null: true,
description: 'Name given to the token.'
def cluster_agent
Gitlab::Graphql::Loaders::BatchModelLoader.new(::Clusters::Agent, object.agent_id).find
end
......
......@@ -3,7 +3,7 @@
module Clusters
module AgentTokens
class CreateService < ::BaseContainerService
ALLOWED_PARAMS = %i[agent_id description].freeze
ALLOWED_PARAMS = %i[agent_id description name].freeze
def execute
return error_feature_not_available unless container.feature_available?(:cluster_agents)
......
......@@ -19,8 +19,9 @@ RSpec.describe Mutations::Clusters::AgentTokens::Create do
describe '#resolve' do
let(:description) { 'new token!' }
let(:name) { 'new name' }
subject { mutation.resolve(cluster_agent_id: cluster_agent.to_global_id, description: description) }
subject { mutation.resolve(cluster_agent_id: cluster_agent.to_global_id, description: description, name: name) }
context 'without token permissions' do
it 'raises an error if the resource is not accessible to the user' do
......@@ -50,8 +51,12 @@ RSpec.describe Mutations::Clusters::AgentTokens::Create do
end
it 'returns token information', :aggregate_failures do
token = subject[:token]
expect(subject[:secret]).not_to be_nil
expect(subject[:token].description).to eq(description)
expect(token.created_by_user).to eq(user)
expect(token.description).to eq(description)
expect(token.name).to eq(name)
end
context 'invalid params' do
......
......@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe GitlabSchema.types['ClusterAgentToken'] do
let(:fields) { %i[cluster_agent created_at created_by_user description id] }
let(:fields) { %i[cluster_agent created_at created_by_user description id name] }
it { expect(described_class.graphql_name).to eq('ClusterAgentToken') }
......
......@@ -9,10 +9,11 @@ RSpec.describe 'Create a new cluster agent token' do
let_it_be(:current_user) { create(:user) }
let(:description) { 'create token' }
let(:name) { 'token name' }
let(:mutation) do
graphql_mutation(
:cluster_agent_token_create,
{ cluster_agent_id: cluster_agent.to_global_id.to_s, description: description }
{ cluster_agent_id: cluster_agent.to_global_id.to_s, description: description, name: name }
)
end
......@@ -58,6 +59,7 @@ RSpec.describe 'Create a new cluster agent token' do
expect(mutation_response['secret']).not_to be_nil
expect(mutation_response.dig('token', 'description')).to eq(description)
expect(mutation_response.dig('token', 'name')).to eq(name)
end
end
end
......@@ -8,7 +8,7 @@ RSpec.describe Clusters::AgentTokens::CreateService do
let_it_be(:user) { create(:user) }
let(:cluster_agent) { create(:cluster_agent) }
let(:project) { cluster_agent.project }
let(:params) { { agent_id: cluster_agent.id } }
let(:params) { { agent_id: cluster_agent.id, description: 'token description', name: 'token name' } }
before do
stub_licensed_features(cluster_agents: false)
......@@ -28,9 +28,6 @@ RSpec.describe Clusters::AgentTokens::CreateService do
end
context 'with premium plan' do
let(:description) { 'New token description' }
let(:params) { { agent_id: cluster_agent.id, description: description } }
before do
stub_licensed_features(cluster_agents: true)
end
......@@ -64,7 +61,8 @@ RSpec.describe Clusters::AgentTokens::CreateService do
expect(subject.payload[:secret]).not_to be_nil
expect(token.created_by_user).to eq(user)
expect(token.description).to eq(description)
expect(token.description).to eq(params[:description])
expect(token.name).to eq(params[:name])
end
context 'when params are invalid' do
......@@ -76,7 +74,7 @@ RSpec.describe Clusters::AgentTokens::CreateService do
it 'returns validation errors', :aggregate_failures do
expect(subject.status).to eq(:error)
expect(subject.message).to eq(['Agent must exist'])
expect(subject.message).to eq(["Agent must exist", "Name can't be blank"])
end
end
end
......
......@@ -32,7 +32,7 @@ module QA
def api_post_body
<<~GQL
mutation createToken {
clusterAgentTokenCreate(input: { clusterAgentId: "gid://gitlab/Clusters::Agent/#{agent.id}" }) {
clusterAgentTokenCreate(input: { clusterAgentId: "gid://gitlab/Clusters::Agent/#{agent.id}" name: "token-#{agent.id}" }) {
secret # This is the value you need to use on the next step
token {
createdAt
......
......@@ -5,5 +5,7 @@ FactoryBot.define do
association :agent, factory: :cluster_agent
token_encrypted { Gitlab::CryptoHelper.aes256_gcm_encrypt(SecureRandom.hex(50)) }
sequence(:name) { |n| "agent-token-#{n}" }
end
end
......@@ -6,6 +6,8 @@ RSpec.describe Clusters::AgentToken do
it { is_expected.to belong_to(:agent).class_name('Clusters::Agent').required }
it { is_expected.to belong_to(:created_by_user).class_name('User').optional }
it { is_expected.to validate_length_of(:description).is_at_most(1024) }
it { is_expected.to validate_length_of(:name).is_at_most(255) }
it { is_expected.to validate_presence_of(:name) }
describe '#token' do
it 'is generated on save' 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