Skip to content

Commit

Permalink
Prep for v3 release
Browse files Browse the repository at this point in the history
* Add new setup and config class
* Define resource ordering better
* Properly bootstrap a fresh install
* Remove `team` param: use org name for team name
* Update metadata: bump version, list dependencies
* Add stupid spec test for later refinement
* Manage `sentry beat` service
* Restart services on version change
  • Loading branch information
Scott Merrill committed Jun 2, 2016
1 parent c60f3b7 commit 2fa148f
Show file tree
Hide file tree
Showing 13 changed files with 226 additions and 93 deletions.
9 changes: 9 additions & 0 deletions .fixtures.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
fixtures:
symlinks:
sentry: "#{source_dir}"
forge_modules:
apache: "puppetlabs/apache"
concat: "puppetlabs/concat"
logrotate: "yo61/logrotate"
python: "stankevich/python"
stdlib: "puppetlabs/stdlib"
7 changes: 7 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
source "https://gems.covermymeds.com"
gem "rspec"
gem "json_pure"
gem "hiera", ">= 2.0", "< 4.0"
gem "puppet", ">= 4"
gem "rspec-puppet", ">= 2.4"
gem "puppetlabs_spec_helper"
88 changes: 33 additions & 55 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ To install the latest version of Sentry with all default values:
```
class { 'sentry': }
```
The default configuration assumes all of the dependencies are running on localhost, which is likely only useful for a development scenario.
The default configuration assumes all of the dependencies are running on localhost, which is likely only useful for a development scenario. This will also use the Red Hat default `snakeoil` SSL certificate for HTTPS.

