Dzahn has uploaded a new change for review. https://gerrit.wikimedia.org/r/94075
Change subject: bugzilla module - WIP ...................................................................... bugzilla module - WIP make bugzilla stuff a module Change-Id: I5381a2c57b0a3483f7ac3e79639b242054ad9e6f --- A modules/bugzilla/README.md A modules/bugzilla/files/bugzilla_report.php A modules/bugzilla/manifests/apache.pp A modules/bugzilla/manifests/auditlog.pp A modules/bugzilla/manifests/communitymetrics.pp A modules/bugzilla/manifests/crons.pp A modules/bugzilla/manifests/init.pp A modules/bugzilla/manifests/reporter.pp A modules/bugzilla/templates/apache/bugzilla.wikimedia.org.erb A modules/bugzilla/templates/scripts/bugzilla_audit_log.sh.erb A modules/bugzilla/templates/scripts/bugzilla_community_metrics.sh.erb 11 files changed, 893 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/operations/puppet refs/changes/75/94075/1 diff --git a/modules/bugzilla/README.md b/modules/bugzilla/README.md new file mode 100644 index 0000000..9f56af8 --- /dev/null +++ b/modules/bugzilla/README.md @@ -0,0 +1,23 @@ +Bugzilla module for Wikimedia +============================= + +https://bugzilla.wikimedia.org +http://wikitech.wikimedia.org/view/Bugzilla + +requirements: a basic Apache setup on the node +e.g. class {'webserver::php5': ssl => true; } + + + - the apache site config + - the SSL certs + - the /srv/org/wikimedia dir + - cronjobs and scripts: + - auditlog mail for bz admins, bash + - mail report for community metrics, bash + - whine / collectstats statistics, perl + - bugzilla reporter, php + +You still have to copy upstream bugzilla itself into +/srv/org/wikimedia/bugzilla/ and clone our modifications +from the wikimedia/bugzilla/modifcations repo. + diff --git a/modules/bugzilla/files/bugzilla_report.php b/modules/bugzilla/files/bugzilla_report.php new file mode 100755 index 0000000..b1cd72e --- /dev/null +++ b/modules/bugzilla/files/bugzilla_report.php @@ -0,0 +1,422 @@ +#!/usr/bin/php +<?php error_reporting(E_ALL); + +function getBugsPerProduct ($begin_date,$end_date) { + print "Created reports per product\n\n"; + return <<<END +SELECT + name, count(*) as total +FROM + bugs +JOIN + products + on + product_id = products.id +WHERE + creation_ts +BETWEEN + "$begin_date" + and + "$end_date" +GROUP BY + product_id +ORDER BY + total +DESC +LIMIT 5; +END; +} + +function getBugsPerComponent ($begin_date,$end_date) { + print "Created reports per component\n\n"; + return <<<END +SELECT + products.name, components.name, count(*) as total +FROM + bugs +JOIN + components + on + bugs.component_id = components.id +JOIN + products + on + bugs.product_id = products.id +WHERE + creation_ts +BETWEEN + "$begin_date" + and + "$end_date" +GROUP BY + component_id +ORDER BY + total +DESC +LIMIT + 5; + +END; +} + +function getBugsResolvedPerUser($begin_date,$end_date) { + print "Top 5 bug report closers\n\n"; + return <<<END +SELECT + login_name, count(*) as total +FROM + bugs_activity +JOIN + profiles + on + who = profiles.userid +WHERE + added = 'RESOLVED' + and + bug_when +BETWEEN + "$begin_date" + and + "$end_date" +GROUP BY + who +ORDER BY + total +DESC +LIMIT + 5; +END; +} +function getBugResolutions($begin_date, $end_date, $resolution) { + $resolution = mysql_real_escape_string($resolution); + $resolution = "'$resolution'"; + + return <<<END +SELECT + count(distinct bugs.bug_id) +FROM + bugs, bugs_activity +WHERE + bugs.resolution = $resolution +AND + bugs_activity.added = $resolution +AND + bugs_activity.bug_when +BETWEEN + "$begin_date" +AND + "$end_date" +AND + bugs.bug_id = bugs_activity.bug_id; +END; +} + +function getBugsChangingStatus($begin_date, $end_date, $state) { + $state = mysql_real_escape_string($state); + $state = "'$state'"; + + return <<<END +SELECT + count(*) +FROM + bugs, bugs_activity +WHERE + bugs.bug_status = $state +AND + bugs_activity.added = $state +AND + bugs_activity.bug_when +BETWEEN + "$begin_date" + and + "$end_date" +AND + bugs.bug_id = bugs_activity.bug_id; +END; +} + +function getTotalOpenReports() { + return <<<END +SELECT + count(*) +FROM + bugs +WHERE + bug_status = 'UNCONFIRMED' or + bug_status = 'ASSIGNED' or + bug_status = 'NEW' or + bug_status = 'PATCH_TO_REVIEW' or + bug_status = 'REOPENED'; +END; +} + +function getTotalOpenEnhancements() { + return <<<END +SELECT + count(*) +FROM + bugs +WHERE + (bug_status = 'UNCONFIRMED' or + bug_status = 'ASSIGNED' or + bug_status = 'NEW' or + bug_status = 'PATCH_TO_REVIEW' or + bug_status = 'REOPENED') +AND + bug_severity = 'enhancement'; +END; +} + +function getTotalOpenBugs() { + return <<<END +SELECT + count(*) +FROM + bugs +WHERE + (bug_status = 'UNCONFIRMED' or + bug_status = 'ASSIGNED' or + bug_status = 'NEW' or + bug_status = 'PATCH_TO_REVIEW' or + bug_status = 'REOPENED') +AND + bug_severity != 'enhancement'; +END; +} + +function getTotalOpenBugsNonLowestPriority() { + return <<<END +SELECT + count(*) +FROM + bugs +WHERE + (bug_status = 'UNCONFIRMED' or + bug_status = 'ASSIGNED' or + bug_status = 'NEW' or + bug_status = 'PATCH_TO_REVIEW' or + bug_status = 'REOPENED') +AND + bug_severity != 'enhancement' +AND + priority != 'lowest'; +END; +} + +function getBugsCreated($begin_date, $end_date) { + return <<<END +SELECT + count(bug_id) +FROM + bugs +WHERE + creation_ts +BETWEEN + "$begin_date" + and + "$end_date" +END; +} + +function getHighestPrioTickets() { + return <<<END +SELECT + products.name AS product, + components.name AS component, + bugs.bug_id AS bugID, + bugs.priority, + bugs.delta_ts, + profiles.login_name AS assignee, + bugs.short_desc as bugsummary +FROM + bugs +JOIN + profiles ON assigned_to = profiles.userid +JOIN + products ON bugs.product_id = products.id +JOIN + components ON bugs.component_id = components.id +LEFT JOIN + bug_group_map AS security_map ON bugs.bug_id = security_map.bug_id +WHERE + ( security_map.group_id != 15 OR security_map.group_id IS NULL ) +AND + ( bug_status != "RESOLVED" AND bug_status != "VERIFIED" AND bug_status != "CLOSED" ) +AND + ( priority = "Highest" OR priority = "Immediate" ) +ORDER BY + product, component, delta_ts +LIMIT + 200; +END; +} + +function formatOutput($result) { + while ($row = mysql_fetch_row($result)) { + if (is_array($row)) { + foreach ($row as $row_i) { + $row_i = str_replace ( '@', ' [AT] ', $row_i); //strip out any easy scrapes + print pack('A30',($row_i)); + } + } + else { + print "0\n"; + } + print "\n"; + } +} + +function reportFailure($text) { + print "Wikimedia Bugzilla report (FAILED), $text "; + die( "FAILED\n\n$text\n" ); +} + +function formatOutputHighestPrio($result) { + printf( "%-13.13s | %-13.13s | %5s | %-9.9s | %-10.10s | %-20.20s | %-37.37s\n", + "Product", "Component", "BugID", "Priority", "LastChange", "Assignee", "Summary" ); + printf ( "%-60s", "--------------------------------------------------------------" ); + print "\n"; + while ($row = mysql_fetch_row($result)) { + foreach ($row as $row_i) { + $row = str_replace ( '@', '[AT]', $row); + } + printf( "%-13.13s | %-13.13s | %5s | %-9.9s | %-10.10s | %-20.20s | %-37.37s", + $row[0], $row[1], $row[2], $row[3], $row[4], $row[5], $row[6] ); + print "\n\n"; + } +} + +# main + +$options = getopt('b:e:'); + +if ( !isset($options['e'])) + $end_date = strtotime('now'); +else + $end_date = strtotime($options['e']); +if ( !isset($options['b']) ) { + $begin_date = $end_date - 86400*7 ; +} +else + $begin_date = strtotime($options['b']); + +print "MediaWiki Bugzilla Report for " . date('F d, Y', $begin_date) . " - " . date('F d, Y', $end_date) . "\n\n"; + +/* TODO: mysql_connect is deprecated - switch to MySQLi or PDO */ +$ok = mysql_connect("db9.pmtpa.wmnet", "bugs", "<%= scope.lookupvar('passwords::bugzilla::bugzilla_db_pass') %>"); +if (!$ok) + reportFailure("DB connection failure"); + +$ok = mysql_select_db("bugzilla3"); +if (!$ok) + reportFailure("DB selection failure"); + +$reportsPerItem = array ('getBugsPerComponent', + 'getBugsPerProduct', + 'getBugsResolvedPerUser',); + +$statesToRun = array('UNCONFIRMED', + 'NEW', + 'ASSIGNED', + 'REOPENED', + 'PATCH_TO_REVIEW', + 'RESOLVED', + 'VERIFIED',); + +$resolutionsToRun = array('FIXED', 'DUPLICATE', + 'INVALID', 'WORKSFORME', + 'WONTFIX',); + +$totalStatistics = array ('getTotalOpenReports',); + +$totalStatisticsEnhancements = array ('getTotalOpenEnhancements',); + +$totalStatisticsBugs = array ('getTotalOpenBugs',); + +$totalStatisticsBugsNonLowestPriority = array ('getTotalOpenBugsNonLowestPriority',); + +$createdStatistics = array('getBugsCreated',); + +$urgentStatistics = array('getHighestPrioTickets',); + +print "Status changes this week\n\n"; +foreach ($statesToRun as $state) { + $sql = getBugsChangingStatus(date('Y-m-d',$begin_date),date('Y-m-d',$end_date), $state); + $result = mysql_query($sql); + if (!$result) + reportFailure("Query failure"); + print pack('A34A3',"Reports changed/set to $state",":"); + formatOutput($result); +} + +foreach ($totalStatistics as $report) { + $sql = getTotalOpenReports(); + $result = mysql_query($sql); + if (!$result) + reportFailure("Query failure"); + print "\nTotal reports still open : "; + formatOutput($result); +} + +foreach ($totalStatisticsBugs as $report) { + $sql = getTotalOpenBugs(); + $result = mysql_query($sql); + if (!$result) + reportFailure("Query failure"); + print "Total bugs still open : "; + formatOutput($result); +} + +foreach ($totalStatisticsBugsNonLowestPriority as $report) { + $sql = getTotalOpenBugsNonLowestPriority(); + $result = mysql_query($sql); + if (!$result) + reportFailure("Query failure"); + print "Total non-lowest prio. bugs still open: "; + formatOutput($result); +} + +foreach ($totalStatisticsEnhancements as $report) { + $sql = getTotalOpenEnhancements(); + $result = mysql_query($sql); + if (!$result) + reportFailure("Query failure"); + print "Total enhancements still open : "; + formatOutput($result); +} + +foreach ($createdStatistics as $report) { + $sql = getBugsCreated(date('Y-m-d', $begin_date),date('Y-m-d', $end_date)); + $result = mysql_query($sql); + if (!$result) + reportFailure( 'Query failure' ); + print "\nReports created this week: "; + formatOutput( $result ); +} + +print "\nResolutions for the week:\n\n"; +foreach ($resolutionsToRun as $resolution) { + $sql = getBugResolutions(date('Y-m-d',$begin_date),date('Y-m-d',$end_date), $resolution); + $result = mysql_query($sql); + if (!$result) + reportFailure("Query failure"); + print pack('A25A3',"Reports marked $resolution",":"); + formatOutput($result); +} +print "\nSpecific Product/Component Resolutions & User Metrics \n\n"; +foreach ($reportsPerItem as $report) { + $sql = $report(date('Y-m-d',$begin_date),date('Y-m-d',$end_date)); + $result = mysql_query($sql); + if (!$result) + reportFailure("Query failure"); + formatOutput($result); + print "\n"; +} +print "\nMost urgent open issues\n\n"; +foreach ($urgentStatistics as $report) { + $sql = getHighestPrioTickets(); + $result = mysql_query($sql); + if (!$result) + reportFailure("Query failure"); + formatOutputHighestPrio($result); +} diff --git a/modules/bugzilla/manifests/apache.pp b/modules/bugzilla/manifests/apache.pp new file mode 100644 index 0000000..281c136 --- /dev/null +++ b/modules/bugzilla/manifests/apache.pp @@ -0,0 +1,22 @@ +# setup Apache site and SSL certs for WMF Bugzilla +# requires: {'webserver::php5': ssl => true; } on node + +class bugzilla::apache ($svc_name, $attach_svc_name){ + + # separate cert and ServerName for attachments for security + install_certificate{ $svc_name: } + install_certificate{ $attach_svc_name: } + + # this includes them both, 80 and 443 + apache_site { $svc_name: name => $svc_name } + + file { + "/etc/apache2/sites-available/${svc_name}": + ensure => present, + content => template("bugzilla/apache/${svc_name}.erb", + mode => '0444', + owner => 'root', + group => 'www-data'; + } +} + diff --git a/modules/bugzilla/manifests/auditlog.pp b/modules/bugzilla/manifests/auditlog.pp new file mode 100644 index 0000000..b2f5592 --- /dev/null +++ b/modules/bugzilla/manifests/auditlog.pp @@ -0,0 +1,22 @@ +# setup script and cron that sends an +# audit log email to admins per RT-4802 + +class bugzilla::auditlog ($bz_path, $script_name, script_user, $rcpt_address, $sndr_address) { + + file { 'bugzilla_auditlog_file': + ensure => present, + path => "${bz_path}/${script_name}", + owner => 'root', + group => $bugzilla::auditlog::script_user, + mode => '0550', + content => template("bugzilla/scripts/${script_name}.erb", + } + + cron { 'bugzilla_auditlog_cron': + command => "cd ${bz_path} ; ./${script_name}", + user => $bugzilla::auditlog::script_user, + hour => '0', + minute => '0', + } +} + diff --git a/modules/bugzilla/manifests/communitymetrics.pp b/modules/bugzilla/manifests/communitymetrics.pp new file mode 100644 index 0000000..58bf8d3 --- /dev/null +++ b/modules/bugzilla/manifests/communitymetrics.pp @@ -0,0 +1,23 @@ +# setup script and cron to send metrics per +# RT-3962 - mail bz user stats to community metrics + +class bugzilla::communitymetrics ($bz_path, $script_user, $script_name, $rcpt_address, $sndr_address) { + + file { 'bugzilla_communitymetrics_file': + ensure => present, + path => "${bz_path}/${script_name}", + owner => 'root', + group => $script_user, + mode => '0550', + content => template("bugzilla/scripts/${script_name}.erb", + } + + cron { 'bugzilla_communitymetrics_cron': + command => "cd ${bz_path} ; ./${script_name}", + user => $script_user, + hour => '0', + minute => '0', + monthday => '1', + } +} + diff --git a/modules/bugzilla/manifests/crons.pp b/modules/bugzilla/manifests/crons.pp new file mode 100644 index 0000000..99a52d5 --- /dev/null +++ b/modules/bugzilla/manifests/crons.pp @@ -0,0 +1,32 @@ +# bugzilla cron jobs + +class bugzilla::crons ($bz_path, $whine = 'whine.pl', $collectstats = 'collectstats.pl'){ + + cron { 'bugzilla_whine': + command => "cd ${bz_path} ; ./${whine}", + user => 'root', + minute => '15', + } + + # 2 cron jobs to generate charts data + # See https://bugzilla.wikimedia.org/29203 + + # 1) get statistics for the day: + cron { 'bugzilla_collectstats': + command => "cd ${bz_path} ; ./${collectstats}", + user => 'root', + hour => '0', + minute => '5', + weekday => [ 1, 2, 3, 4, 5, 6 ] # Monday - Saturday + } + + # 2) on sunday, regenerates the whole statistics data + cron { 'bugzilla_collectstats_regenerate': + command => "cd ${bz_path} ; ./${collectstats} --regenerate", + user => root, + hour => 0, + minute => 5, + weekday => 0 # Sunday + } +} + diff --git a/modules/bugzilla/manifests/init.pp b/modules/bugzilla/manifests/init.pp new file mode 100644 index 0000000..fc54cff --- /dev/null +++ b/modules/bugzilla/manifests/init.pp @@ -0,0 +1,46 @@ +# setup Bugzilla instance for WMF +# also see README.md + +class bugzilla { + + # system role for motd + system_role { 'role::bugzilla': description => 'Bugzilla server' } + + # basic apache site and certs + class {'bugzilla::apache': + svc_name => 'bugzilla.wikimedia.org', + attach_svc_name => 'bug-attachment.wikimedia.org', + docroot => '/srv/org/wikimedia/bugzilla/', + } + + # whine / collectstats crons + class {'bugzilla::crons': + bz_path => '/srv/org/wikimedia/bugzilla', + whine => 'whine.pl', + collectstats => 'collectstats.pl', + } + + # community metrics mail + class {'bugzilla::communitymetrics': + bz_path => '/srv/org/wikimedia/bugzilla', + script_user => 'www-data', + script_name => 'bugzilla_community_metrics.sh', + rcpt_address => '[email protected]', + sndr_address => '[email protected]', + } + + # bugzilla reporter PHP script + class {'bugzilla::reporter': + bz_report_user => 'reporter', + } + + # audit log mail for admins + class {'bugzilla::auditlog': + bz_path => '/srv/org/wikimedia/bugzilla', + script_user => 'www-data', + script_name => 'bugzilla_audit_log.sh', + rcpt_address => '[email protected]', + sndr_address => '[email protected]', + } + +} diff --git a/modules/bugzilla/manifests/reporter.pp b/modules/bugzilla/manifests/reporter.pp new file mode 100644 index 0000000..92c0745 --- /dev/null +++ b/modules/bugzilla/manifests/reporter.pp @@ -0,0 +1,24 @@ +# setup user and script for bugzilla reporter +# parameters: user name that will run this (also used for group) + +class bugzilla::reporter ($bz_report_user = 'reporter') { + + systemuser { 'bzreporter': + name => $bz_report_user, + home => "/home/${bz_report_user}", + groups => [ $bz_report_user ] + } + + require passwords::bugzilla + + file { 'bugzilla_report': + ensure => present, + path => "/home/${bz_report_user}/bugzilla_report.php", + owner => $bz_report_user, + group => $bz_report_user, + mode => '0550', + source => 'puppet:///bugzilla/bugzilla_report.php', + } + +} + diff --git a/modules/bugzilla/templates/apache/bugzilla.wikimedia.org.erb b/modules/bugzilla/templates/apache/bugzilla.wikimedia.org.erb new file mode 100644 index 0000000..28e1675 --- /dev/null +++ b/modules/bugzilla/templates/apache/bugzilla.wikimedia.org.erb @@ -0,0 +1,162 @@ +# Apache config for bugzilla.wikimedia.org +# ! THIS FILE IS MANAGED BY PUPPET ! +# ./modules/bugzilla/templates/apache/bugzilla.wikimedia.org.erb + +NameVirtualHost *:80 +NameVirtualHost *:443 + +<VirtualHost *:80> + ServerAdmin [email protected] + ServerName <%= scope.lookupvar('bugzilla::apache::svc_name') %> + Redirect permanent / https://<%= scope.lookupvar('bugzilla::apache::svc_name') %>/ + RewriteEngine On + RewriteCond %{HTTPS} off + RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} +</VirtualHost> + +<VirtualHost *:80> + ServerAdmin [email protected] + ServerName bugs.wikimedia.org + Redirect permanent / https://<%= scope.lookupvar('bugzilla::apache::svc_name') %>/ + RewriteEngine On + RewriteCond %{HTTPS} off + RewriteRule (.*) https://<%= scope.lookupvar('bugzilla::apache::svc_name') %>%{REQUEST_URI} +</VirtualHost> + +<VirtualHost *:80> + ServerAdmin [email protected] + ServerName bugs.wikipedia.org + Redirect permanent / https://<%= scope.lookupvar('bugzilla::apache::svc_name') %>/ + RewriteEngine On + RewriteCond %{HTTPS} off + RewriteRule (.*) https://<%= scope.lookupvar('bugzilla::apache::svc_name') %>%{REQUEST_URI} +</VirtualHost> + +<VirtualHost *:80> + ServerAdmin [email protected] + ServerName bugzilla.wikipedia.org + Redirect permanent / https://<%= scope.lookupvar('bugzilla::apache::svc_name') %>/ + RewriteEngine On + RewriteCond %{HTTPS} off + RewriteRule (.*) https://<%= scope.lookupvar('bugzilla::apache::svc_name') %>%{REQUEST_URI} +</VirtualHost> + +<VirtualHost *:443> + ServerAdmin [email protected] + ServerName bugs.wikimedia.org + Redirect permanent / https://<%= scope.lookupvar('bugzilla::apache::svc_name') %>/ + SSLEngine On + SSLProtocol -ALL +SSLv3 +TLSv1 + SSLCipherSuite AES128-GCM-SHA256:RC4-SHA:RC4-MD5:DES-CBC3-SHA:AES128-SHA:AES256-SHA + SSLHonorCipherOrder on + SSLCertificateFile /etc/ssl/certs/<%= scope.lookupvar('bugzilla::apache::svc_name') %>.pem + SSLCertificateKeyFile /etc/ssl/private/<%= scope.lookupvar('bugzilla::apache::svc_name') %>.key + SSLCACertificatePath /etc/ssl/certs/ + + RewriteEngine On + RewriteRule (.*) https://<%= scope.lookupvar('bugzilla::apache::svc_name') %>%{REQUEST_URI} +</VirtualHost> + +<VirtualHost *:443> + ServerAdmin [email protected] + ServerName <%= scope.lookupvar('bugzilla::apache::svc_name') %> + DocumentRoot <%= scope.lookupvar('bugzilla::apache::docroot') %> + SSLEngine On + SSLProtocol -ALL +SSLv3 +TLSv1 + SSLCipherSuite AES128-GCM-SHA256:RC4-SHA:RC4-MD5:DES-CBC3-SHA:AES128-SHA:AES256-SHA + SSLHonorCipherOrder on + SSLCertificateFile /etc/ssl/certs/<%= scope.lookupvar('bugzilla::apache::svc_name') %>.pem + SSLCertificateKeyFile /etc/ssl/private/<%= scope.lookupvar('bugzilla::apache::svc_name') %>.key + SSLCACertificatePath /etc/ssl/certs/ + + <Directory /> + Options FollowSymLinks + AllowOverride None + </Directory> + + <Directory <%= scope.lookupvar('bugzilla::apache::docroot') %>> + BrowserMatchNoCase spider nobots + BrowserMatchNoCase bot nobots + Options Indexes FollowSymLinks MultiViews + AllowOverride None + Order allow,deny + Deny from env=nobots + allow from all + # This directive allows us to have apache2's default start page + # in /apache2-default/, but still have / go to the right place + #RedirectMatch ^/$ /apache2-default/ + + # For bugzilla + AddHandler cgi-script .cgi + Options +ExecCGI +FollowSymLinks + AllowOverride Limit FileInfo Indexes + DirectoryIndex index.cgi index.html + </Directory> + + ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ + + <Directory "/usr/lib/cgi-bin"> + AllowOverride None + Options ExecCGI -MultiViews +SymLinksIfOwnerMatch + Order allow,deny + Allow from all + </Directory> + +ErrorLog /var/log/apache2/error.log + +# Possible values include: debug, info, notice, warn, error, crit, +# alert, emerg. +LogLevel warn + +CustomLog /var/log/apache2/access.log combined +ServerSignature On + +RewriteEngine On +RewriteRule ^/(\d+)$ https://<%= scope.lookupvar('bugzilla::apache::svc_name') %>/show_bug.cgi?id=$1 [R] + +RewriteCond %{QUERY_STRING} ^(id=bug-writing.html)$ +RewriteRule /page\.cgi$ https://www.mediawiki.org/wiki/How_to_report_a_bug? [R=303] + +RewriteCond %{QUERY_STRING} ^(id=fields.html)$ +RewriteRule /page\.cgi$ https://www.mediawiki.org/wiki/Bugzilla/Fields? [R=303] + +</VirtualHost> + +<VirtualHost *:80> + ServerName <%= scope.lookupvar('bugzilla::apache::attach_svc_name') %> + DocumentRoot <%= scope.lookupvar('bugzilla::apache::docroot') %> + + <Directory /> + Order Allow,Deny + Deny from all + </Directory> + + ScriptAlias /attachment.cgi <%= scope.lookupvar('bugzilla::apache::docroot') %>attachment.cgi + <Location /attachment.cgi> + Order Allow,Deny + Allow from all + </Location> +</VirtualHost> + +<VirtualHost *:443> + ServerName <%= scope.lookupvar('bugzilla::apache::attach_svc_name') %> + DocumentRoot <%= scope.lookupvar('bugzilla::apache::docroot') %> + SSLEngine On + SSLProtocol -ALL +SSLv3 +TLSv1 + SSLCipherSuite AES128-GCM-SHA256:RC4-SHA:RC4-MD5:DES-CBC3-SHA:AES128-SHA:AES256-SHA + SSLHonorCipherOrder on + SSLCertificateFile /etc/ssl/certs/<%= scope.lookupvar('bugzilla::apache::attach_svc_name') %>.pem + SSLCertificateKeyFile /etc/ssl/private/<%= scope.lookupvar('bugzilla::apache::attach_svc_name') %>.key + SSLCACertificatePath /etc/ssl/certs/ + + <Directory /> + Order Allow,Deny + Deny from all + </Directory> + + ScriptAlias /attachment.cgi <%= scope.lookupvar('bugzilla::apache::docroot') %>attachment.cgi + <Location /attachment.cgi> + Order Allow,Deny + Allow from all + </Location> +</VirtualHost> diff --git a/modules/bugzilla/templates/scripts/bugzilla_audit_log.sh.erb b/modules/bugzilla/templates/scripts/bugzilla_audit_log.sh.erb new file mode 100755 index 0000000..e31d90d --- /dev/null +++ b/modules/bugzilla/templates/scripts/bugzilla_audit_log.sh.erb @@ -0,0 +1,48 @@ +#!/bin/bash +# send the Bugzilla audit log to BZ admin(s) +# per RT-4802 - dzahn 20130328 +# ! this file is managed by puppet ! +# ./modules/bugzilla/templates/scripts/<%= scope.lookupvar('bugzilla::auditlog::script_name') %>.erb + +declare rcpt_address='<%= scope.lookupvar('bugzilla::auditlog::rcpt_address') %>' +declare sndr_address='<%= scope.lookupvar('bugzilla::auditlog::sndr_address') %>' + +# reads db user/pass/host from bugzilla config +declare bugzilla_path='<%= scope.lookupvar('bugzilla::auditlog::bz_path') %>' +declare -a config_var=(host name user pass) +declare -A my_var +declare script_user='<%= scope.lookupvar('bugzilla::auditlog::script_user') %>' + +define(){ IFS='\n' read -r -d '' ${1} || true; } + +for mv in "${config_var[@]}"; do + my_var[$mv]=$(grep db_${mv} ${bugzilla_path}/localconfig | cut -d\' -f2 | sed 's/;/\\\;/g') +done + +# fix if there is a ; in the pass itself +mypass=$(echo ${my_var[pass]} | sed 's/\\//g') + +# fetch audit log from mysql db +my_result=$(/usr/bin/mysql -h ${my_var[host]} -u${my_var[user]} ${my_var[name]} -p${mypass}<< END + +select * from audit_log order by at_time desc; + +END +) + +# send it out per mail +cat <<EOF | /usr/bin/mail -s "bugzilla audit log" ${rcpt_address} -- -f ${sndr_address} + +Hi Bugzilla admins, + +this is your automatic Bugzilla audit log mail: + +$my_result + +Yours sincerely, + +Bugs Zilla + +(via $(basename $0) on $(hostname) at $(date)) +EOF + diff --git a/modules/bugzilla/templates/scripts/bugzilla_community_metrics.sh.erb b/modules/bugzilla/templates/scripts/bugzilla_community_metrics.sh.erb new file mode 100755 index 0000000..89bbeab --- /dev/null +++ b/modules/bugzilla/templates/scripts/bugzilla_community_metrics.sh.erb @@ -0,0 +1,69 @@ +#!/bin/bash +# send the number of active users on Bugzilla +# in the last month to "community metrics" team +# per RT-3962 - dzahn 20121219 +# ! this file is managed by puppet ! + +declare rcpt_address='<%= scope.lookupvar('bugzilla::communitymetrics::rcpt_address') %>' +declare sndr_address='<%= scope.lookupvar('bugzilla::communitymetrics::sndr_address') %>' + +# reads db user/pass/host from bugzilla config +declare bugzilla_path='<%= scope.lookupvar('bugzilla::communitymetrics::bz_path') %>' +declare -a config_var=(host name user pass) +declare -A my_var +declare script_user='<%= scope.lookupvar('bugzilla::communitymetrics::script_user') %>' + +define(){ IFS='\n' read -r -d '' ${1} || true; } + +for mv in "${config_var[@]}"; do + my_var[$mv]=$(grep db_${mv} ${bugzilla_path}/localconfig | cut -d\' -f2 | sed 's/;/\\\;/g') +done + +# fix if there is a ; in the pass itself +mypass=$(echo ${my_var[pass]} | sed 's/\\//g') + +my_result=$(MYSQL_PWD=${mypass} /usr/bin/mysql -h ${my_var[host]} -u${my_var[user]} ${my_var[name]} << END + +select + count(distinct userid) +from +( + select + ba.who as userid, + ba.bug_when as action_date + from bugs_activity ba + where + date_format(ba.bug_when,'%Y%m')=date_format(NOW() - INTERVAL 1 MONTH,'%Y%m') and + ba.fieldid in (2,4,5,6,7,8,9,10,11,12,13,14,15,16,18,19,30,35,36,37,38,40,41,42,47,55,56,57,58) + group by action_date,userid + union all + select + b.reporter, + b.creation_ts + from bugs b + where + date_format(b.creation_ts,'%Y%m')=date_format(NOW() - INTERVAL 1 MONTH,'%Y%m') +) as filtered_actions; + +END +) + +activeusers=$(echo $my_result | cut -d " " -f3) +lastmonth=$(date --date="last month" +%Y-%m) + +# the actual email +cat <<EOF | /usr/bin/mail -s "bugzilla stats - ${lastmonth}" ${rcpt_address} -- -f ${sndr_address} + +Hi Community Metrics team, + +this is your automatic monthly Bugzilla statistics mail. + +The number of active users in Bugzilla in the last month (${lastmonth}) was: ${activeusers} + +Yours sincerely, + +Bugs Zilla + +(via $(basename $0) on $(hostname) at $(date)) +EOF + -- To view, visit https://gerrit.wikimedia.org/r/94075 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5381a2c57b0a3483f7ac3e79639b242054ad9e6f Gerrit-PatchSet: 1 Gerrit-Project: operations/puppet Gerrit-Branch: production Gerrit-Owner: Dzahn <[email protected]> _______________________________________________ MediaWiki-commits mailing list [email protected] https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
