Commit 46a1af50 authored by Nick Thomas's avatar Nick Thomas

Merge branch 'sh-geo-handle-no-current-geo-node' into 'master'

Gracefully handle case where current instance is not a Geo Node

See merge request gitlab-org/gitlab-ee!2977
parents ac6378c0 304aebc2
...@@ -12,6 +12,7 @@ class Admin::ApplicationController < ApplicationController ...@@ -12,6 +12,7 @@ class Admin::ApplicationController < ApplicationController
def display_geo_information def display_geo_information
return unless Gitlab::Geo.secondary? return unless Gitlab::Geo.secondary?
return unless Gitlab::Geo.primary_node_configured?
primary_node = view_context.link_to('primary node', Gitlab::Geo.primary_node.url) primary_node = view_context.link_to('primary node', Gitlab::Geo.primary_node.url)
flash.now[:notice] = "You are on a secondary (read-only) Geo node. If you want to make any changes, you must visit the #{primary_node}.".html_safe flash.now[:notice] = "You are on a secondary (read-only) Geo node. If you want to make any changes, you must visit the #{primary_node}.".html_safe
......
...@@ -39,6 +39,8 @@ module Geo ...@@ -39,6 +39,8 @@ module Geo
Array([message, details].compact.join("\n")) Array([message, details].compact.join("\n"))
end end
rescue Gitlab::Geo::GeoNodeNotFoundError
['This GitLab instance does not appear to be configured properly as a Geo node. Make sure the URLs are using the correct fully-qualified domain names.']
rescue OpenSSL::Cipher::CipherError rescue OpenSSL::Cipher::CipherError
['Error decrypting the Geo secret from the database. Check that the primary uses the correct db_key_base.'] ['Error decrypting the Geo secret from the database. Check that the primary uses the correct db_key_base.']
rescue HTTParty::Error, Timeout::Error, SocketError, SystemCallError, OpenSSL::SSL::SSLError => e rescue HTTParty::Error, Timeout::Error, SocketError, SystemCallError, OpenSSL::SSL::SSLError => e
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
= link_to sherlock_transactions_path, class: 'admin-icon', title: 'Sherlock Transactions', = link_to sherlock_transactions_path, class: 'admin-icon', title: 'Sherlock Transactions',
data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('tachometer fw') = icon('tachometer fw')
- if Gitlab::Geo.secondary? - if Gitlab::Geo.secondary? && Gitlab::Geo.primary_node_configured?
%li %li
= link_to Gitlab::Geo.primary_node.url, title: 'Go to primary node', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = link_to Gitlab::Geo.primary_node.url, title: 'Go to primary node', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('globe fw') = icon('globe fw')
module Gitlab module Gitlab
module Geo module Geo
OauthApplicationUndefinedError = Class.new(StandardError) OauthApplicationUndefinedError = Class.new(StandardError)
GeoNodeNotFoundError = Class.new(StandardError)
CACHE_KEYS = %i( CACHE_KEYS = %i(
geo_primary_node geo_primary_node
...@@ -49,6 +50,10 @@ module Gitlab ...@@ -49,6 +50,10 @@ module Gitlab
Rails.configuration.respond_to?(:geo_database) Rails.configuration.respond_to?(:geo_database)
end end
def self.primary_node_configured?
Gitlab::Geo.primary_node.present?
end
def self.license_allows? def self.license_allows?
::License.feature_available?(:geo) ::License.feature_available?(:geo)
end end
......
...@@ -9,6 +9,7 @@ module Gitlab ...@@ -9,6 +9,7 @@ module Gitlab
@request_data = request_data @request_data = request_data
end end
# Raises GeoNodeNotFoundError if current node is not a Geo node
def headers def headers
{ {
'Authorization' => geo_auth_token(request_data) 'Authorization' => geo_auth_token(request_data)
...@@ -19,7 +20,7 @@ module Gitlab ...@@ -19,7 +20,7 @@ module Gitlab
def geo_auth_token(message) def geo_auth_token(message)
geo_node = requesting_node geo_node = requesting_node
return unless geo_node raise GeoNodeNotFoundError unless geo_node
payload = { data: message.to_json, iat: Time.now.to_i } payload = { data: message.to_json, iat: Time.now.to_i }
token = JWT.encode(payload, geo_node.secret_access_key, 'HS256') token = JWT.encode(payload, geo_node.secret_access_key, 'HS256')
......
...@@ -43,6 +43,20 @@ describe Gitlab::Geo do ...@@ -43,6 +43,20 @@ describe Gitlab::Geo do
end end
end end
describe 'primary_node_configured?' do
context 'when current node is a primary node' do
it 'returns true' do
primary_node
expect(described_class.primary_node_configured?).to be_truthy
end
it 'returns false when primary does not exist' do
expect(described_class.primary_node_configured?).to be_falsey
end
end
end
describe 'secondary?' do describe 'secondary?' do
context 'when current node is a secondary node' do context 'when current node is a secondary node' do
before do before do
......
...@@ -83,5 +83,13 @@ describe Geo::NodeStatusService do ...@@ -83,5 +83,13 @@ describe Geo::NodeStatusService do
expect(status.health).to eq('Error decrypting the Geo secret from the database. Check that the primary uses the correct db_key_base.') expect(status.health).to eq('Error decrypting the Geo secret from the database. Check that the primary uses the correct db_key_base.')
end end
it 'gracefully handles case when primary is deleted' do
primary.destroy
status = subject.call(secondary)
expect(status.health).to eq('This GitLab instance does not appear to be configured properly as a Geo node. Make sure the URLs are using the correct fully-qualified domain names.')
end
end end
end end
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