Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Opt-in email notifications when {repo sync, cv promote, cv publish, proxy sync} fails #10742

Merged
merged 7 commits into from
Oct 4, 2023
39 changes: 30 additions & 9 deletions app/lib/actions/katello/capsule_content/sync.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ module Actions
module Katello
module CapsuleContent
class Sync < ::Actions::EntryAction
include ::Actions::ObservableAction
def resource_locks
:link
end

execution_plan_hooks.use :notify_on_failure, :on => [:failure, :paused]

input_format do
param :name
end
Expand All @@ -19,20 +22,16 @@ def humanized_input
end

def plan(smart_proxy, options = {})
input[:options] = options

action_subject(smart_proxy)
smart_proxy.verify_ueber_certs
environment_id = options.fetch(:environment_id, nil)
environment = ::Katello::KTEnvironment.find(environment_id) if environment_id
repository_id = options.fetch(:repository_id, nil)
repository = ::Katello::Repository.find(repository_id) if repository_id
content_view_id = options.fetch(:content_view_id, nil)
content_view = ::Katello::ContentView.find(content_view_id) if content_view_id

subjects = subjects(options)

fail _("Action not allowed for the default smart proxy.") if smart_proxy.pulp_primary?

refresh_options = options.merge(content_view: content_view,
environment: environment,
repository: repository)
refresh_options = options.merge(subjects)
sequence do
if smart_proxy.has_feature?(SmartProxy::PULP3_FEATURE)
plan_action(Actions::Pulp3::ContentGuard::Refresh, smart_proxy)
Expand All @@ -49,6 +48,28 @@ def finalize
smart_proxy&.audit_capsule_sync
end
end

def notify_on_failure(_plan)
notification = MailNotification[:proxy_sync_failure]
proxy = SmartProxy.find(input.fetch(:smart_proxy, {})[:id])
subjects = subjects(input[:options]).merge(smart_proxy: proxy)
notification.users.each do |user|
notification.deliver(subjects.merge(user: user, task: task))
end
end

def subjects(options = {})
environment_id = options.fetch(:environment_id, nil)
environment = ::Katello::KTEnvironment.find(environment_id) if environment_id

repository_id = options.fetch(:repository_id, nil)
repository = ::Katello::Repository.find(repository_id) if repository_id

content_view_id = options.fetch(:content_view_id, nil)
content_view = ::Katello::ContentView.find(content_view_id) if content_view_id

{content_view: content_view, environment: environment, repository: repository}
end
end
end
end
Expand Down
9 changes: 9 additions & 0 deletions app/lib/actions/katello/content_view/promote.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module ContentView
class Promote < Actions::EntryAction
extend ApipieDSL::Class
include ::Actions::ObservableAction
execution_plan_hooks.use :notify_on_failure, :on => [:failure, :paused]

