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

Add support for rsync Storage #73

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 2 additions & 16 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,10 @@ sudo: false
matrix:
fast_finish: true
include:
- rvm: 1.8.7
env: PUPPET_GEM_VERSION="~> 3.3.0"
- rvm: 1.8.7
env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes"
- rvm: 1.9.3
env: PUPPET_GEM_VERSION="~> 3.3.0"
env: PUPPET_GEM_VERSION="~> 3.8.0" JSON_PURE_GEM_VERSION="~> 1.8.3"
- rvm: 1.9.3
env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes"
env: PUPPET_GEM_VERSION="~> 3.0" JSON_PURE_GEM_VERSION="~> 1.8.3" FUTURE_PARSER="yes"
- rvm: 2.0.0
env: PUPPET_GEM_VERSION="~> 3.3.0"
- rvm: 2.0.0
Expand All @@ -25,13 +21,3 @@ matrix:
env: PUPPET_GEM_VERSION="~> 4.1"
- rvm: 2.1.0
env: PUPPET_GEM_VERSION="~> 4.2"
notifications:
email: false
hipchat:
rooms:
- secure: CK11caPkzorkB4onwQPDolAFM32RO+Mn/rt3MRBe0xkt+SyRj8Icmv4MLbWUhiIydZQLrZpC+k993U9RuNOgghOcBq9tKF3U1sM6rrWLNJOnvobi6S+WZYe325IcsMchREERd0TUJYeYWCw2YxYlJBS/xRmpXO5gLZAPzm1NI9k=
template:
- '%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message} (<a href="%{build_url}">Details</a>/<a href="%{compare_url}">Change view</a>)'
format: html
on_success: always
on_failure: always
5 changes: 5 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ group :unit_tests do
gem 'puppet-syntax', :require => false
gem 'metadata-json-lint', :require => false
gem 'json', :require => false
if jasonpureversion = ENV['JSON_PURE_GEM_VERSION']
gem 'json_pure', jasonpureversion, :require => false
else
gem 'json_pure', :require => false
end
gem 'puppet-lint-absolute_classname-check', :require => false
gem 'puppet-lint-appends-check', :require => false
gem 'puppet-lint-empty_string-check', :require => false
Expand Down
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,22 @@ String. Bucket to store archive when using S3 storage type

String. Region to store archive when using S3 storage type

##### `rsync_mode`

String. rsync mode to use with rsync storage

##### `rsync_port`

Integer. Port for rsync storage model to use

Default: 22

##### `rsync_compress`

Boolean. Weather or not to enable rsync compression on transfer

Default: undef (false)

##### `encryptor`

String. Encryptor to use on backup archive
Expand Down
3 changes: 3 additions & 0 deletions manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
# FTP
$ftp_port = $::backup::params::ftp_port,
$ftp_passive_mode = $::backup::params::ftp_passive_mode,
# Rsync
$rsync_mode = $::backup::params::rsync_mode,
$rsync_password_file = $::backup::params::rsync_password_file,

## Encryptors
$encryptor = $::backup::params::encryptor,
Expand Down
48 changes: 45 additions & 3 deletions manifests/job.pp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@
# FTP
$ftp_port = $::backup::ftp_port,
$ftp_passive_mode = $::backup::ftp_passive_mode,
# rsync
$rsync_mode = $::backup::rsync_mode,
$rsync_port = $::backup::rsync_port,
$rsync_compress = $::backup::rsync_compress,
$rsync_password_file = $::backup::rsync_password_file,

## Encryptors
$encryptor = $::backup::encryptor,
Expand Down Expand Up @@ -173,8 +178,8 @@
}

