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
fixes #7666, #7667, #7668 - errata mail notifications #4780
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# | ||
# Copyright 2014 Red Hat, Inc. | ||
# | ||
# This software is licensed to you under the GNU General Public | ||
# License as published by the Free Software Foundation; either version | ||
# 2 of the License (GPLv2) or (at your option) any later version. | ||
# There is NO WARRANTY for this software, express or implied, | ||
# including the implied warranties of MERCHANTABILITY, | ||
# NON-INFRINGEMENT, or FITNESS FOR A PARTICULAR PURPOSE. You should | ||
# have received a copy of GPLv2 along with this software; if not, see | ||
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. | ||
|
||
module Katello | ||
module ErrataMailerHelper | ||
def content_host_errata_path(content_host) | ||
uuid = Katello::System.find(content_host).uuid | ||
"#{Setting[:foreman_url]}/content_hosts/#{uuid}/errata" | ||
end | ||
|
||
def content_view_environment_errata_path(content_view, environment) | ||
version = Katello::ContentViewEnvironment.find_by_content_view_id_and_environment_id(content_view.id, environment.id).content_view_version_id | ||
"#{Setting[:foreman_url]}/content_views/#{content_view.id}/versions/#{version}/errata" | ||
end | ||
|
||
def content_view_path(content_view) | ||
"#{Setting[:foreman_url]}/content_views/#{content_view.id}/versions" | ||
end | ||
|
||
def erratum_path(erratum) | ||
"#{Setting[:foreman_url]}/errata/#{erratum.uuid}/info" | ||
end | ||
|
||
def errata_count(host, errata_type) | ||
available = host.available_errata.send(errata_type.to_sym).count | ||
applicable = host.applicable_errata.send(errata_type.to_sym).count - available | ||
"#{available} (#{applicable})" | ||
end | ||
|
||
def format_summary(summary) | ||
summary.blank? ? summary : summary.gsub(/\n\n/, '<p>').gsub(/\n/, ' ').html_safe | ||
end | ||
|
||
def host_count(hosts, errata_type) | ||
hosts.to_a.count { |host| host.available_errata.send(errata_type.to_sym).any? } | ||
end | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nitpick empty line at the bottom since you have one at the top. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👎 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❓ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not a fan of putting a blank line before an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't realize that was a thing... I think I always put a space at the top, after the namespace(s), but never at the bottom. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The two styles I see most often are no blank lines at the top/bottom (rails, sinatra, etc) or a blank line at the top but not at the bottom. Rails use to include a mixture of both but it looks like they've since cleaned up their code by going with the former. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well looking around the Katello code, it's not consistent at all - so if we're going to hold people to a specific style here, we should enable a cop.... |
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# | ||
# Copyright 2014 Red Hat, Inc. | ||
# | ||
# This software is licensed to you under the GNU General Public | ||
# License as published by the Free Software Foundation; either version | ||
# 2 of the License (GPLv2) or (at your option) any later version. | ||
# There is NO WARRANTY for this software, express or implied, | ||
# including the implied warranties of MERCHANTABILITY, | ||
# NON-INFRINGEMENT, or FITNESS FOR A PARTICULAR PURPOSE. You should | ||
# have received a copy of GPLv2 along with this software; if not, see | ||
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. | ||
|
||
module Actions | ||
module Katello | ||
module ContentView | ||
class ErrataMail < Actions::EntryAction | ||
def plan(content_view, environment) | ||
plan_self(:content_view => content_view.id, :environment => environment.id) | ||
end | ||
|
||
def run | ||
MailNotification[:katello_promote_errata].deliver(:content_view => input[:content_view], | ||
:environment => input[:environment]) | ||
end | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# | ||
# Copyright 2014 Red Hat, Inc. | ||
# | ||
# This software is licensed to you under the GNU General Public | ||
# License as published by the Free Software Foundation; either version | ||
# 2 of the License (GPLv2) or (at your option) any later version. | ||
# There is NO WARRANTY for this software, express or implied, | ||
# including the implied warranties of MERCHANTABILITY, | ||
# NON-INFRINGEMENT, or FITNESS FOR A PARTICULAR PURPOSE. You should | ||
# have received a copy of GPLv2 along with this software; if not, see | ||
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. | ||
|
||
module Actions | ||
module Katello | ||
module Repository | ||
class ErrataMail < Actions::EntryAction | ||
def plan(repo) | ||
last_updated = repo.repository_errata.order('updated_at ASC').last.try(:updated_at) || Time.now | ||
plan_self(:repo => repo.id, :last_updated => last_updated.to_s) | ||
end | ||
|
||
def run | ||
::User.current = ::User.anonymous_admin | ||
MailNotification[:katello_sync_errata].deliver(:repo => input[:repo], :last_updated => input[:last_updated]) | ||
end | ||
|
||
def finalize | ||
::User.current = nil | ||
end | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# | ||
# Copyright 2014 Red Hat, Inc. | ||
# | ||
# This software is licensed to you under the GNU General Public | ||
# License as published by the Free Software Foundation; either version | ||
# 2 of the License (GPLv2) or (at your option) any later version. | ||
# There is NO WARRANTY for this software, express or implied, | ||
# including the implied warranties of MERCHANTABILITY, | ||
# NON-INFRINGEMENT, or FITNESS FOR A PARTICULAR PURPOSE. You should | ||
# have received a copy of GPLv2 along with this software; if not, see | ||
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. | ||
|
||
module Katello | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tests? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missed this earlier, but we do tend to put copyright notices at the top of all of our files. |
||
class ErrataMailer < ApplicationMailer | ||
helper :'katello/errata_mailer' | ||
|
||
def host_errata(options) | ||
return unless (user = User.find(options[:user])) | ||
|
||
@content_hosts = Katello::System.authorized_as(user, :view_content_hosts).reject { |host| host.applicable_errata.empty? } | ||
|
||
set_locale_for user | ||
|
||
mail(:to => user.mail, | ||
:subject => _("Katello Host Advisory"), | ||
:date => Time.zone.now) | ||
end | ||
|
||
def sync_errata(options) | ||
return unless (@repo = Katello::Repository.find(options[:repo])) && (last_updated = options[:last_updated].to_datetime) | ||
|
||
recipients = User.all.select do |user| | ||
user.receives?(:katello_sync_errata) && user.can?(:view_products, @repo.product) | ||
end | ||
|
||
fail Errors::NotFound, N_("No recipients found for %s sync report") % @repo.name unless recipients.any? | ||
|
||
all_errata = Katello::Erratum.where(:id => @repo.repository_errata.where('katello_repository_errata.updated_at > ?', last_updated).pluck(:erratum_id)) | ||
|
||
@errata_counts = errata_counts(all_errata) | ||
@errata = all_errata.take(100).group_by(&:errata_type) | ||
|
||
group_mail(recipients, :subject => (_("Katello Sync Summary for %s") % @repo.name)) | ||
end | ||
|
||
def promote_errata(options) | ||
return unless (content_view = Katello::ContentView.find(options[:content_view])) && | ||
(environment = Katello::KTEnvironment.find(options[:environment])) | ||
|
||
recipients = User.all.select do |user| | ||
user.receives?(:katello_promote_errata) && user.can?(:view_content_views, content_view) | ||
end | ||
|
||
fail Errors::NotFound, N_("No recipients found for %s promotion summary") % content_view.name unless recipients.any? | ||
|
||
@content_view = content_view | ||
@environment = environment | ||
|
||
@content_hosts = Katello::System.where(:environment_id => environment.id, :content_view_id => content_view.id) | ||
|
||
group_mail(recipients, :subject => (_("Katello Promotion Summary for %{content_view}") % {:content_view => content_view.name})) | ||
end | ||
|
||
private | ||
|
||
def errata_counts(errata) | ||
counts = {:total => errata.count} | ||
counts.merge(Hash[[:security, :bugfix, :enhancement].collect do |errata_type| | ||
[errata_type, errata.send(errata_type).count] | ||
end]) | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<table class="errata" style="border: 1px solid #cccccc; padding: 5px; background-color: #ffffff; border-collapse: collapse; text-align: justify; width: 100%;" bgcolor="#ffffff"> | ||
<tr> | ||
<td width="18%" style="text-align: left; border-collapse: collapse; background-image: linear-gradient(#f5f5f5, #e8e8e8); padding: 4px; border: 1px solid #cccccc;" align="left"> | ||
<b><%= _("Errata ID") %></b> | ||
</td> | ||
|
||
<td width="32%" style="border-collapse: collapse; text-align: left; background-color: #FFFFFF; padding: 4px; border: 1px solid #cccccc;" align="center" bgcolor="#FFFFFF"> | ||
<%= link_to erratum.errata_id, erratum_path(erratum) %> | ||
</td> | ||
|
||
<td width="18%" style="text-align: left; border-collapse: collapse; background-image: linear-gradient(#f5f5f5, #e8e8e8); padding: 4px; border: 1px solid #cccccc;" align="left"> | ||
<b><%= _("Severity") %></b> | ||
</td> | ||
|
||
<td width="32%" style="border-collapse: collapse; text-align: left; background-color: #FFFFFF; padding: 4px; border: 1px solid #cccccc;" align="center" bgcolor="#FFFFFF"> | ||
<%= erratum.severity.blank? ? "-" : erratum.severity %> | ||
</td> | ||
</tr> | ||
|
||
<tr> | ||
<td colspan="1" style="text-align: left; border-collapse: collapse; background-image: linear-gradient(#f5f5f5, #e8e8e8); padding: 4px; border: 1px solid #cccccc;" valign="top" align="left"> | ||
<b><%= _("Summary") %></b> | ||
</td> | ||
|
||
<td colspan="3" style="border-collapse: collapse; text-align: left; background-color: #FFFFFF; padding: 4px; border: 1px solid #cccccc;" align="center" bgcolor="#FFFFFF"> | ||
<%= format_summary(erratum.summary) %> | ||
</td> | ||
</tr> | ||
</table> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<h4><%= title %></h4> | ||
|
||
<div align="center" style="margin: 10px 0px;"> | ||
<table class="summary" style="border: 1px solid; padding: 5px; background-color: #ffffff; border-collapse: collapse; text-align: center; width: 100%;" bgcolor="#ffffff"> | ||
<tr> | ||
<td style="width: 33%; padding: 5px; border: 1px solid #ccc;"> | ||
<b class="counter" style="color: #6bb5df;"><%= host_count(content_hosts, :security) %></b> | ||
|
||
<p class="summary-title" style="font-size: 80%; font-weight: bold; margin: 5px; padding: 0px;"><%= _("Security").upcase %></p> | ||
</td> | ||
<td style="width: 33%; padding: 5px; border: 1px solid #ccc;"> | ||
<b class="counter" style="color: #6bb5df;"><%= host_count(content_hosts, :bugfix) %></b> | ||
|
||
<p class="summary-title" style="font-size: 80%; font-weight: bold; margin: 5px; padding: 0px;"><%= _("Bugfix").upcase %></p> | ||
</td> | ||
<td style="width: 33%; padding: 5px; border: 1px solid #ccc;"> | ||
<b class="counter" style="color: #6bb5df;"><%= host_count(content_hosts, :enhancement) %></b> | ||
|
||
<p class="summary-title" style="font-size: 80%; font-weight: bold; margin: 5px; padding: 0px;"><%= _("Enhancement").upcase %></p> | ||
</td> | ||
</tr> | ||
</table> | ||
</div> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||
<html xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: #3f3f3f; background-color: #f1f1f1;"> | ||
<body> | ||
<style type="text/css"> | ||
a, a:visited { | ||
color: #6bb5df !important; | ||
} | ||
|
||
a:hover { | ||
color: #CCCCCC !important; | ||
} | ||
</style> | ||
<div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: #3f3f3f; background-color: #f1f1f1;"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder about all of these inline styles and how they will affect the ability to easily change the styling of these emails in the future. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We're a bit stuck there, it's the only option for some very popular web mail providers (e.g. Gmail). We're lucky they're supporting CSS at all these days. I did break some things out as partials, but even then, the styles are in-line on those tables too. It could all be abstracted away to helpers or something, but the nature of e-mail notifications is that I don't expect the number of e-mail types to ever become more than a handful. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True, I'm fine with using helpers in the future if we ever need to change these or add more. Don't want to create a premature abstraction. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could create variables with the common css attributes and use those variables when styling. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah that looks nicer. At this point though, I want to get this in for the Katello 2.1 RC so will have to do it as a separate PR later. |
||
<table border="0" cellpadding="0" cellspacing="0" height="100%" width="100%" id="bodyTable" bgcolor="#f1f1f1"> | ||
<tr> | ||
<td align="center" valign="top"> | ||
<table border="0" id="emailContainer" style="max-width: 600px;"> | ||
<tr> | ||
<td align="center" valign="top"> | ||
<div align="left"> | ||
<h2 style="font-weight: normal;"><b>KATELLO</b> <%= _("Host Advisory").upcase %></h2> | ||
</div> | ||
<table border="0" width="100%" id="emailHeader" style="background-color: #e1e2e3;" bgcolor="#e1e2e3"> | ||
<tr> | ||
<td align="left" valign="top" style="padding: 0px 20px;"> | ||
<%= render :partial => 'host_dashboard', :locals => {:content_hosts => @content_hosts, :title => _("Hosts with Available Errata")} %> | ||
</td> | ||
</tr> | ||
</table> | ||
</td> | ||
</tr> | ||
<tr> | ||
<td align="center" valign="top"> | ||
<table border="0" width="100%" id="emailBody" style="background-color: #fff; margin-top: 10px; padding: 0px 0px 15px;" bgcolor="#fff"> | ||
<tr> | ||
<td align="center" valign="top" style="padding: 0px 20px 5px;"> | ||
|
||
<% @content_hosts.group_by(&:organization).each do |org, hosts| %> | ||
<h3 style="text-align: left; margin: 10px 0px 5px;" align="left"><%= org %></h3> | ||
|
||
<p style="text-align: left; font-size: 75%; margin: 5px;" align="left"> | ||
<%= _("The following hosts have errata that apply to them: ") %> | ||
</p> | ||
<table class="errata" style="border: 1px solid #cccccc; padding: 5px; background-color: #ffffff; border-collapse: collapse; text-align: justify; width: 100%;" bgcolor="#ffffff"> | ||
<tr> | ||
<th style="text-align: left; border-collapse: collapse; background-image: linear-gradient(#f5f5f5, #e8e8e8); padding: 4px; border: 1px solid #cccccc;" align="left"><%= _("Host") %></th> | ||
<th style="border-collapse: collapse; background-image: linear-gradient(#f5f5f5, #e8e8e8); text-align: center; padding: 4px; border: 1px solid #cccccc;" align="center"><%= _("Security") %></th> | ||
<th style="border-collapse: collapse; background-image: linear-gradient(#f5f5f5, #e8e8e8); text-align: center; padding: 4px; border: 1px solid #cccccc;" align="center"><%= _("Bugfix") %></th> | ||
<th style="border-collapse: collapse; background-image: linear-gradient(#f5f5f5, #e8e8e8); text-align: center; padding: 4px; border: 1px solid #cccccc;" align="center"><%= _("Enhancement") %></th> | ||
</tr> | ||
<% hosts.each do |host| %> | ||
<tr> | ||
<td style="text-align: left; border-collapse: collapse; background-color: #FFFFFF; padding: 4px; border: 1px solid #cccccc;" width="48%" align="left" bgcolor="#FFFFFF"><%= link_to host, content_host_errata_path(host) %></td> | ||
<td width="18%" style="border-collapse: collapse; text-align: center; background-color: #FFFFFF; padding: 4px; border: 1px solid #cccccc;" align="center" bgcolor="#FFFFFF"><%= errata_count(host, :security) %></td> | ||
<td width="18%" style="border-collapse: collapse; text-align: center; background-color: #FFFFFF; padding: 4px; border: 1px solid #cccccc;" align="center" bgcolor="#FFFFFF"><%= errata_count(host, :bugfix) %></td> | ||
<td width="18%" style="border-collapse: collapse; text-align: center; background-color: #FFFFFF; padding: 4px; border: 1px solid #cccccc;" align="center" bgcolor="#FFFFFF"><%= errata_count(host, :enhancement) %></td> | ||
</tr> | ||
<% end -%> | ||
</table> | ||
<% end -%> | ||
</td> | ||
</tr> | ||
</table> | ||
</td> | ||
</tr> | ||
<tr> | ||
<td align="center" valign="top"> | ||
<table border="0" cellpadding="20" cellspacing="0" width="100%" id="emailFooter" style="background-color: #e1e2e3;" bgcolor="#e1e2e3"> | ||
<tr> | ||
<td align="left" valign="top" style="font-size: 82%; padding: 0px 20px;"> | ||
<p><%= _("Note: The number in parentheses reflects all applicable errata from the Library environment that are unavailable to the host. You will need to promote this content to the relevant content view in order to make it available.") %></p> | ||
</td> | ||
</tr> | ||
</table> | ||
</td> | ||
</tr> | ||
</table> | ||
</td> | ||
</tr> | ||
</table> | ||
</div> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<%= _("The following hosts have errata that apply to them: ") %> | ||
|
||
<% @content_hosts.group_by(&:organization).each do |org, hosts| %> | ||
|
||
<%= _("Organization") %>: <%= org %> | ||
|
||
<% hosts.each do |host| %> | ||
<%= host %>: | ||
<%= _("Security") %>: <%= errata_count(host, :security) %> | ||
<%= _("Bugfix") %>: <%= errata_count(host, :bugfix) %> | ||
<%= _("Enhancement") %>: <%= errata_count(host, :enhancement) %> | ||
<% end -%> | ||
<% end -%> | ||
|
||
<%= _("Note: The number in parentheses reflects all applicable errata from the Library environment that are unavailable to the host. You will need to promote this content to the relevant content view in order to make it available.") %> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why reduce the applicable count by the available count?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It gives the user a better idea of what isn't available. Currently, if all errata are in the current environment, then it would look like this in the e-mail
I think it's more useful to know that I'm current and there's no action to take.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I must still be missing something. If I have 5 available errata, and 2 of those are applicable, won't I get:
2 - 5 = -3 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You would not have a situation like that: available is a subset of applicable.
The report shows available as the first number, and the second as applicable. So as an administrator, I get an e-mail that tells me my host has 3 available errata -- that I can apply yum update right now and get.
The second number is a heads up there's new content in the Library coming up the pipeline to my host, and I may want to check those out -- especially if it's security. It's not useful if that number includes available too.