def plan(version, environments, is_force = false, description = nil, incremental_update = false)
action_subject(version.content_view)
Expand All @@ -23,6 +24,14 @@ def plan(version, environments, is_force = false, description = nil, incremental
end
end

def notify_on_failure(_plan)
notification = MailNotification[:content_view_promote_failure]
view = ::Katello::ContentView.find(input.fetch(:content_view, {})[:id])
notification.users.each do |user|
notification.deliver(user: user, content_view: view, task: task)
end
end

def environments
input['environments']
end
Expand Down
9 changes: 9 additions & 0 deletions app/lib/actions/katello/content_view/publish.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class Publish < Actions::EntryAction
include ::Actions::ObservableAction
attr_accessor :version
execution_plan_hooks.use :trigger_capsule_sync, :on => :success
execution_plan_hooks.use :notify_on_failure, :on => [:failure, :paused]

# rubocop:disable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity
def plan(content_view, description = "", options = {importing: false, syncable: false}) # rubocop:disable Metrics/PerceivedComplexity
Expand Down Expand Up @@ -132,6 +133,14 @@ def trigger_capsule_sync(_execution_plan)
end
end

def notify_on_failure(_plan)
notification = MailNotification[:content_view_publish_failure]
view = ::Katello::ContentView.find(input.fetch(:content_view, {})[:id])
notification.users.each do |user|
notification.deliver(user: user, content_view: view, task: task)
end
end

def content_view_version_id
input['content_view_version_id']
end
Expand Down
10 changes: 10 additions & 0 deletions app/lib/actions/katello/repository/sync.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ class Sync < Actions::EntryAction
include ::Actions::ObservableAction
middleware.use Actions::Middleware::ExecuteIfContentsChanged

execution_plan_hooks.use :notify_on_failure, :on => [:failure, :paused]

input_format do
param :id, Integer
param :sync_result, Hash
Expand Down Expand Up @@ -96,6 +98,14 @@ def rescue_strategy
Dynflow::Action::Rescue::Skip
end

def notify_on_failure(_plan)
notification = MailNotification[:repository_sync_failure]
repo = ::Katello::Repository.find(input.fetch(:repository, {})[:id])
notification.users.each do |user|
notification.deliver(user: user, repo: repo, task: task)
end
end

def repository_id
input['repository']['id']
end
Expand Down
54 changes: 54 additions & 0 deletions app/mailers/katello/task_mailer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
module Katello
class TaskMailer < ApplicationMailer
helper ApplicationHelper
include Rails.application.routes.url_helpers

def repo_sync_failure(options)
user, @repo, @task = options.values_at(:user, :repo, :task)

::User.as(user.login) do
subject = _("Repository %{label} failed to synchronize") % { :label => @repo.label }

set_locale_for(user) do
mail(:to => user.mail, :subject => subject)
end
end
end

def cv_publish_failure(options)
user, @content_view, @task = options.values_at(:user, :content_view, :task)

::User.as(user.login) do
subject = _("%{label} failed") % { :label => @task.action }

set_locale_for(user) do
mail(:to => user.mail, :subject => subject)
end
end
end

def cv_promote_failure(options)
user, @content_view, @task = options.values_at(:user, :content_view, :task)

::User.as(user.login) do
subject = _("%{label} failed") % { :label => @task.action }

set_locale_for(user) do
mail(:to => user.mail, :subject => subject)
end
end
end

def proxy_sync_failure(options)
user, @environment, @repo, @content_view, @task, @smart_proxy = options.values_at(:user, :environment, :repository, :content_view, :task, :smart_proxy)

::User.as(user.login) do
subject = _("%{label} failed") % { :label => @task.action }

set_locale_for(user) do
mail(:to => user.mail, :subject => subject)
end
end
end
end
end
31 changes: 31 additions & 0 deletions app/views/katello/task_mailer/cv_promote_failure.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<p>
<%= _("%{label} failed.") % { :label => @task.action } %>
</p>

<div class="dashboard">
<table>
<tr>
<td><%= _('Content view') %></td>
<td><%= link_to @content_view.name, "#{katello_url}content_views/#{@content_view.id}" %></td>
</tr>
<tr>
<td><%= _('Task ID') %></td>
<td><%= link_to @task.id, foreman_tasks_task_url(@task.id) %></td>
</tr>
<tr>
<td><%= _('Task state') %></td>
<td><%= @task.state %></td>
</tr>
<tr>
<td><%= _('Task result') %></td>
<td><%= @task.result %></td>
</tr>
</table>

Errors:
<ul>
<% @task.execution_plan.errors.each do |error| %>
<li><%= error.exception_class %>: <%= error.message %></li>
<% end %>
</ul>
</div>
13 changes: 13 additions & 0 deletions app/views/katello/task_mailer/cv_promote_failure.text.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<%= _("%{label} failed.") % { :label => @task.action } %>

<%= _('Content view ID') %>: <%= @content_view.id %>
<%= _('Content view name') %>: <%= @content_view.name %>
<%= _('Task ID') %>: <%= @task.id %>
<%= _('Task state') %>: <%= @task.state %>
<%= _('Task result') %>: <%= @task.result %>
<%= _('Task details') %>: <%= foreman_tasks_task_url(@task) %>

Errors:
<% @task.execution_plan.errors.each do |error| %>
- <%= error.exception_class %>: <%= error.message %>
<% end %>
31 changes: 31 additions & 0 deletions app/views/katello/task_mailer/cv_publish_failure.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<p>
<%= _("%{label} failed.") % { :label => @task.action } %>
</p>

<div class="dashboard">
<table>
<tr>
<td><%= _('Content view') %></td>
<td><%= link_to @content_view.name, "#{katello_url}content_views/#{@content_view.id}" %></td>
</tr>
<tr>
<td><%= _('Task ID') %></td>
<td><%= link_to @task.id, foreman_tasks_task_url(@task.id) %></td>
</tr>
<tr>
<td><%= _('Task state') %></td>
<td><%= @task.state %></td>
</tr>
<tr>
<td><%= _('Task result') %></td>
<td><%= @task.result %></td>
</tr>
</table>

Errors:
<ul>
<% @task.execution_plan.errors.each do |error| %>
<li><%= error.exception_class %>: <%= error.message %></li>
<% end %>
</ul>
</div>
13 changes: 13 additions & 0 deletions app/views/katello/task_mailer/cv_publish_failure.text.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<%= _("%{label} failed.") % { :label => @task.action } %>

<%= _('Content view ID') %>: <%= @content_view.id %>
<%= _('Content view name') %>: <%= @content_view.name %>
<%= _('Task ID') %>: <%= @task.id %>
<%= _('Task state') %>: <%= @task.state %>
<%= _('Task result') %>: <%= @task.result %>
<%= _('Task details') %>: <%= foreman_tasks_task_url(@task) %>

Errors:
<% @task.execution_plan.errors.each do |error| %>
- <%= error.exception_class %>: <%= error.message %>
<% end %>
45 changes: 45 additions & 0 deletions app/views/katello/task_mailer/proxy_sync_failure.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<p>
<%= _("%{label} failed.") % { :label => @task.action } %>
</p>

<div class="dashboard">
<table>
<% if @environment %>
<tr>
<td><%= _('Environment') %></td>
<td><%= link_to @environment.name, "#{katello_url}lifecycle_environments/#{@environment.id}" %></td>
</tr>
<% end %>
<% if @content_view %>
<tr>
<td><%= _('Content view') %></td>
<td><%= link_to @content_view.name, "#{katello_url}content_views/#{@content_view.id}" %></td>
</tr>
<% end %>
<% if @repo %>
<tr>
<td><%= _('Repository') %></td>
<td><%= link_to @repo.name, "#{katello_url}products/#{@repo.product.id}/repositories/#{@repo.id}" %></td>
</tr>
<% end %>
<tr>
<td><%= _('Task ID') %></td>
<td><%= link_to @task.id, foreman_tasks_task_url(@task.id) %></td>
</tr>
<tr>
<td><%= _('Task state') %></td>
<td><%= @task.state %></td>
</tr>
<tr>
<td><%= _('Task result') %></td>
<td><%= @task.result %></td>
</tr>
</table>

Errors:
<ul>
<% @task.execution_plan.errors.each do |error| %>
<li><%= error.exception_class %>: <%= error.message %></li>
<% end %>
</ul>
</div>
25 changes: 25 additions & 0 deletions app/views/katello/task_mailer/proxy_sync_failure.text.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<%= _("%{label} failed.") % { :label => @task.action } %>

<%= _('Smart proxy ID') %>: <%= @smart_proxy.id %>
<%= _('Smart proxy name') %>: <%= @smart_proxy.name %>
<% if @environment %>
<%= _('Environment ID') %>: <%= @environment&.id %>
<%= _('Environment name') %>: <%= @environment&.name %>
<% end %>
<% if @content_view %>
<%= _('Content view ID') %>: <%= @content_view&.id %>
<%= _('Content view name') %>: <%= @content_view&.name %>
<% end %>
<% if @repo %>
<%= _('Repository ID') %>: <%= @repo&.id %>
<%= _('Repository name') %>: <%= @repo&.name %>
<% end %>
<%= _('Task ID') %>: <%= @task.id %>
<%= _('Task state') %>: <%= @task.state %>
<%= _('Task result') %>: <%= @task.result %>
<%= _('Task details') %>: <%= foreman_tasks_task_url(@task) %>

Errors:
<% @task.execution_plan.errors.each do |error| %>
- <%= error.exception_class %>: <%= error.message %>
<% end %>
35 changes: 35 additions & 0 deletions app/views/katello/task_mailer/repo_sync_failure.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<p>
<%= _("%{label} failed.") % { :label => @task.action } %>
</p>

<div class="dashboard">
<table>
<tr>
<td><%= _('Repository') %></td>
<td><%= link_to @repo.label, "#{katello_url}products/#{@repo.product.id}/repositories/#{@repo.id}" %></td>
</tr>
<tr>
<td><%= _('Product') %></td>
<td><%= link_to @repo.product.label, "#{katello_url}products/#{@repo.product.id}" %></td>
</tr>
<tr>
<td><%= _('Task ID') %></td>
<td><%= link_to @task.id, foreman_tasks_task_url(@task.id) %></td>
</tr>
<tr>
<td><%= _('Task state') %></td>
<td><%= @task.state %></td>
</tr>
<tr>
<td><%= _('Task result') %></td>
<td><%= @task.result %></td>
</tr>
</table>

Errors:
<ul>
<% @task.execution_plan.errors.each do |error| %>
<li><%= error.exception_class %>: <%= error.message %></li>
<% end %>
</ul>
</div>
Loading
Loading