Added ssh fingerprint, gitlab ci and pages information in an instance configuration page
Closes #25142
This commit is contained in:
parent
3ddffec0d6
commit
294f40e2c8
16 changed files with 411 additions and 4 deletions
|
@ -57,6 +57,10 @@ class HelpController < ApplicationController
|
|||
def shortcuts
|
||||
end
|
||||
|
||||
def instance_configuration
|
||||
@instance_configuration = InstanceConfiguration.new
|
||||
end
|
||||
|
||||
def ui
|
||||
@user = User.new(id: 0, name: 'John Doe', username: '@johndoe')
|
||||
end
|
||||
|
|
18
app/helpers/instance_configuration_helper.rb
Normal file
18
app/helpers/instance_configuration_helper.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
module InstanceConfigurationHelper
|
||||
def instance_configuration_cell_html(value, &block)
|
||||
return '-' unless value.to_s.presence
|
||||
|
||||
block_given? ? yield(value) : value
|
||||
end
|
||||
|
||||
def instance_configuration_host(host)
|
||||
@instance_configuration_host ||= instance_configuration_cell_html(host).capitalize
|
||||
end
|
||||
|
||||
# Value must be in bytes
|
||||
def instance_configuration_human_size_cell(value)
|
||||
instance_configuration_cell_html(value) do |v|
|
||||
number_to_human_size(v, strip_insignificant_zeros: true, significant: false)
|
||||
end
|
||||
end
|
||||
end
|
71
app/models/instance_configuration.rb
Normal file
71
app/models/instance_configuration.rb
Normal file
|
@ -0,0 +1,71 @@
|
|||
require 'resolv'
|
||||
|
||||
class InstanceConfiguration
|
||||
SSH_ALGORITHMS = %w(DSA ECDSA ED25519 RSA).freeze
|
||||
SSH_ALGORITHMS_PATH = '/etc/ssh/'.freeze
|
||||
CACHE_KEY = 'instance_configuration'.freeze
|
||||
EXPIRATION_TIME = 24.hours
|
||||
|
||||
def settings
|
||||
@configuration ||= Rails.cache.fetch(CACHE_KEY, expires_in: EXPIRATION_TIME) do
|
||||
{ ssh_algorithms_hashes: ssh_algorithms_hashes,
|
||||
host: host,
|
||||
gitlab_pages: gitlab_pages,
|
||||
gitlab_ci: gitlab_ci }.deep_symbolize_keys
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def ssh_algorithms_hashes
|
||||
SSH_ALGORITHMS.map { |algo| ssh_algorithm_hashes(algo) }.compact
|
||||
end
|
||||
|
||||
def host
|
||||
Settings.gitlab.host
|
||||
end
|
||||
|
||||
def gitlab_pages
|
||||
Settings.pages.to_h.merge(ip_address: resolv_dns(Settings.pages.host))
|
||||
end
|
||||
|
||||
def resolv_dns(dns)
|
||||
Resolv.getaddress(dns)
|
||||
rescue Resolv::ResolvError
|
||||
end
|
||||
|
||||
def gitlab_ci
|
||||
Settings.gitlab_ci
|
||||
.to_h
|
||||
.merge(artifacts_max_size: { value: Settings.artifacts.max_size&.megabytes,
|
||||
default: 100.megabytes })
|
||||
end
|
||||
|
||||
def ssh_algorithm_file(algorithm)
|
||||
File.join(SSH_ALGORITHMS_PATH, "ssh_host_#{algorithm.downcase}_key.pub")
|
||||
end
|
||||
|
||||
def ssh_algorithm_hashes(algorithm)
|
||||
content = ssh_algorithm_file_content(algorithm)
|
||||
return unless content.present?
|
||||
|
||||
{ name: algorithm,
|
||||
md5: ssh_algorithm_md5(content),
|
||||
sha256: ssh_algorithm_sha256(content) }
|
||||
end
|
||||
|
||||
def ssh_algorithm_file_content(algorithm)
|
||||
file = ssh_algorithm_file(algorithm)
|
||||
return unless File.exist?(file)
|
||||
|
||||
File.read(file)
|
||||
end
|
||||
|
||||
def ssh_algorithm_md5(ssh_file_content)
|
||||
OpenSSL::Digest::MD5.hexdigest(ssh_file_content).scan(/../).join(':')
|
||||
end
|
||||
|
||||
def ssh_algorithm_sha256(ssh_file_content)
|
||||
OpenSSL::Digest::SHA256.hexdigest(ssh_file_content)
|
||||
end
|
||||
end
|
|
@ -11,6 +11,7 @@
|
|||
%span= Gitlab::VERSION
|
||||
%small= link_to Gitlab::REVISION, Gitlab::COM_URL + namespace_project_commits_path('gitlab-org', 'gitlab-ce', Gitlab::REVISION)
|
||||
= version_status_badge
|
||||
|
||||
%p.slead
|
||||
GitLab is open source software to collaborate on code.
|
||||
%br
|
||||
|
@ -23,6 +24,7 @@
|
|||
Used by more than 100,000 organizations, GitLab is the most popular solution to manage git repositories on-premises.
|
||||
%br
|
||||
Read more about GitLab at #{link_to promo_host, promo_url, target: '_blank', rel: 'noopener noreferrer'}.
|
||||
%p= link_to 'Check the current instance configuration ', help_instance_configuration_url
|
||||
%hr
|
||||
|
||||
.row.prepend-top-default
|
||||
|
|
17
app/views/help/instance_configuration.html.haml
Normal file
17
app/views/help/instance_configuration.html.haml
Normal file
|
@ -0,0 +1,17 @@
|
|||
- page_title 'Instance Configuration'
|
||||
.wiki.documentation
|
||||
%h1 Instance Configuration
|
||||
|
||||
%p
|
||||
In this page you will find information about the settings that are used in your current instance.
|
||||
|
||||
= render 'help/instance_configuration/ssh_info'
|
||||
= render 'help/instance_configuration/gitlab_pages'
|
||||
= render 'help/instance_configuration/gitlab_ci'
|
||||
%p
|
||||
%strong Table of contents
|
||||
|
||||
%ul
|
||||
= content_for :table_content
|
||||
|
||||
= content_for :settings_content
|
24
app/views/help/instance_configuration/_gitlab_ci.html.haml
Normal file
24
app/views/help/instance_configuration/_gitlab_ci.html.haml
Normal file
|
@ -0,0 +1,24 @@
|
|||
- content_for :table_content do
|
||||
%li= link_to 'GitLab CI', '#gitlab-ci'
|
||||
|
||||
- content_for :settings_content do
|
||||
%h2#gitlab-ci
|
||||
GitLab CI
|
||||
|
||||
%p
|
||||
Below are the current settings regarding
|
||||
= succeed('.') { link_to('GitLab CI', 'https://about.gitlab.com/gitlab-ci', target: '_blank') }
|
||||
|
||||
.table-responsive
|
||||
%table
|
||||
%thead
|
||||
%tr
|
||||
%th Setting
|
||||
%th= instance_configuration_host(@instance_configuration.settings[:host])
|
||||
%th Default
|
||||
%tbody
|
||||
%tr
|
||||
- artifacts_size = @instance_configuration.settings[:gitlab_ci][:artifacts_max_size]
|
||||
%td Artifacts maximum size
|
||||
%td= instance_configuration_human_size_cell(artifacts_size[:value])
|
||||
%td= instance_configuration_human_size_cell(artifacts_size[:default])
|
|
@ -0,0 +1,35 @@
|
|||
- gitlab_pages = @instance_configuration.settings[:gitlab_pages]
|
||||
- content_for :table_content do
|
||||
%li= link_to 'GitLab Pages', '#gitlab-pages'
|
||||
|
||||
- content_for :settings_content do
|
||||
%h2#gitlab-pages
|
||||
GitLab Pages
|
||||
|
||||
%p
|
||||
Below are the settings for
|
||||
= succeed('.') { link_to('Gitlab Pages', gitlab_pages[:url], target: '_blank') }
|
||||
.table-responsive
|
||||
%table
|
||||
%thead
|
||||
%tr
|
||||
%th Setting
|
||||
%th= instance_configuration_host(@instance_configuration.settings[:host])
|
||||
%tbody
|
||||
%tr
|
||||
%td Domain Name
|
||||
%td
|
||||
%code= instance_configuration_cell_html(gitlab_pages[:host])
|
||||
%tr
|
||||
%td IP Address
|
||||
%td
|
||||
%code= instance_configuration_cell_html(gitlab_pages[:ip_address])
|
||||
%tr
|
||||
%td Port
|
||||
%td
|
||||
%code= instance_configuration_cell_html(gitlab_pages[:port])
|
||||
%br
|
||||
|
||||
%p
|
||||
The maximum size of your Pages site is regulated by the artifacts maximum
|
||||
size which is part of #{succeed('.') { link_to('GitLab CI', '#gitlab-ci') }}
|
27
app/views/help/instance_configuration/_ssh_info.html.haml
Normal file
27
app/views/help/instance_configuration/_ssh_info.html.haml
Normal file
|
@ -0,0 +1,27 @@
|
|||
- ssh_info = @instance_configuration.settings[:ssh_algorithms_hashes]
|
||||
- if ssh_info.any?
|
||||
- content_for :table_content do
|
||||
%li= link_to 'SSH host keys fingerprints', '#ssh-host-keys-fingerprints'
|
||||
|
||||
- content_for :settings_content do
|
||||
%h2#ssh-host-keys-fingerprints
|
||||
SSH host keys fingerprints
|
||||
|
||||
%p
|
||||
Below are the fingerprints for the current instance SSH host keys.
|
||||
|
||||
.table-responsive
|
||||
%table
|
||||
%thead
|
||||
%tr
|
||||
%th Algorithm
|
||||
%th MD5
|
||||
%th SHA256
|
||||
%tbody
|
||||
- ssh_info.each do |algorithm|
|
||||
%tr
|
||||
%td= algorithm[:name]
|
||||
%td
|
||||
%code= instance_configuration_cell_html(algorithm[:md5])
|
||||
%td
|
||||
%code= instance_configuration_cell_html(algorithm[:sha256])
|
5
changelogs/unreleased/feature-ssh_host_fingerprint.yml
Normal file
5
changelogs/unreleased/feature-ssh_host_fingerprint.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Automatic configuration settings page
|
||||
merge_request: 13850
|
||||
author: Francisco Lopez
|
||||
type: added
|
|
@ -1,4 +1,5 @@
|
|||
get 'help' => 'help#index'
|
||||
get 'help/shortcuts' => 'help#shortcuts'
|
||||
get 'help/ui' => 'help#ui'
|
||||
get 'help/*path' => 'help#show', as: :help_page
|
||||
get 'help' => 'help#index'
|
||||
get 'help/shortcuts' => 'help#shortcuts'
|
||||
get 'help/ui' => 'help#ui'
|
||||
get 'help/instance_configuration' => 'help#instance_configuration'
|
||||
get 'help/*path' => 'help#show', as: :help_page
|
||||
|
|
5
spec/factories/instance_configuration.rb
Normal file
5
spec/factories/instance_configuration.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
FactoryGirl.define do
|
||||
factory :instance_configuration do
|
||||
skip_create
|
||||
end
|
||||
end
|
1
spec/fixtures/ssh_host_example_key.pub
vendored
Normal file
1
spec/fixtures/ssh_host_example_key.pub
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
random content
|
51
spec/helpers/instance_configuration_helper_spec.rb
Normal file
51
spec/helpers/instance_configuration_helper_spec.rb
Normal file
|
@ -0,0 +1,51 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe InstanceConfigurationHelper do
|
||||
describe '#instance_configuration_cell_html' do
|
||||
describe 'if not block is passed' do
|
||||
it 'returns the parameter if present' do
|
||||
expect(helper.instance_configuration_cell_html('gitlab')).to eq('gitlab')
|
||||
end
|
||||
|
||||
it 'returns "-" if the parameter is blank' do
|
||||
expect(helper.instance_configuration_cell_html(nil)).to eq('-')
|
||||
expect(helper.instance_configuration_cell_html('')).to eq('-')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'if a block is passed' do
|
||||
let(:upcase_block) { ->(value) { value.upcase } }
|
||||
|
||||
it 'returns the result of the block' do
|
||||
expect(helper.instance_configuration_cell_html('gitlab', &upcase_block)).to eq('GITLAB')
|
||||
expect(helper.instance_configuration_cell_html('gitlab') { |v| v.upcase }).to eq('GITLAB')
|
||||
end
|
||||
|
||||
it 'returns "-" if the parameter is blank' do
|
||||
expect(helper.instance_configuration_cell_html(nil, &upcase_block)).to eq('-')
|
||||
expect(helper.instance_configuration_cell_html(nil) { |v| v.upcase }).to eq('-')
|
||||
expect(helper.instance_configuration_cell_html('', &upcase_block)).to eq('-')
|
||||
end
|
||||
end
|
||||
|
||||
it 'boolean are valid values to display' do
|
||||
expect(helper.instance_configuration_cell_html(true)).to eq(true)
|
||||
expect(helper.instance_configuration_cell_html(false)).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#instance_configuration_human_size_cell' do
|
||||
it 'returns "-" if the parameter is blank' do
|
||||
expect(helper.instance_configuration_human_size_cell(nil)).to eq('-')
|
||||
expect(helper.instance_configuration_human_size_cell('')).to eq('-')
|
||||
end
|
||||
|
||||
it 'accepts the value in bytes' do
|
||||
expect(helper.instance_configuration_human_size_cell(1024)).to eq('1 KB')
|
||||
end
|
||||
|
||||
it 'returns the value in human size readable format' do
|
||||
expect(helper.instance_configuration_human_size_cell(1048576)).to eq('1 MB')
|
||||
end
|
||||
end
|
||||
end
|
109
spec/models/instance_configuration_spec.rb
Normal file
109
spec/models/instance_configuration_spec.rb
Normal file
|
@ -0,0 +1,109 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe InstanceConfiguration do
|
||||
context 'without cache' do
|
||||
describe '#settings' do
|
||||
describe '#ssh_algorithms_hashes' do
|
||||
let(:md5) { '54:e0:f8:70:d6:4f:4c:b1:b3:02:44:77:cf:cd:0d:fc' }
|
||||
let(:sha256) { '9327f0d15a48c4d9f6a3aee65a1825baf9a3412001c98169c5fd022ac27762fc' }
|
||||
|
||||
it 'does not return anything if file does not exist' do
|
||||
stub_pub_file(exist: false)
|
||||
|
||||
expect(subject.settings[:ssh_algorithms_hashes]).to be_empty
|
||||
end
|
||||
|
||||
it 'does not return anything if file is empty' do
|
||||
stub_pub_file
|
||||
|
||||
allow(File).to receive(:read).and_return('')
|
||||
|
||||
expect(subject.settings[:ssh_algorithms_hashes]).to be_empty
|
||||
end
|
||||
|
||||
it 'returns the md5 and sha256 if file valid and exists' do
|
||||
stub_pub_file
|
||||
|
||||
result = subject.settings[:ssh_algorithms_hashes].select { |o| o[:md5] == md5 && o[:sha256] == sha256 }
|
||||
|
||||
expect(result.size).to eq(InstanceConfiguration::SSH_ALGORITHMS.size)
|
||||
end
|
||||
|
||||
def stub_pub_file(exist: true)
|
||||
path = 'spec/fixtures/ssh_host_example_key.pub'
|
||||
path << 'random' unless exist
|
||||
allow(subject).to receive(:ssh_algorithm_file).and_return(Rails.root.join(path))
|
||||
end
|
||||
end
|
||||
|
||||
describe '#host' do
|
||||
it 'returns current instance host' do
|
||||
allow(Settings.gitlab).to receive(:host).and_return('exampledomain')
|
||||
|
||||
expect(subject.settings[:host]).to eq(Settings.gitlab.host)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#gitlab_pages' do
|
||||
let(:gitlab_pages) { subject.settings[:gitlab_pages] }
|
||||
it 'returns Settings.pages' do
|
||||
gitlab_pages.delete(:ip_address)
|
||||
|
||||
expect(gitlab_pages).to eq(Settings.pages.symbolize_keys)
|
||||
end
|
||||
|
||||
it 'returns the Gitlab\'s pages host ip address' do
|
||||
expect(gitlab_pages.keys).to include(:ip_address)
|
||||
end
|
||||
|
||||
it 'returns the ip address as nil if the domain is invalid' do
|
||||
allow(Settings.pages).to receive(:host).and_return('exampledomain')
|
||||
|
||||
expect(gitlab_pages[:ip_address]).to eq nil
|
||||
end
|
||||
|
||||
it 'returns the ip address of the domain' do
|
||||
allow(Settings.pages).to receive(:host).and_return('localhost')
|
||||
|
||||
expect(gitlab_pages[:ip_address]).to eq('127.0.0.1').or eq('::1')
|
||||
end
|
||||
end
|
||||
|
||||
describe '#gitlab_ci' do
|
||||
let(:gitlab_ci) { subject.settings[:gitlab_ci] }
|
||||
it 'returns Settings.gitalb_ci' do
|
||||
gitlab_ci.delete(:artifacts_max_size)
|
||||
|
||||
expect(gitlab_ci).to eq(Settings.gitlab_ci.symbolize_keys)
|
||||
end
|
||||
|
||||
it 'returns the key artifacts_max_size' do
|
||||
expect(gitlab_ci.keys).to include(:artifacts_max_size)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with cache', :use_clean_rails_memory_store_caching do
|
||||
it 'caches settings content' do
|
||||
expect(Rails.cache.read(described_class::CACHE_KEY)).to be_nil
|
||||
|
||||
settings = subject.settings
|
||||
|
||||
expect(Rails.cache.read(described_class::CACHE_KEY)).to eq(settings)
|
||||
end
|
||||
|
||||
describe 'cached settings' do
|
||||
before do
|
||||
subject.settings
|
||||
end
|
||||
|
||||
it 'expires after EXPIRATION_TIME' do
|
||||
allow(Time).to receive(:now).and_return(Time.now + described_class::EXPIRATION_TIME)
|
||||
Rails.cache.cleanup
|
||||
|
||||
expect(Rails.cache.read(described_class::CACHE_KEY)).to eq(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -25,6 +25,14 @@ describe 'help/index' do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'instance configuration link' do
|
||||
it 'is visible to guests' do
|
||||
render
|
||||
|
||||
expect(rendered).to have_link(nil, help_instance_configuration_url)
|
||||
end
|
||||
end
|
||||
|
||||
def stub_user(user = double)
|
||||
allow(view).to receive(:user_signed_in?).and_return(user)
|
||||
end
|
||||
|
|
29
spec/views/help/instance_configuration.html.haml_spec.rb
Normal file
29
spec/views/help/instance_configuration.html.haml_spec.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe 'help/instance_configuration' do
|
||||
describe 'General Sections:' do
|
||||
let(:instance_configuration) { build(:instance_configuration)}
|
||||
let(:settings) { instance_configuration.settings }
|
||||
let(:ssh_settings) { settings[:ssh_algorithms_hashes] }
|
||||
|
||||
before do
|
||||
assign(:instance_configuration, instance_configuration)
|
||||
end
|
||||
|
||||
it 'has links to several sections' do
|
||||
render
|
||||
|
||||
expect(rendered).to have_link(nil, '#ssh-host-keys-fingerprints') if ssh_settings.any?
|
||||
expect(rendered).to have_link(nil, '#gitlab-pages')
|
||||
expect(rendered).to have_link(nil, '#gitlab-ci')
|
||||
end
|
||||
|
||||
it 'has several sections' do
|
||||
render
|
||||
|
||||
expect(rendered).to have_css('h2#ssh-host-keys-fingerprints') if ssh_settings.any?
|
||||
expect(rendered).to have_css('h2#gitlab-pages')
|
||||
expect(rendered).to have_css('h2#gitlab-ci')
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue