Skip to content

Commit

Permalink
Fixes #29516 - Add Tracer bulk action support
Browse files Browse the repository at this point in the history
  • Loading branch information
chris1984 committed May 8, 2020
1 parent 89f8339 commit 93fab73
Show file tree
Hide file tree
Showing 17 changed files with 326 additions and 5 deletions.
39 changes: 39 additions & 0 deletions app/controllers/katello/api/v2/host_tracer_controller.rb
Expand Up @@ -16,6 +16,45 @@ def index
respond_for_index(:collection => collection)
end

api :PUT, "/traces/resolve", N_("Resolve Traces")
param :trace_ids, Array, :required => true, :desc => N_("Array of Trace IDs")
def resolve
traces = Katello::HostTracer.resolvable.where(id: params[:trace_ids])

traces.each do |trace|
if trace.helper.include?('reboot')
trace.helper = 'reboot'
end
end

traces_by_host_id = traces.group_by(&:host_id)
traces_by_helper = traces.group_by(&:helper)

composers = []

if traces_by_host_id.size < traces_by_helper.size
traces_by_host_id.each do |host_id, trace|
needed_traces = trace.map(&:helper).join(',')
joined_helpers = { :helper => needed_traces }
composers << JobInvocationComposer.for_feature(:katello_service_restart, [host_id], joined_helpers)
end
else
traces_by_helper.each do |helper, trace|
helpers = { :helper => helper }
composers << JobInvocationComposer.for_feature(:katello_service_restart, trace.map(&:host_id), helpers)
end
end

job_invocations = []

composers.each do |composer|
composer.trigger
job_invocations << composer.job_invocation
end

render json: job_invocations
end

protected

def index_relation
Expand Down
Expand Up @@ -225,6 +225,13 @@ def release_version
respond_for_async :resource => task
end

api :POST, "/hosts/bulk/traces", N_("Fetch traces for one or more hosts")
param_group :bulk_params
def traces
collection = scoped_search(Katello::HostTracer.where(host_id: @hosts.pluck(:id)), 'application', 'desc', resource_class: Katello::HostTracer)
respond_for_index(:collection => collection, :template => '../../../api/v2/host_tracer/index')
end

api :POST, "/hosts/bulk/available_incremental_updates", N_("Given a set of hosts and errata, lists the content view versions" \
" and environments that need updating.")
param_group :bulk_params
Expand Down
14 changes: 14 additions & 0 deletions app/models/katello/authorization/host_tracer.rb
@@ -0,0 +1,14 @@
module Katello
module Authorization::HostTracer
extend ActiveSupport::Concern

include Authorizable

module ClassMethods
def resolvable
relation = joins_authorized(::Host::Managed, :edit_hosts)
relation
end
end
end
end
2 changes: 2 additions & 0 deletions app/models/katello/host_tracer.rb
@@ -1,5 +1,7 @@
module Katello
class HostTracer < Katello::Model
include Katello::Authorization::HostTracer

belongs_to :host, :inverse_of => :host_traces, :class_name => '::Host::Managed'

validates :application, :length => {:maximum => 255}, :presence => true
Expand Down
1 change: 1 addition & 0 deletions app/views/katello/api/v2/host_tracer/base.json.rabl
Expand Up @@ -4,3 +4,4 @@ attributes :id, :id
attributes :application, :application
attributes :helper, :helper
attributes :app_type, :app_type
attributes :host_id, :host
6 changes: 6 additions & 0 deletions config/routes/api/v2.rb
Expand Up @@ -304,6 +304,12 @@ class ActionDispatch::Routing::Mapper
end
end

api_resources :traces, :only => [], :controller => 'host_tracer' do
collection do
put :resolve
end
end

api_resources :srpms, :only => [:index, :show], :controller => 'srpms' do
collection do
get :auto_complete_search
Expand Down
1 change: 1 addition & 0 deletions config/routes/overrides.rb
Expand Up @@ -76,6 +76,7 @@ def matches?(request)
match '/bulk/destroy' => 'hosts_bulk_actions#destroy_hosts', :via => :put
match '/bulk/environment_content_view' => 'hosts_bulk_actions#environment_content_view', :via => :put
match '/bulk/release_version' => 'hosts_bulk_actions#release_version', :via => :put
match '/bulk/traces' => 'hosts_bulk_actions#traces', :via => :post
match '/bulk/available_incremental_updates' => 'hosts_bulk_actions#available_incremental_updates', :via => :post
match '/bulk/module_streams' => 'hosts_bulk_actions#module_streams', :via => :post
match '/subscriptions/' => 'host_subscriptions#create', :via => :post
Expand Down
@@ -0,0 +1,61 @@
/**
* @ngdoc object
* @name Bastion.content-hosts.controller:ContentHostsBulkTracesController
*
* @requires $scope
* @requires $uibModalInstance
* @requires HostBulkAction
* @requires Notification
* @requires Nutupane
* @requires BastionConfig
* @requires hostIds
* @requires HostTracesResolve
* @requires translate
*
* @description
* Provides the functionality to support resolving traces on multiple hosts.
*/
/*jshint camelcase:false*/
angular.module('Bastion.content-hosts').controller('ContentHostsBulkTracesController',
['$scope', '$uibModalInstance', 'HostBulkAction', 'Notification', 'Nutupane', 'BastionConfig', 'hostIds', 'HostTracesResolve', 'translate',
function ($scope, $uibModalInstance, HostBulkAction, Notification, Nutupane, BastionConfig, hostIds, HostTracesResolve, translate) {

var tracesNutupane = new Nutupane(HostBulkAction, hostIds, 'traces');
tracesNutupane.enableSelectAllResults();
tracesNutupane.masterOnly = true;
$scope.table = tracesNutupane.table;
$scope.remoteExecutionPresent = BastionConfig.remoteExecutionPresent;

$scope.performViaRemoteExecution = function() {
var traceids = _.map($scope.table.getSelected(), 'id');

var onSuccess = function () {
var message = translate('Successfully initiated restart of services.');
Notification.setSuccessMessage(message, {
link: {
children: translate("View job invocations."),
href: translate("/job_invocations")
}});
$scope.ok();
};

var onFailure = function (response) {
angular.forEach(response.data.errors, function (responseError) {
Notification.setErrorMessage(responseError);
});
};
/* eslint-disable camelcase */
HostTracesResolve.resolve({trace_ids: traceids}, onSuccess, onFailure);
/* eslint-enable camelcase */
};

$scope.ok = function () {
$uibModalInstance.close();
};

$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};

}
]);
@@ -0,0 +1,74 @@
<div data-extend-template="components/views/bst-modal.html">
<h4 data-block="modal-header">Content Host Traces Management</h4>

<div data-block="modal-body">

<div class="row">
<div class="col-sm-12">
<div bst-global-notification></div>
</div>
</div>

<div bst-alert="info" ng-hide="remoteExecutionPresent">
<span translate>
The Remote Execution plugin needs to be installed in order to resolve Traces.
</span>
</div>

<div data-extend-template="layouts/partials/table.html">
<div data-block="search" ng-show="false"></div>
<span data-block="list-actions">
<div bst-modal="performViaRemoteExecution()">
<div data-block="modal-header" translate>Confirm services restart</div>
<div data-block="modal-body" translate>Are you sure you want to restart the services on the selected content hosts?</div>
<span data-block="modal-confirm-button">
<button class="btn btn-danger" ng-click="ok()">
<span translate>Restart</span>
</button>
</span>
</div>

<span class="btn-group">
<button class="btn btn-danger" type="button"
translate
ng-hide="denied('edit_hosts', host)"
ng-disabled="table.getSelected().length == 0 || !remoteExecutionPresent"
ng-click="openModal()">
Restart Selected
</button>
</span>
</span>

<span data-block="no-rows-message" translate>
There are no Traces to display.
</span>

<div data-block="table">
<div data-extend-template="layouts/select-all-results.html"></div>
<table bst-table="table" class="table table-striped table-bordered" ng-class="{'table-mask': table.working}">
<thead>
<tr bst-table-head row-select>
<th bst-table-column="application" translate>Application</th>
<th bst-table-column="app_type" translate>Type</th>
<th bst-table-column="helper" translate>Helper</th>
<th bst-table-column="affected_hosts" translate>Hostname</th>
</tr>
</thead>
<tbody>
<tr bst-table-row ng-repeat="trace in table.rows" row-select="trace">
<td bst-table-cell >{{ trace.application }}</td>
<td bst-table-cell >{{ trace.app_type }}</td>
<td bst-table-cell >{{ trace.helper }}</td>
<td bst-table-cell >{{ trace.host }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div data-block="modal-footer">
<button type="button" class="btn btn-primary" ng-click="cancel()" translate>
Cancel
</button>
</div>
</div>
Expand Up @@ -69,6 +69,17 @@ angular.module('Bastion.content-hosts').service('ContentHostsModalHelper', ['$ui
});
};

this.openTracesModal = function() {
$uibModal.open({
templateUrl: 'content-hosts/bulk/views/content-hosts-bulk-traces-modal.html',
controller: 'ContentHostsBulkTracesController',
size: 'lg',
resolve: {
hostIds: this.resolveFunc()
}
});
};

this.openSubscriptionsModal = function() {
$uibModal.open({
templateUrl: 'content-hosts/bulk/views/content-hosts-bulk-subscriptions-modal.html',
Expand Down
Expand Up @@ -157,5 +157,10 @@ angular.module('Bastion.content-hosts').controller('ContentHostsController',
nutupane.invalidate();
ContentHostsModalHelper.openModuleStreamsModal();
};

$scope.openTracesModal = function () {
nutupane.invalidate();
ContentHostsModalHelper.openTracesModal();
};
}]
);
Expand Up @@ -51,6 +51,10 @@ <h2 translate>Content Hosts</h2>
<a ng-click="openModuleStreamsModal()" disable-link="table.numSelected === 0" translate>Manage Module Streams</a>
</li>

<li role="menuitem" ng-show="permitted('edit_hosts')" ng-class="{disabled: table.numSelected === 0}">
<a ng-click="openTracesModal()" disable-link="table.numSelected === 0" translate>Manage Host Traces</a>
</li>

<li class="divider"></li>

<li role="menuitem" ng-show="permitted('destroy_hosts')" ng-class="{disabled: table.numSelected === 0}">
Expand Down
Expand Up @@ -25,7 +25,8 @@ angular.module('Bastion.hosts').factory('HostBulkAction',
environmentContentView: {method: 'PUT', params: {action: 'environment_content_view'}},
releaseVersion: {method: 'PUT', params: {action: 'release_version'}},
availableIncrementalUpdates: {method: 'POST', isArray: true, params: {action: 'available_incremental_updates'}},
moduleStreams: {method: 'POST', params: {action: 'module_streams'}}
moduleStreams: {method: 'POST', params: {action: 'module_streams'}},
traces: {method: 'POST', params: {action: 'traces'}}
});

}]
Expand Down
@@ -0,0 +1,18 @@
/**
* @ngdoc service
* @name Bastion.hosts.factory:HostTracesResolve
*
* @requires BastionResource
*
* @description
* Provides a BastionResource for resolving traces on a set of systems.
*/
angular.module('Bastion.hosts').factory('HostTracesResolve',
['BastionResource', function (BastionResource) {

return BastionResource('katello/api/v2/traces/:action', {}, {
resolve: {method: 'PUT', isArray: true, params: {action: 'resolve'}}
});

}]
);
2 changes: 2 additions & 0 deletions lib/katello/permissions/host_permissions.rb
Expand Up @@ -26,6 +26,7 @@
'katello/api/v2/hosts_bulk_actions/content_overrides',
'katello/api/v2/hosts_bulk_actions/environment_content_view',
'katello/api/v2/hosts_bulk_actions/release_version',
'katello/api/v2/hosts_bulk_actions/traces',
'katello/api/rhsm/candlepin_dynflow_proxy/upload_package_profile',
'katello/api/rhsm/candlepin_dynflow_proxy/upload_profiles',
'katello/api/rhsm/candlepin_dynflow_proxy/deb_package_profile',
Expand Down Expand Up @@ -55,6 +56,7 @@
'katello/api/v2/host_debs/index',
'katello/api/v2/host_packages/index',
'katello/api/v2/host_tracer/index',
'katello/api/v2/host_tracer/resolve',
'katello/remote_execution/new',
'katello/remote_execution/create'
]
Expand Down

0 comments on commit 93fab73

Please sign in to comment.