Skip to content
Snippets Groups Projects
Verified Commit 5b7f9cf1 authored by Timo Furrer's avatar Timo Furrer :juggling:
Browse files

Implement create service for agent url configuration

parent bda38621
No related branches found
No related tags found
No related merge requests found
# frozen_string_literal: true
module Clusters
module Agents
class CreateUrlConfigurationService
attr_reader :agent, :current_user, :params
def initialize(agent:, current_user:, params:)
@agent = agent
@current_user = current_user
@params = params
end
def execute
return error_no_permissions unless cluster_agent_permissions?
return error_receptive_agents_disabled unless receptive_agents_enabled?
return error_already_receptive if agent.is_receptive
config = ::Clusters::Agents::UrlConfiguration.new(
agent: agent,
project: project,
created_by_user: current_user,
url: params[:url],
ca_cert: params[:ca_cert],
tls_host: params[:tls_host]
)
if params[:client_key]
config.client_key = params[:client_key]
config.client_cert = params[:client_cert]
else
private_key = Ed25519::SigningKey.generate
public_key = private_key.verify_key
config.private_key = private_key.to_bytes
config.public_key = public_key.to_bytes
end
if config.save
ServiceResponse.new(status: :success, payload: { url_configuration: config }, reason: :created)
else
ServiceResponse.error(message: config.errors.full_messages)
end
end
private
delegate :project, to: :agent
def cluster_agent_permissions?
current_user.can?(:admin_pipeline, project) && current_user.can?(:create_cluster, project)
end
def receptive_agents_enabled?
Feature.enabled?(:cluster_agent_incoming_connections, project)
end
def error_receptive_agents_disabled
ServiceResponse.error(
message: s_('ClusterAgent|Receptive agents are disabled for this GitLab instance')
)
end
def error_already_receptive
ServiceResponse.error(
message: s_('ClusterAgent|URL configuration already exists for this agent')
)
end
def error_no_permissions
ServiceResponse.error(
message: s_('ClusterAgent|You have insufficient permissions to create an url configuration for this agent')
)
end
end
end
end
Clusters::Agents::CreateService.prepend_mod
......@@ -12555,6 +12555,12 @@ msgstr ""
msgid "ClusterAgent|An agent can have only two active tokens at a time"
msgstr ""
 
msgid "ClusterAgent|Receptive agents are disabled for this GitLab instance"
msgstr ""
msgid "ClusterAgent|URL configuration already exists for this agent"
msgstr ""
msgid "ClusterAgent|User has insufficient permissions to create a token for this project"
msgstr ""
 
......@@ -12564,6 +12570,9 @@ msgstr ""
msgid "ClusterAgent|You have insufficient permissions to create a cluster agent for this project"
msgstr ""
 
msgid "ClusterAgent|You have insufficient permissions to create an url configuration for this agent"
msgstr ""
msgid "ClusterAgent|You have insufficient permissions to delete this cluster agent"
msgstr ""
 
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Clusters::Agents::CreateUrlConfigurationService, feature_category: :deployment_management do
describe '#execute' do
let(:agent) { create(:cluster_agent) }
let(:project) { agent.project }
let(:user) { create(:user, maintainer_of: project) }
let(:url) { 'grpc://agent.example.com' }
let(:params) { { url: url } }
subject(:service) { described_class.new(agent: agent, current_user: user, params: params) }
context 'when using public key auth' do
let(:private_key) { Ed25519::SigningKey.generate }
let(:public_key) { private_key.verify_key }
before do
allow(Ed25519::SigningKey).to receive(:generate).and_return(private_key)
end
it 'creates a new configuration' do
response = service.execute
expect(response).to be_success
expect(agent.agent_url_configuration).to have_attributes(
project: project,
created_by_user: user,
url: url,
public_key: public_key.to_bytes,
private_key: private_key.to_bytes.force_encoding('UTF-8')
)
expect(agent.is_receptive).to be(true)
end
end
context 'when using certificate auth' do
let(:client_cert) { File.read(Rails.root.join('spec/fixtures/clusters/sample_cert.pem')) }
let(:client_key) { File.read(Rails.root.join('spec/fixtures/clusters/sample_key.key')) }
let(:ca_cert) { File.read(Rails.root.join('spec/fixtures/clusters/sample_cert.pem')) }
let(:tls_host) { 'host.example.com' }
let(:params) do
{
url: url,
client_cert: client_cert,
client_key: client_key,
ca_cert: ca_cert,
tls_host: tls_host
}
end
it 'creates a new configuration' do
response = service.execute
expect(response).to be_success
expect(agent.agent_url_configuration).to have_attributes(
project: project,
created_by_user: user,
url: url,
client_cert: client_cert,
client_key: client_key,
ca_cert: ca_cert,
tls_host: tls_host
)
end
end
context 'when the configuration has a validation error' do
let(:url) { 'not.a.url' }
it 'returns an error' do
response = service.execute
expect(response.status).to eq(:error)
expect(response.message).to eq(['Url is not a valid URL'])
end
end
context 'when the user does not have permission' do
let(:user) { create(:user) }
it 'returns an error' do
response = service.execute
expect(response.status).to eq(:error)
expect(response.message).to eq(
'You have insufficient permissions to create an url configuration for this agent'
)
end
end
context 'when receptive agents are disabled' do
before do
stub_feature_flags(cluster_agent_incoming_connections: false)
end
it 'returns an error' do
response = service.execute
expect(response.status).to eq(:error)
expect(response.message).to eq('Receptive agents are disabled for this GitLab instance')
end
end
context 'when the associated agent already has a url configuration' do
let(:agent) { create(:cluster_agent, is_receptive: true) }
it 'returns an error' do
response = service.execute
expect(response.status).to eq(:error)
expect(response.message).to eq('URL configuration already exists for this agent')
end
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment