Get Geo secondaries nodes statuses over AJAX

parent a67245a8
......@@ -43,6 +43,8 @@ import GroupsList from './groups_list';
import ProjectsList from './projects_list';
import MiniPipelineGraph from './mini_pipeline_graph_dropdown';
import GeoNodes from './geo_nodes';
const ShortcutsBlob = require('./shortcuts_blob');
const UserCallout = require('./user_callout');
......@@ -348,6 +350,9 @@ const UserCallout = require('./user_callout');
case 'abuse_reports':
new gl.AbuseReports();
break;
case 'geo_nodes':
new GeoNodes($('.geo-nodes'));
break;
}
break;
case 'dashboard':
......
/* eslint-disable no-new*/
import './smart_interval';
const healthyClass = 'geo-node-icon-healthy';
const unhealthyClass = 'geo-node-icon-unhealthy';
class GeoNodeStatus {
constructor(el) {
this.$el = $(el);
this.$icon = $('.js-geo-node-icon', this.$el);
this.$status = $('.js-geo-node-status', this.$el);
this.$repositoriesSynced = $('.js-repositories-synced', this.$status);
this.$repositoriesFailed = $('.js-repositories-failed', this.$status);
this.$lfsObjectsSynced = $('.js-lfs-objects-synced', this.$status);
this.$health = $('.js-health', this.$status);
this.endpoint = this.$el.data('status-url');
this.statusInterval = new gl.SmartInterval({
callback: this.getStatus.bind(this),
startingInterval: 30000,
maxInterval: 120000,
hiddenInterval: 240000,
incrementByFactorOf: 15000,
immediateExecution: true,
});
}
getStatus() {
$.getJSON(this.endpoint, (status) => {
this.setStatusIcon(status.healthy);
this.$repositoriesSynced.html(`${status.repositories_synced_count}/${status.repositories_count} (${status.repositories_synced_in_percentage})`);
this.$repositoriesFailed.html(status.repositories_failed_count);
this.$lfsObjectsSynced.html(`${status.lfs_objects_synced_count}/${status.lfs_objects_count} (${status.lfs_objects_synced_in_percentage})`);
this.$health.html(status.health);
this.$status.show();
});
}
setStatusIcon(healthy) {
if (healthy) {
this.$icon.removeClass(unhealthyClass)
.addClass(healthyClass)
.attr('title', 'Healthy');
} else {
this.$icon.removeClass(healthyClass)
.addClass(unhealthyClass)
.attr('title', 'Unhealthy');
}
this.$icon.tooltip('fixTitle');
}
}
class GeoNodes {
constructor(container) {
this.$container = $(container);
this.pollForSecondaryNodeStatus();
}
pollForSecondaryNodeStatus() {
$('.js-geo-secondary-node', this.$container).each((i, el) => {
new GeoNodeStatus(el);
});
}
}
export default GeoNodes;
class Admin::GeoNodesController < Admin::ApplicationController
before_action :check_license, except: [:index, :destroy]
before_action :load_node, only: [:destroy, :repair, :toggle]
before_action :load_node, only: [:destroy, :repair, :toggle, :status]
def index
# Ensure all nodes are using their Presenter
......@@ -57,6 +57,16 @@ class Admin::GeoNodesController < Admin::ApplicationController
redirect_to admin_geo_nodes_path
end
def status
status = Geo::NodeStatusService.new.call(@node)
respond_to do |format|
format.json do
render json: GeoNodeStatusSerializer.new.represent(status)
end
end
end
private
def geo_node_params
......
......@@ -4,15 +4,10 @@ module EE
if node.primary?
icon 'star fw', class: 'has-tooltip', title: 'Primary node'
else
status =
if node.enabled?
node.healthy? ? 'healthy' : 'unhealthy'
else
'disabled'
end
status = node.enabled? ? 'healthy' : 'disabled'
icon 'globe fw',
class: "geo-node-icon-#{status} has-tooltip",
class: "js-geo-node-icon geo-node-icon-#{status} has-tooltip",
title: status.capitalize
end
end
......
class GeoNodeStatus
include ActiveModel::Model
attr_accessor :id
attr_writer :health
def health
......
class GeoNodeStatusEntity < Grape::Entity
include ActionView::Helpers::NumberHelper
expose :id
expose :healthy?, as: :healthy
expose :health do |node|
node.healthy? ? 'No Health Problems Detected' : node.health
end
expose :lfs_objects_total, as: :lfs_objects_count
expose :lfs_objects_synced, as: :lfs_objects_synced_count
expose :lfs_objects_synced_in_percentage do |node|
number_to_percentage(node.lfs_objects_synced_in_percentage, precision: 2)
end
expose :repositories_count
expose :repositories_failed_count
expose :repositories_synced_count
expose :repositories_synced_in_percentage do |node|
number_to_percentage(node.repositories_synced_in_percentage, precision: 2)
end
end
class GeoNodeStatusSerializer < BaseSerializer
entity GeoNodeStatusEntity
end
......@@ -5,10 +5,10 @@ module Geo
KEYS = %w(health repositories_count repositories_synced_count repositories_failed_count lfs_objects_total lfs_objects_synced).freeze
def call(status_url)
def call(geo_node)
values =
begin
response = self.class.get(status_url, headers: headers, timeout: timeout)
response = self.class.get(geo_node.status_url, headers: headers, timeout: timeout)
if response.success?
response.parsed_response.values_at(*KEYS)
......@@ -19,7 +19,7 @@ module Geo
[e.message]
end
GeoNodeStatus.new(KEYS.zip(values).to_h)
GeoNodeStatus.new(KEYS.zip(values).to_h.merge(id: geo_node.id))
end
private
......
......@@ -14,9 +14,9 @@
.panel.panel-default
.panel-heading
Geo nodes (#{@nodes.count})
%ul.well-list
%ul.well-list.geo-nodes
- @nodes.each do |node|
%li
%li{ id: dom_id(node), class: ('js-geo-secondary-node' if node.secondary?), data: { status_url: status_admin_geo_node_path(node) } }
.list-item-name
%span
= node_status_icon(node)
......@@ -24,17 +24,21 @@
- if node.primary?
%span.help-block Primary node
- else
%p
%span.help-block
Repositories synced: #{node.repositories_synced_count}/#{node.repositories_count} (#{number_to_percentage(node.repositories_synced_in_percentage, precision: 2)})
%p
%span.help-block
Repositories failed: #{node.repositories_failed_count}
%p
%span.help-block
LFS objects synced: #{node.lfs_objects_synced}/#{node.lfs_objects_total} (#{number_to_percentage(node.lfs_objects_synced_in_percentage, precision: 2)})
%p
%span.help-block= node.healthy? ? 'No Health Problems Detected' : node.health
.js-geo-node-status{ style: 'display: none' }
%p
%span.help-block
Repositories synced:
%span.js-repositories-synced
%p
%span.help-block
Repositories failed:
%span.js-repositories-failed
%p
%span.help-block
LFS objects synced:
%span.js-lfs-objects-synced
%p
%span.help-block.js-health
.pull-right
- if Gitlab::Geo.license_allows?
......
......@@ -119,6 +119,7 @@ namespace :admin do
member do
post :repair
post :toggle
get :status
end
end
## EE-specific
......
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