# Storage
if !member(['s3', 'local', 'ftp'], $storage_type) {
fail("[Backup::Job::${name}]: Currently supported storage types are: ftp, local, and s3")
if !member(['s3', 'local', 'ftp', 'rsync'], $storage_type) {
fail("[Backup::Job::${name}]: Currently supported storage types are: ftp, local, s3, and rsync")
}

if $keep and !is_integer($keep) {
Expand All @@ -186,7 +191,7 @@
}

# local and ftp require path parameter
if member(['ftp', 'local'], $storage_type) {
if member(['ftp', 'local', 'rsync'], $storage_type) {
if !$path {
fail("[Backup::Job::${name}]: Path parameter is required with storage_type => ${storage_type}")
}
Expand Down Expand Up @@ -243,6 +248,30 @@
validate_bool($ftp_passive_mode)
}

if $storage_type == 'rsync' {
if $rsync_mode and !member([
'ssh',
'ssh_daemon',
'rsync_daemon',
], $rsync_mode ) {
fail("[Backup::Job::${name}]: ${rsync_mode} is not a valid mode")
}
if !$storage_host or !is_string($storage_host) {
fail("[Backup::Job::${name}]: Parameter storage_host is required for rsync storage")
}
if $rsync_port and !is_integer($rsync_port) {
fail("[Backup::Job::${name}]: rsync_port must be an integer. (Got: ${rsync_port})")
}

if $rsync_compress {
validate_bool($rsync_compress)
}
if $rsync_password_file {
validate_string($rsync_password_file)
}

}

# Encryptor
if $encryptor and !member(['openssl'], $encryptor) {
fail("[Backup::Job::${name}]: Supported encryptors are openssl")
Expand Down Expand Up @@ -479,6 +508,19 @@
content => template('backup/job/ftp.erb'),
order => '35',
}
} elsif $storage_type == 'rsync' {
# Template uses
# - $server_username
# - $server_ip
# - $server_port
# - $server_compress
# - $server_mode
# - $path
concat::fragment { "${_name}_rsync":
target => "/etc/backup/models/${_name}.rb",
content => template('backup/job/rsync.erb'),
order => '35',
}
}

if $logfile_enabled or $syslog_enabled or $console_quiet {
Expand Down
5 changes: 5 additions & 0 deletions manifests/params.pp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@
# FTP
$ftp_port = 21
$ftp_passive_mode = false
# rsync
$rsync_mode = undef
$rsync_port = undef
$rsync_compress = undef
$rsync_password_file = undef

## Encryptors
$encryptor = undef
Expand Down
139 changes: 139 additions & 0 deletions spec/defines/backup_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,97 @@
end
end # ftp

context 'rsync' do
context 'bad mode' do
let(:params) { {
:types => 'archive',
:add => 'here',
:storage_type => 'rsync',
:storage_host => 'mysite.example.com',
:path => '/there',
:rsync_mode => 'abcde'
} }
it { expect { is_expected.to compile }.to raise_error(/abcde is not a valid mode/)}
end

context 'missing host' do
let(:params) { {
:types => 'archive',
:add => 'here',
:storage_type => 'rsync',
:storage_username => 'myuser',
:path => '/there',
} }
it { expect { is_expected.to compile }.to raise_error(/storage_host is required/)}
end

context 'missing path' do
let(:params) { {
:types => 'archive',
:add => 'here',
:storage_type => 'rsync',
:storage_username => 'myuser',
:storage_host => 'mysite.example.com',
} }
it { expect { is_expected.to compile }.to raise_error(/Path parameter is required/)}
end

context 'bad port' do
let(:params) { {
:types => 'archive',
:add => 'here',
:storage_type => 'rsync',
:storage_username => 'myuser',
:storage_host => 'mysite.example.com',
:rsync_port => 'abcde',
:path => '/there',
} }
it { expect { is_expected.to compile }.to raise_error(/rsync_port must be an integer/)}
end

context 'bad rsync_compress' do
let(:params) { {
:types => 'archive',
:add => 'here',
:storage_type => 'rsync',
:storage_username => 'myuser',
:storage_host => 'mysite.example.com',
:path => '/there',
:rsync_compress => 'bob',
} }
it { expect { is_expected.to compile }.to raise_error(/"bob" is not a boolean/)}
end

context 'bad rsync_compress' do
let(:params) { {
:types => 'archive',
:add => 'here',
:storage_type => 'rsync',
:storage_username => 'myuser',
:storage_host => 'mysite.example.com',
:path => '/there',
:rsync_compress => 'bob',
} }
it { expect { is_expected.to compile }.to raise_error(/"bob" is not a boolean/)}
end

context 'rsync_password_file is not a string' do
let(:params) { {
:types => 'archive',
:add => 'here',
:storage_type => 'rsync',
:storage_username => 'myuser',
:storage_host => 'mysite.example.com',
:path => '/there',
:rsync_compress => true,
:rsync_mode => 'rsync_daemon',
:rsync_password_file => true
} }
it { expect { is_expected.to compile }.to raise_error(/true is not a string/)}
end

end # rsync

context 'encryptor generic' do
context 'bad encryptor' do
let(:params) { {
Expand Down Expand Up @@ -1014,6 +1105,54 @@
end
end # ftp

context 'rsync' do
context 'minimum settings' do
let(:params) { {
:types => 'archive',
:add => '/here',
:storage_type => 'rsync',
:storage_host => 'mysite.example.com',
:path => '/there',
} }
it { should_not contain_concat__fragment('job1_rsync').with(:content => /server\..+user/) }
it { should contain_concat__fragment('job1_rsync').with(:content => /server\.host\s+=\s"mysite.example.com"/) }
it { should contain_concat__fragment('job1_rsync').with(:content => /server\.path\s+=\s"\/there"/) }
it { should_not contain_concat__fragment('job1_rsync').with(:content => /server\.rsync_compress/) }
end

context 'all params' do
let(:params) { {
:types => 'archive',
:add => '/here',
:storage_type => 'rsync',
:storage_username => 'myuser',
:storage_host => 'mysite.example.com',
:path => '/there',
:rsync_port => 22,
:rsync_mode => 'ssh',
:keep => 10,
} }
it { should contain_concat__fragment('job1_rsync').with(:content => /server\..+user\s+=\s"myuser"/) }
it { should contain_concat__fragment('job1_rsync').with(:content => /server\.port\s+=\s22/) }
it { should contain_concat__fragment('job1_rsync').with(:content => /server\.mode\s+=\s:ssh/) }
end

context 'rsync_daemon mode' do
let(:params) { {
:types => 'archive',
:add => '/here',
:storage_type => 'rsync',
:storage_host => 'mysite.example.com',
:path => 'there',
:rsync_port => 873,
:rsync_mode => 'rsync_daemon',
:keep => 10,
} }
it { should contain_concat__fragment('job1_rsync').with(:content => /server\.port\s+=\s873/) }
it { should contain_concat__fragment('job1_rsync').with(:content => /server\.mode\s+=\s:rsync_daemon/) }
end
end # rsync

context 'logging' do
context 'no logging' do
let(:params) { {
Expand Down
24 changes: 24 additions & 0 deletions templates/job/rsync.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
##
# rsync [Storage]
#
store_with RSync do |server|
<%if @storage_username and (@rsync_mode == 'ssh') -%>
server.ssh_user = "<%= @storage_username -%>"
<% elsif @storage_username -%>
server.rsync_user = "<%= @storage_username -%>"
<% end -%>
server.host = "<%= @storage_host -%>"
<%if @rsync_port -%>
server.port = <%= @rsync_port %>
<% end -%>
server.path = "<%= @_path -%>"
<% if @rsync_compress -%>
server.compress = "<%= @rsync_compress %>"
<% end -%>
<% if @rsync_mode -%>
server.mode = :<%= @rsync_mode %>
<% end -%>
<% if @rsync_password_file -%>
server.rsync_password_file = "<%= @rsync_password_file %>"
<% end -%>
end