A more realistic use case following the roles and profiles pattern:
* **role/manifests/sentry.pp**
Expand Down Expand Up @@ -55,36 +55,37 @@ class profile::sentry {
---
classes:
- role::sentry
sentry::admin_email: '[email protected]'
sentry::admin_password: <redacted>
sentry::db_host: 'postgresql.example.com'
sentry::db_name: 'sentry'
sentry::db_user: 'sentry'
sentry::db_password: 'sentry_db_password'
sentry::sentry_vhost: 'sentry.example.com'
sentry::extensions:
sentry-github: https://github.com/getsentry/sentry-github/archive/master.zip
sentry-hipchat: https://github.com/getsentry/sentry-hipchat-ac/archive/master.zip
sentry::ldap_auth_version: '2.0'
sentry::ldap_domain: 'example'
sentry::ldap_base_ou: 'dc=example,dc=com'
sentry::ldap_group_base: 'OU=Sentry Users,OU=Admin Users,DC=example,DC=com'
sentry::ldap_group_dn: 'CN=Sentry Group,OU=Admin Groups,DC=example,DC=com'
sentry::ldap_host: 'ldap.example.com'
sentry::ldap_user: '[email protected]'
sentry::ldap_password: 'ldap_bind_password'
sentry::ldap_domain: 'example'
sentry::ldap_base_ou: 'dc=example,dc=com'
sentry::sentry_group_base: 'OU=Sentry Users,OU=Admin Users,DC=example,DC=com'
sentry::sentry_group_dn: 'CN=Sentry Group,OU=Admin Groups,DC=example,DC=com'
sentry::organization: 'Awesome Organization'
sentry::path: '/var/lib/sentry'
sentry::redis_host: 'redis.example.com'
sentry::smtp_host: 'smtp.example.com'
sentry::admin_email: '[email protected]'
sentry::admin_password: <redacted>
sentry::organization: 'Your Organization Name'
sentry::team: 'Default Team Name'
sentry::secret_key: <some secret key>
sentry::path: '/var/lib/sentry'
sentry::version: '8.0.0'
sentry::extensions:
sentry-github: https://github.com/getsentry/sentry-github/archive/master.zip
sentry-hipchat: https://github.com/getsentry/sentry-hipchat-ac/archive/master.zip
sentry::smtp_host: 'smtp.example.com'
sentry::ssl_cert: '/etc/ssl/sentry.example.com.pem'
sentry::ssl_key: '/etc/ssl/sentry.example.com.key'
sentry::version: '8.4.1'
sentry::sentry_vhost: 'sentry.example.com'
```

## Classes
### sentry
This is the main class that handles the installation of Sentry from [PyPI](https://pypi.python.org/pypi), configures an Apache virtual host running `mod_wsgi`, and manages the Sentry background worker processes.
This is the main class that handles the installation of Sentry, configures an Apache virtual host running `mod_wsgi`, and manages the Sentry background worker processes.

Class parameters:
* **admin_email**: the admin user's email address; also used as login name (root@localhost)
Expand All @@ -96,6 +97,7 @@ Class parameters:
* **db_password**: the DB user's password (sentry)
* **db_port**: the PostgreSQL database port (5432)
* **db_user**: the user account with which to connect to the database (sentry)
* **extensions**: hash of Sentry extensions, with source URLs, to install
* **group**: UNIX group to own virtualenv, and run background workers (sentry)
* **ldap_* **: LDAP connection details used for creating local user accounts from AD users
* **memcached_host**: name or IP of memcached server (localhost)
Expand All @@ -106,55 +108,31 @@ Class parameters:
* **redis_port**: port to use for Redis (6379)
* **secret_key**: string used to hash cookies (fqdn_rand_string(40))
* **smtp_host**: name or IP of SMTP server (localhost)
* **ssl_* **: Apache SSL controls
* **team**: name of the default team to create and use for new projects
* **url**: source URL form which to install Sentry (false, use PyPI)
* **ssl_* **: Apache SSL controls. The `ssl_cert` and `ssl_key` parameters reference files on the Sentry server. You are responsible for getting these files onto the server yourself.
* **url**: source URL form which to install Sentry (false, use [PyPI](https://pypi.python.org/pypi/sentry/))
* **user**: UNIX user to own virtualenv, and run background workers (sentry)
* **version**: the Sentry version to install
* **vhost**: the URL at which users will access the Sentry GUI
* **wsgi_* **: mod_wsgi controls
* **extensions**: hash of Sentry extensions, with source URLs, to install

### sentry::setup
This private class ensures that all of the Sentry prerequisites are installed. It will create the direcotry into which Sentry will be installed, create the Sentry user and group, create a Python virtual environment, and install the RPM and `pip` dependencies.

### sentry::config
This private class installs the `sentry.conf.py` and `config.yml` configuration files used by Sentry.

### sentry::install
This class installs Sentry and its various dependencies. It will create the system user and group, install a Python virtualenv, several RPMs, and several `pip` packages. The [getsentry-ldap-auth](https://github.com/banno/getsentry-ldap-auth) plugin is installed, but will not be used unless an LDAP host is defined in `sentry::init`.
This private class installs Sentry itself. The [getsentry-ldap-auth](https://github.com/banno/getsentry-ldap-auth) plugin is installed, but will not be used unless an LDAP host is defined in `sentry::init`.

This class will also handle upgrades to Sentry, when the `version` parameter defined here is different from the version installed. The upgrade process is as automated as possible, but manual intervention may be required depending on your specific configuration.
Upon first installation, the initial database migrations will be performed, a Sentry admin user will be created, and a basic configuration will be bootstrapped.

Class parameters:
* **admin_email**: Sentry admin user email address
* **admin_password**: Sentry admin user password
* **group**: UNIX group to own Sentry files
* **organization**: default Sentry organization to create
* **path**: path into which to create virtualenv and install Sentry
* **project**: initial Sentry project to create
* **team**: default Sentry team to create
* **url**: an optional URL from which to install Sentry
* **user**: UNIX user to own Sentry files
* **version**: version of Sentry to install
* **extensions**: array of sentry extensions to install
This class will also handle upgrades to Sentry, when the `version` parameter defined here is different from the version installed. The upgrade process is as automated as possible, but manual intervention may be required depending on your specific configuration.

### sentry::service
This class manages the Sentry background worker via `systemd`.

Class parameters:
* **user**: UNIX user to run Sentry services
* **group**: UNIX group to run Sentry services
* **path**: path to Sentry installation / virtualenv
This private class manages the Sentry background workers via `systemd`.

### sentry::wsgi
This class installs an Apache virtual host with `mod_wsgi`. HTTPS support is optional.

Class parameters:
* **path**: the virtualenv path for your Sentry installation
* **publish_dsns**: whether or not to make each Sentry application's DSN accessible via http(s)
* **ssl**: whether or not to enable SSL support
* **ssl_ca**: the SSL CA file to use
* **ssl_chain**: the SSL chain file to use
* **ssl_cert**: the SSL public certificate to use
* **ssl_key**: the SSL private key to use
* **vhost**: the hostname at which Sentry will be accessible
* **wsgi_processes**: the number of mod_wsgi processes to use
* **wsgi_threads**: the number of mod_wsgi threads to use
This private class installs an Apache virtual host with `mod_wsgi`. HTTPS support is optional.

## Defines
### sentry::server::collect
Expand All @@ -180,7 +158,7 @@ This defined type looks for a custom fact named `${name}_lang`. If found, the v
### sentry::source::project
This defined type defines a Sentry project.

For each `sentry::source::project`, a Sentry project will be created in the default Organization and Team.
For each `sentry::source::project`, a Sentry project will be created in the default Organization and Team.

Type parameters:
* **organization**: The Sentry organization to use. Required. No default.
Expand Down
12 changes: 12 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require 'rspec-puppet/rake_task'
require 'puppetlabs_spec_helper/rake_tasks'

begin
if Gem::Specification::find_by_name('puppet-lint')
require 'puppet-lint/tasks/puppet-lint'
PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "vendor/**/*.pp"]
task :default => [:rspec, :lint]
end
rescue Gem::LoadError
task :default => :rspec
end
6 changes: 1 addition & 5 deletions manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@
#
# ssl_*: Apache SSL controls
#
# team: name of the default team to create and use for new projects
#
# url: source URL from which to install Sentry. (false, use PyPI)
#
# user: UNIX user to own virtualenv, and run background workers (sentry)
Expand Down Expand Up @@ -104,7 +102,6 @@
$ssl_chain = $sentry::params::ssl_chain,
$ssl_cert = $sentry::params::ssl_cert,
$ssl_key = $sentry::params::ssl_key,
$team = $sentry::params::team,
$url = $sentry::params::url,
$user = $sentry::params::user,
$version = $sentry::params::version,
Expand Down Expand Up @@ -161,7 +158,6 @@
path => $path,
project => $project,
ldap_auth_version => $ldap_auth_version,
team => $team,
user => $user,
version => $version,
subscribe => Class['::sentry::config'],
Expand All @@ -187,7 +183,7 @@
user => $user,
group => $group,
path => $path,
subscribe => Class['::sentry::config'],
subscribe => Class['::sentry::install'],
}
contain '::sentry::service'

Expand Down
2 changes: 0 additions & 2 deletions manifests/install.pp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
# organization: default Sentry organization to create
# path: path into which to create virtualenv and install Sentry
# project: initial Sentry project to create
# team: default Sentry team to create
# url: URL from which to install Sentry
# user: UNIX user to own Sentry files
# version: version of Sentry to install
Expand All @@ -35,7 +34,6 @@
$organization = $sentry::organization,
$path = $sentry::path,
$project = $sentry::project,
$team = $sentry::team,
$url = $sentry::url,
$user = $sentry::user,
$version = $sentry::version,
Expand Down
1 change: 0 additions & 1 deletion manifests/params.pp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
$ssl_chain = undef
$ssl_cert = '/etc/pki/tls/certs/localhost.crt'
$ssl_key = '/etc/pki/tls/private/localhost.key'
$team = 'Default'
$url = false
$user = 'sentry'
$version = 'latest'
Expand Down
45 changes: 43 additions & 2 deletions manifests/service.pp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# == Class: sentry::service
#
# This class is meant to be called from sentry.
# It ensures the service is running via systemd
# It ensures the background services are running via systemd
#
# === Parameters
#
Expand Down Expand Up @@ -30,6 +30,7 @@
path => '/bin:/sbin',
}

# Sentry Celery Worker
file { '/etc/systemd/system/sentry-worker.service':
ensure => present,
mode => '0644',
Expand All @@ -56,7 +57,34 @@
subscribe => Class['::sentry::config'],
}

# Setup log rotation for the sentry-worker process
# Sentry Celery Beat
file { '/etc/systemd/system/sentry-beat.service':
ensure => present,
mode => '0644',
owner => 'root',
group => 'root',
content => template('sentry/sentry-beat.service.erb'),
notify => Exec['enable-sentry-services'],
}

service { 'sentry-beat':
ensure => running,
enable => true,
hasrestart => true,
require => [ File['/etc/systemd/system/sentry-beat.service'],
User[$user],
],
}

# if the Sentry config changes, do a full restart of the Sentry beat worker
exec { 'restart-sentry-beat':
command => '/usr/bin/systemctl stop sentry-beat; /usr/bin/systemctl start sentry-beat',
path => '/bin:/usr/bin',
refreshonly => true,
subscribe => Class['::sentry::config'],
}

# Setup log rotation
logrotate::rule { 'sentry-worker':
ensure => present,
path => '/var/log/sentry/sentry-worker.log',
Expand All @@ -70,4 +98,17 @@
create_group => $group,
}

logrotate::rule { 'sentry-beat':
ensure => present,
path => '/var/log/sentry/sentry-beat.log',
create => true,
compress => true,
missingok => true,
rotate => 14,
ifempty => false,
create_mode => '0644',
create_owner => $user,
create_group => $group,
}

}
2 changes: 1 addition & 1 deletion metadata.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "covermymeds-sentry",
"version": "2.0.1",
"version": "3.0.0",
"author": "CoverMyMeds",
"license": "MIT",
"summary": "Install and configure Sentry",
Expand Down
38 changes: 38 additions & 0 deletions spec/classes/init_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require 'spec_helper'
describe 'Sentry' do
let(:facts) do
{
osfamily: 'RedHat',
operatingsystem: 'RedHat',
operatingsystemrelease: '7.2',
operatingsystemmajrelease: '7',
os: {
architecture: "x86_64",
family: "RedHat",
hardware: "x86_64",
name: "RedHat",
release: {
full: "7.2",
major: "7",
minor: "2"
},
selinux: {
config_mode: "permissive",
config_policy: "targeted",
current_mode: "permissive",
enabled: true,
enforced: false,
policy_version: "28"
}
},
python_version: '2.7.5'
}
end
context 'all default values' do
it { is_expected.to contain_class('sentry::setup') }
it { is_expected.to contain_class('sentry::config') }
it { is_expected.to contain_class('sentry::install') }
it { is_expected.to contain_class('sentry::service') }
it { is_expected.to contain_class('sentry::wsgi') }
end
end
40 changes: 40 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'rspec-puppet/spec_helper'
require 'puppetlabs_spec_helper/puppetlabs_spec_helper'

fixture_path = File.expand_path(File.join(__FILE__, '..', 'fixtures'))

RSpec.configure do |c|
c.module_path = File.join(fixture_path, 'modules')
c.manifest_dir = File.join(fixture_path, 'manifests')
c.hiera_config = 'spec/fixtures/hiera/hiera.yaml'
end

shared_context 'RedHat 7' do
let(:facts) do
{
osfamily: 'RedHat',
operatingsystem: 'RedHat',
operatingsystemrelease: '7.2',
operatingsystemmajrelease: '7',
os: {
architecture: "x86_64",
family: "RedHat",
hardware: "x86_64",
name: "RedHat",
release: {
full: "7.2",
major: "7",
minor: "2"
},
selinux: {
config_mode: "permissive",
config_policy: "targeted",
current_mode: "permissive",
enabled: true,
enforced: false,
policy_version: "28"
}
}
}
end
end
Loading

0 comments on commit 2fa148f

Please sign in to comment.