Commit cd255a09 authored by Tiger Watson's avatar Tiger Watson

Merge branch 'emilyring-clustertoken-name' into 'master'

Add name field to Cluster Agent Token

See merge request gitlab-org/gitlab!53920
parents f70d70a1 7c8110e7
......@@ -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