orats 0.6.5 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +231 -58
- data/lib/orats/cli.rb +63 -25
- data/lib/orats/commands/common.rb +47 -22
- data/lib/orats/commands/{outdated → diff}/compare.rb +5 -4
- data/lib/orats/commands/diff/exec.rb +86 -0
- data/lib/orats/commands/{outdated → diff}/parse.rb +5 -1
- data/lib/orats/commands/inventory.rb +121 -0
- data/lib/orats/commands/{play.rb → playbook.rb} +5 -5
- data/lib/orats/commands/project/exec.rb +74 -0
- data/lib/orats/commands/{new → project}/rails.rb +57 -81
- data/lib/orats/commands/{new → project}/server.rb +6 -4
- data/lib/orats/templates/auth.rb +26 -481
- data/lib/orats/templates/base.rb +74 -716
- data/lib/orats/templates/includes/common/LICENSE +22 -0
- data/lib/orats/templates/includes/new/rails/.env +43 -0
- data/lib/orats/templates/includes/{Gemfile → new/rails/Gemfile} +1 -1
- data/lib/orats/templates/includes/new/rails/Procfile +3 -0
- data/lib/orats/templates/includes/new/rails/README.md +3 -0
- data/lib/orats/templates/includes/{app → new/rails/app}/assets/favicon/favicon_base.png +0 -0
- data/lib/orats/templates/includes/new/rails/app/helpers/application_helper.rb +53 -0
- data/lib/orats/templates/includes/new/rails/app/models/account.rb +40 -0
- data/lib/orats/templates/includes/new/rails/app/views/devise/confirmations/new.html.erb +26 -0
- data/lib/orats/templates/includes/new/rails/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
- data/lib/orats/templates/includes/new/rails/app/views/devise/mailer/reset_password_instructions.html.erb +10 -0
- data/lib/orats/templates/includes/new/rails/app/views/devise/mailer/unlock_instructions.html.erb +8 -0
- data/lib/orats/templates/includes/new/rails/app/views/devise/passwords/edit.html.erb +28 -0
- data/lib/orats/templates/includes/new/rails/app/views/devise/passwords/new.html.erb +26 -0
- data/lib/orats/templates/includes/new/rails/app/views/devise/registrations/edit.html.erb +51 -0
- data/lib/orats/templates/includes/new/rails/app/views/devise/registrations/new.html.erb +31 -0
- data/lib/orats/templates/includes/new/rails/app/views/devise/sessions/new.html.erb +39 -0
- data/lib/orats/templates/includes/new/rails/app/views/devise/shared/_links.html.erb +38 -0
- data/lib/orats/templates/includes/new/rails/app/views/devise/unlocks/new.html.erb +26 -0
- data/lib/orats/templates/includes/new/rails/app/views/layouts/_disqus_comments_snippet.html.erb +19 -0
- data/lib/orats/templates/includes/new/rails/app/views/layouts/_disqus_count_snippet.html.erb +12 -0
- data/lib/orats/templates/includes/new/rails/app/views/layouts/_flash.html.erb +10 -0
- data/lib/orats/templates/includes/new/rails/app/views/layouts/_footer.html.erb +2 -0
- data/lib/orats/templates/includes/new/rails/app/views/layouts/_google_analytics_snippet.html.erb +13 -0
- data/lib/orats/templates/includes/new/rails/app/views/layouts/_google_analytics_tracker.html.erb +4 -0
- data/lib/orats/templates/includes/new/rails/app/views/layouts/_navigation.html.erb +18 -0
- data/lib/orats/templates/includes/new/rails/app/views/layouts/_navigation_auth.html.erb +15 -0
- data/lib/orats/templates/includes/new/rails/app/views/layouts/_navigation_links.html.erb +3 -0
- data/lib/orats/templates/includes/new/rails/app/views/layouts/application.html.erb +48 -0
- data/lib/orats/templates/includes/new/rails/app/views/pages/home.html.erb +81 -0
- data/lib/orats/templates/includes/new/rails/config/database.yml +19 -0
- data/lib/orats/templates/includes/new/rails/config/environments/staging.rb +5 -0
- data/lib/orats/templates/includes/new/rails/config/initializers/devise_async.rb +1 -0
- data/lib/orats/templates/includes/new/rails/config/initializers/mini_profiler.rb +4 -0
- data/lib/orats/templates/includes/new/rails/config/initializers/sidekiq.rb +16 -0
- data/lib/orats/templates/includes/new/rails/config/puma.rb +25 -0
- data/lib/orats/templates/includes/new/rails/config/secrets.yml +12 -0
- data/lib/orats/templates/includes/new/rails/config/sidekiq.yml +5 -0
- data/lib/orats/templates/includes/new/rails/config/sitemap.rb +20 -0
- data/lib/orats/templates/includes/new/rails/config/whenever.rb +7 -0
- data/lib/orats/templates/includes/new/rails/lib/backup/config.rb +116 -0
- data/lib/orats/templates/includes/new/rails/lib/backup/models/backup.rb +55 -0
- data/lib/orats/templates/includes/new/rails/lib/tasks/orats/backup.rake +18 -0
- data/lib/orats/templates/includes/new/rails/lib/tasks/orats/favicon.rake +48 -0
- data/lib/orats/templates/includes/new/rails/public/404.html +13 -0
- data/lib/orats/templates/includes/new/rails/public/422.html +13 -0
- data/lib/orats/templates/includes/new/rails/public/500.html +13 -0
- data/lib/orats/templates/includes/new/rails/public/502.html +13 -0
- data/lib/orats/templates/includes/new/rails/test/fixtures/accounts.yml +27 -0
- data/lib/orats/templates/includes/new/rails/test/models/account_test.rb +46 -0
- data/lib/orats/templates/includes/{Galaxyfile → playbook/Galaxyfile} +0 -0
- data/lib/orats/templates/includes/playbook/site.yml +53 -0
- data/lib/orats/templates/playbook.rb +115 -0
- data/lib/orats/version.rb +1 -1
- data/test/integration/cli_test.rb +122 -75
- data/test/test_helper.rb +16 -8
- metadata +63 -14
- data/lib/orats/commands/new/ansible.rb +0 -98
- data/lib/orats/commands/new/exec.rb +0 -60
- data/lib/orats/commands/outdated/exec.rb +0 -46
- data/lib/orats/templates/play.rb +0 -185
@@ -0,0 +1,55 @@
|
|
1
|
+
Model.new(:backup, 'Backup for the current RAILS_ENV') do
|
2
|
+
split_into_chunks_of 10
|
3
|
+
compress_with Gzip
|
4
|
+
|
5
|
+
database PostgreSQL do |db|
|
6
|
+
db.sudo_user = ENV['DATABASE_USERNAME']
|
7
|
+
# To dump all databases, set `db.name = :all` (or leave blank)
|
8
|
+
db.name = ENV['DATABASE_NAME']
|
9
|
+
db.username = ENV['DATABASE_USERNAME']
|
10
|
+
db.password = ENV['DATABASE_PASSWORD']
|
11
|
+
db.host = ENV['DATABASE_HOST']
|
12
|
+
db.port = 5432
|
13
|
+
db.socket = '/var/run/postgresql'
|
14
|
+
#db.skip_tables = ['skip', 'these', 'tables']
|
15
|
+
#db.only_tables = ['only', 'these', 'tables']
|
16
|
+
end
|
17
|
+
|
18
|
+
# uncomment the block below to archive a specific path
|
19
|
+
# this may be useful if you have user supplied content
|
20
|
+
|
21
|
+
# archive :app_archive do |archive|
|
22
|
+
# archive.add File.join(ENV['PROJECT_PATH'], 'public', 'system')
|
23
|
+
# end
|
24
|
+
|
25
|
+
# uncomment the block below and fill in the required information
|
26
|
+
# to use S3 to store your backups
|
27
|
+
|
28
|
+
# don't want to use S3? check out the other available options:
|
29
|
+
# http://meskyanichi.github.io/backup/v4/storages/
|
30
|
+
|
31
|
+
# store_with S3 do |s3|
|
32
|
+
# s3.access_key_id = ENV['S3_ACCESS_KEY_ID']
|
33
|
+
# s3.secret_access_key = ENV['S3_SECRET_ACCESS_KEY']
|
34
|
+
# s3.region = ENV['S3_REGION']
|
35
|
+
# s3.bucket = 'backup'
|
36
|
+
# s3.path = "/database/#{ENV['RAILS_ENV']}"
|
37
|
+
# end
|
38
|
+
|
39
|
+
ENV['SMTP_ENCRYPTION'].empty? ? mail_encryption = 'none' : mail_encryption = ENV['SMTP_ENCRYPTION']
|
40
|
+
|
41
|
+
notify_by Mail do |mail|
|
42
|
+
mail.on_success = false
|
43
|
+
#mail.on_warning = true
|
44
|
+
mail.on_failure = true
|
45
|
+
mail.from = ENV['ACTION_MAILER_DEFAULT_FROM']
|
46
|
+
mail.to = ENV['ACTION_MAILER_DEFAULT_TO']
|
47
|
+
mail.address = ENV['SMTP_ADDRESS']
|
48
|
+
mail.port = ENV['SMTP_PORT'].to_i
|
49
|
+
mail.domain = ENV['SMTP_DOMAIN']
|
50
|
+
mail.user_name = ENV['SMTP_USERNAME']
|
51
|
+
mail.password = ENV['SMTP_PASSWORD']
|
52
|
+
mail.authentication = ENV['SMTP_AUTH']
|
53
|
+
mail.encryption = mail_encryption.to_sym
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
namespace :orats do
|
2
|
+
desc 'Create a backup of your application for a specific environment'
|
3
|
+
task :backup do
|
4
|
+
if File.exist?('.env') && File.file?('.env')
|
5
|
+
require 'dotenv'
|
6
|
+
Dotenv.load
|
7
|
+
source_external_env = ''
|
8
|
+
else
|
9
|
+
source_external_env = '. /etc/default/app_name &&'
|
10
|
+
end
|
11
|
+
|
12
|
+
# hack'ish way to run the backup command with elevated privileges, it won't prompt for a password on the production
|
13
|
+
# server because passwordless sudo has been enabled if you use the ansible setup provided by orats
|
14
|
+
system 'sudo whoami'
|
15
|
+
|
16
|
+
system "#{source_external_env} backup perform -t backup -c '#{File.join('lib', 'backup', 'config.rb')}' --log-path='#{File.join('log')}'"
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
namespace :orats do
|
2
|
+
desc 'Create favicons from a single base png'
|
3
|
+
task :favicons do
|
4
|
+
require 'favicon_maker'
|
5
|
+
|
6
|
+
FaviconMaker.generate do
|
7
|
+
setup do
|
8
|
+
template_dir Rails.root.join('app', 'assets', 'favicon')
|
9
|
+
output_dir Rails.root.join('public')
|
10
|
+
end
|
11
|
+
|
12
|
+
favicon_base_path = "#{template_dir}/favicon_base.png"
|
13
|
+
|
14
|
+
unless File.exist?(favicon_base_path)
|
15
|
+
puts
|
16
|
+
puts 'A base favicon could not be found, make sure one exists at:'
|
17
|
+
puts favicon_base_path
|
18
|
+
puts
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
|
22
|
+
from File.basename(favicon_base_path) do
|
23
|
+
icon 'speeddial-160x160.png'
|
24
|
+
icon 'apple-touch-icon-228x228-precomposed.png'
|
25
|
+
icon 'apple-touch-icon-152x152-precomposed.png'
|
26
|
+
icon 'apple-touch-icon-144x144-precomposed.png'
|
27
|
+
icon 'apple-touch-icon-120x120-precomposed.png'
|
28
|
+
icon 'apple-touch-icon-114x114-precomposed.png'
|
29
|
+
icon 'apple-touch-icon-76x76-precomposed.png'
|
30
|
+
icon 'apple-touch-icon-72x72-precomposed.png'
|
31
|
+
icon 'apple-touch-icon-60x60-precomposed.png'
|
32
|
+
icon 'apple-touch-icon-57x57-precomposed.png'
|
33
|
+
icon 'favicon-196x196.png'
|
34
|
+
icon 'favicon-160x160.png'
|
35
|
+
icon 'favicon-96x96.png'
|
36
|
+
icon 'favicon-64x64.png'
|
37
|
+
icon 'favicon-32x32.png'
|
38
|
+
icon 'favicon-24x24.png'
|
39
|
+
icon 'favicon-16x16.png'
|
40
|
+
icon 'favicon.ico', size: '64x64,32x32,24x24,16x16'
|
41
|
+
end
|
42
|
+
|
43
|
+
each_icon do |filepath|
|
44
|
+
puts "Creating favicon @ #{filepath}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
---
|
2
|
+
foo:
|
3
|
+
id: 1
|
4
|
+
email: foo@bar.com
|
5
|
+
encrypted_password: passwordisnotreallyencrypted
|
6
|
+
role: admin
|
7
|
+
created_at: 2012-01-01 01:45:17
|
8
|
+
current_sign_in_at: 2013-03-15 11:22:33
|
9
|
+
|
10
|
+
no_role:
|
11
|
+
id: 2
|
12
|
+
email: joey@almostcool.com
|
13
|
+
encrypted_password: hackthegibson
|
14
|
+
created_at: 1995-09-15 08:10:12
|
15
|
+
|
16
|
+
bad_role:
|
17
|
+
id: 3
|
18
|
+
email: hello@world.com
|
19
|
+
encrypted_password: reallysecure
|
20
|
+
role: ahhhh
|
21
|
+
created_at: 2011-09-20 10:10:10
|
22
|
+
|
23
|
+
beep:
|
24
|
+
id: 4
|
25
|
+
email: beep@beep.com
|
26
|
+
encrypted_password: beepbeepbeep
|
27
|
+
created_at: 2010-03-6 05:15:45
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class AccountTest < ActiveSupport::TestCase
|
4
|
+
def setup
|
5
|
+
@account = accounts(:foo)
|
6
|
+
end
|
7
|
+
|
8
|
+
def teardown
|
9
|
+
@account = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
test 'expect new account' do
|
13
|
+
assert @account.valid?
|
14
|
+
assert_not_nil @account.email
|
15
|
+
assert_not_nil @account.encrypted_password
|
16
|
+
end
|
17
|
+
|
18
|
+
test 'expect guest to be default role' do
|
19
|
+
no_role = accounts(:no_role)
|
20
|
+
assert_equal 'guest', no_role.role
|
21
|
+
end
|
22
|
+
|
23
|
+
test 'expect invalid role to not save' do
|
24
|
+
bad_role = accounts(:bad_role)
|
25
|
+
assert_not bad_role.valid?
|
26
|
+
end
|
27
|
+
|
28
|
+
test 'expect e-mail to be unique' do
|
29
|
+
duplicate = Account.create(email: 'foo@bar.com')
|
30
|
+
|
31
|
+
assert_not duplicate.valid?
|
32
|
+
end
|
33
|
+
|
34
|
+
test 'expect random password if password is empty' do
|
35
|
+
@account.password = ''
|
36
|
+
@account.encrypted_password = ''
|
37
|
+
@account.save
|
38
|
+
|
39
|
+
random_password = Account.generate_password
|
40
|
+
assert_equal 10, random_password.length
|
41
|
+
end
|
42
|
+
|
43
|
+
test 'expect random password of 20 characters' do
|
44
|
+
assert_equal 20, Account.generate_password(20).length
|
45
|
+
end
|
46
|
+
end
|
File without changes
|
@@ -0,0 +1,53 @@
|
|
1
|
+
---
|
2
|
+
- name: ensure all servers are commonly configured
|
3
|
+
hosts: all
|
4
|
+
sudo: true
|
5
|
+
|
6
|
+
roles:
|
7
|
+
- { role: nickjj.user, tags: [common, user] }
|
8
|
+
|
9
|
+
- name: ensure database servers are configured
|
10
|
+
hosts: database
|
11
|
+
sudo: true
|
12
|
+
|
13
|
+
roles:
|
14
|
+
- role: nickjj.security
|
15
|
+
tags: [database, security]
|
16
|
+
security_ufw_ports:
|
17
|
+
- rule: deny
|
18
|
+
port: 80
|
19
|
+
proto: tcp
|
20
|
+
- { role: nickjj.postgres, tags: [database, postgres] }
|
21
|
+
|
22
|
+
- name: ensure cache servers are configured
|
23
|
+
hosts: cache
|
24
|
+
sudo: true
|
25
|
+
|
26
|
+
roles:
|
27
|
+
- role: nickjj.security
|
28
|
+
tags: [cache, security]
|
29
|
+
security_ufw_ports:
|
30
|
+
- rule: deny
|
31
|
+
port: 80
|
32
|
+
proto: tcp
|
33
|
+
- { role: DavidWittman.redis, tags: [cache, redis] }
|
34
|
+
|
35
|
+
- name: ensure app servers are configured
|
36
|
+
hosts: app
|
37
|
+
sudo: true
|
38
|
+
|
39
|
+
roles:
|
40
|
+
- role: nickjj.security
|
41
|
+
tags: [app, security]
|
42
|
+
security_ufw_ports:
|
43
|
+
- rule: allow
|
44
|
+
port: 80
|
45
|
+
proto: tcp
|
46
|
+
- { role: nickjj.ruby, tags: [app, ruby] }
|
47
|
+
- { role: nickjj.nodejs, tags: [app, nodejs] }
|
48
|
+
- { role: nickjj.nginx, tags: [app, nginx] }
|
49
|
+
- { role: nickjj.rails, tags: [app, rails] }
|
50
|
+
- { role: nickjj.whenever, tags: [app, rails] }
|
51
|
+
- { role: nickjj.pumacorn, tags: [app, rails] }
|
52
|
+
- { role: nickjj.sidekiq, tags: [app, rails] }
|
53
|
+
- { role: nickjj.monit, tags: [app, monit] }
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
# =============================================================================
|
4
|
+
# template for generating an orats ansible playbook for ansible 1.6.x
|
5
|
+
# =============================================================================
|
6
|
+
# view the task list at the bottom of the file
|
7
|
+
# -----------------------------------------------------------------------------
|
8
|
+
|
9
|
+
# -----------------------------------------------------------------------------
|
10
|
+
# private functions
|
11
|
+
# -----------------------------------------------------------------------------
|
12
|
+
def generate_token
|
13
|
+
SecureRandom.hex(64)
|
14
|
+
end
|
15
|
+
|
16
|
+
def method_to_sentence(method)
|
17
|
+
method.tr!('_', ' ')
|
18
|
+
method[0] = method[0].upcase
|
19
|
+
method
|
20
|
+
end
|
21
|
+
|
22
|
+
def log_task(message)
|
23
|
+
puts
|
24
|
+
say_status 'task', "#{method_to_sentence(message.to_s)}:", :yellow
|
25
|
+
puts '-'*80, ''; sleep 0.25
|
26
|
+
end
|
27
|
+
|
28
|
+
def git_commit(message)
|
29
|
+
git add: '-A'
|
30
|
+
git commit: "-m '#{message}'"
|
31
|
+
end
|
32
|
+
|
33
|
+
def git_config(field)
|
34
|
+
command = "git config --global user.#{field}"
|
35
|
+
git_field_value = run(command, capture: true).gsub("\n", '')
|
36
|
+
default_value = "YOUR_#{field.upcase}"
|
37
|
+
|
38
|
+
git_field_value.to_s.empty? ? default_value : git_field_value
|
39
|
+
end
|
40
|
+
|
41
|
+
def copy_from_local_gem(source, dest = '')
|
42
|
+
dest = source if dest.empty?
|
43
|
+
|
44
|
+
base_path = "#{File.expand_path File.dirname(__FILE__)}/includes/playbook"
|
45
|
+
|
46
|
+
run "mkdir -p #{File.dirname(dest)}" unless Dir.exist?(File.dirname(dest))
|
47
|
+
run "cp -f #{base_path}/#{source} #{dest}"
|
48
|
+
end
|
49
|
+
|
50
|
+
# ---
|
51
|
+
|
52
|
+
def delete_generated_rails_code
|
53
|
+
log_task __method__
|
54
|
+
|
55
|
+
run 'rm -rf * .git .gitignore'
|
56
|
+
end
|
57
|
+
|
58
|
+
def add_playbook_directory
|
59
|
+
log_task __method__
|
60
|
+
|
61
|
+
run "mkdir -p #{app_name}"
|
62
|
+
run "mv #{app_name}/* ."
|
63
|
+
run "rm -rf #{app_name}"
|
64
|
+
git :init
|
65
|
+
git_commit 'Initial commit'
|
66
|
+
end
|
67
|
+
|
68
|
+
def add_license
|
69
|
+
log_task __method__
|
70
|
+
|
71
|
+
author_name = git_config 'name'
|
72
|
+
author_email = git_config 'email'
|
73
|
+
|
74
|
+
copy_from_local_gem '../common/LICENSE', 'LICENSE'
|
75
|
+
gsub_file 'LICENSE', 'Time.now.year', Time.now.year.to_s
|
76
|
+
gsub_file 'LICENSE', 'author_name', author_name
|
77
|
+
gsub_file 'LICENSE', 'author_email', author_email
|
78
|
+
git_commit 'Add MIT license'
|
79
|
+
end
|
80
|
+
|
81
|
+
def add_main_playbook
|
82
|
+
log_task __method__
|
83
|
+
|
84
|
+
copy_from_local_gem 'site.yml', 'site.yml'
|
85
|
+
git_commit 'Add the main playbook'
|
86
|
+
end
|
87
|
+
|
88
|
+
def remove_unused_files_from_git
|
89
|
+
log_task __method__
|
90
|
+
|
91
|
+
git add: '-u'
|
92
|
+
git_commit 'Remove unused files'
|
93
|
+
end
|
94
|
+
|
95
|
+
def log_complete
|
96
|
+
puts
|
97
|
+
say_status 'success', "\e[1m\Everything has been setup successfully\e[0m", :cyan
|
98
|
+
puts
|
99
|
+
say_status 'question', 'Are most of your apps similar?', :yellow
|
100
|
+
say_status 'answer', 'You only need to generate one playbook and you just did', :white
|
101
|
+
say_status 'answer', 'Use the inventory in each project to customize certain things', :white
|
102
|
+
puts
|
103
|
+
say_status 'question', 'Are you new to ansible?', :yellow
|
104
|
+
say_status 'answer', 'http://docs.ansible.com/intro_getting_started.html', :white
|
105
|
+
puts
|
106
|
+
end
|
107
|
+
|
108
|
+
# ---
|
109
|
+
|
110
|
+
delete_generated_rails_code
|
111
|
+
add_playbook_directory
|
112
|
+
add_license
|
113
|
+
add_main_playbook
|
114
|
+
remove_unused_files_from_git
|
115
|
+
log_complete
|
data/lib/orats/version.rb
CHANGED
@@ -1,135 +1,182 @@
|
|
1
|
+
require 'yaml'
|
1
2
|
require_relative '../test_helper'
|
2
3
|
|
3
4
|
class TestCLI < Minitest::Test
|
4
5
|
include Orats::Test
|
5
6
|
|
6
|
-
|
7
|
-
app_name = generate_app_name
|
7
|
+
attr_accessor :target_path, :extra_flags
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
assert_match /Start your server/, out
|
9
|
+
def startup
|
10
|
+
@target_path = ''
|
11
|
+
@extra_flags = ''
|
12
|
+
end
|
14
13
|
|
15
|
-
|
16
|
-
|
14
|
+
def teardown
|
15
|
+
assert_nuked unless @target_path.nil?
|
16
|
+
end
|
17
17
|
|
18
|
-
|
18
|
+
def test_project
|
19
|
+
assert_project ansible: :assert
|
19
20
|
end
|
20
21
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
22
|
+
def test_project_with_auth
|
23
|
+
assert_project '--template auth', ansible: :assert
|
24
|
+
end
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
def test_project_without_ansible
|
27
|
+
assert_project '--skip-ansible', ansible: :refute
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
+
def test_project_with_invalid_template
|
31
|
+
@target_path = generate_app_name
|
32
|
+
@extra_flags = "#{ORATS_NEW_FLAGS} --template foo"
|
30
33
|
|
31
|
-
|
32
|
-
|
33
|
-
assert_path_exists "#{TEST_PATH}/#{app_name}/services/#{app_name}"
|
34
|
+
assert_orats 'project', 'not a valid template'
|
35
|
+
end
|
34
36
|
|
35
|
-
|
36
|
-
|
37
|
-
|
37
|
+
def test_inventory
|
38
|
+
assert_inventory
|
39
|
+
end
|
38
40
|
|
39
|
-
|
41
|
+
def test_playbook
|
42
|
+
assert_playbook
|
40
43
|
end
|
41
44
|
|
42
|
-
def
|
43
|
-
|
45
|
+
def test_diff
|
46
|
+
assert_playbook
|
44
47
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
+
@target_path = ''
|
49
|
+
assert_orats 'diff', 'Compare this version of'
|
50
|
+
end
|
48
51
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
assert_path_exists "#{TEST_PATH}/#{app_name}"
|
52
|
+
def test_templates
|
53
|
+
assert_orats 'templates', '--template auth'
|
54
|
+
end
|
53
55
|
|
54
|
-
|
56
|
+
def test_version
|
57
|
+
assert_orats 'version', 'Orats'
|
55
58
|
end
|
56
59
|
|
57
|
-
|
58
|
-
app_name = generate_app_name
|
60
|
+
private
|
59
61
|
|
60
|
-
|
61
|
-
|
62
|
-
end
|
62
|
+
def assert_orats(command, match_regex, ansible: nil)
|
63
|
+
out, err = capture_orats(command)
|
63
64
|
|
64
|
-
assert_match
|
65
|
-
|
65
|
+
assert_match /#{match_regex}/, out
|
66
|
+
|
67
|
+
assert_or_refute_ansible ansible if ansible
|
66
68
|
end
|
67
69
|
|
68
|
-
def
|
69
|
-
|
70
|
+
def assert_project(flags = '', ansible: nil)
|
71
|
+
@target_path = generate_app_name
|
72
|
+
absolute_target_path = "#{TEST_PATH}/#{@target_path}"
|
73
|
+
@extra_flags = "#{ORATS_NEW_FLAGS} #{flags}"
|
70
74
|
|
71
|
-
|
72
|
-
orats "play #{app_name}"
|
73
|
-
end
|
74
|
-
assert_match /success/, out
|
75
|
+
assert_orats 'project', 'Start your server', ansible: ansible
|
75
76
|
|
76
|
-
|
77
|
-
|
77
|
+
if ansible == :assert
|
78
|
+
assert_ansible_yaml "#{absolute_target_path}/inventory/group_vars/all.yml"
|
78
79
|
end
|
79
|
-
assert_match /Comparing this version of/, out
|
80
80
|
|
81
|
-
|
81
|
+
absolute_target_path << "/services/#{@target_path}"
|
82
|
+
assert_project_tests_pass absolute_target_path
|
82
83
|
end
|
83
84
|
|
84
|
-
def
|
85
|
+
def assert_project_tests_pass(target_path)
|
85
86
|
out, err = capture_subprocess_io do
|
86
|
-
|
87
|
+
system "cd #{target_path} && bundle exec rake test"
|
87
88
|
end
|
88
89
|
|
89
|
-
|
90
|
+
log_rails_test_results out
|
91
|
+
assert out.include?('0 failures') && out.include?('0 errors'), err
|
90
92
|
end
|
91
93
|
|
92
|
-
|
94
|
+
def assert_inventory
|
95
|
+
@target_path = generate_app_name
|
96
|
+
@extra_flags = '--skip-galaxy'
|
97
|
+
|
98
|
+
assert_orats 'inventory', 'success'
|
99
|
+
assert_ansible_yaml "#{TEST_PATH}/#{@target_path}/inventory/group_vars/all.yml"
|
100
|
+
end
|
101
|
+
|
102
|
+
def assert_playbook
|
103
|
+
@target_path = generate_app_name
|
93
104
|
|
94
|
-
|
105
|
+
assert_orats 'playbook', 'success'
|
106
|
+
assert_ansible_yaml "#{TEST_PATH}/#{@target_path}/site.yml"
|
107
|
+
end
|
108
|
+
|
109
|
+
def assert_nuked(options = {})
|
95
110
|
out, err = capture_subprocess_io do
|
96
|
-
orats "nuke #{
|
111
|
+
orats "nuke #{@target_path}", flags: options[:flags], answer: 'y'
|
97
112
|
end
|
98
113
|
|
99
|
-
assert_match /#{
|
100
|
-
system
|
114
|
+
assert_match /#{@target_path}/, out
|
115
|
+
system "rm -rf #{TEST_PATH}"
|
101
116
|
end
|
102
117
|
|
103
|
-
def
|
104
|
-
|
118
|
+
def assert_in_file(file_path, match_regex)
|
119
|
+
file_contents = `cat #{file_path}`
|
120
|
+
assert_match /#{match_regex}/, file_contents
|
105
121
|
end
|
106
122
|
|
107
|
-
def
|
123
|
+
def assert_path(file_or_dir)
|
108
124
|
assert File.exists?(file_or_dir), "Expected path '#{file_or_dir}' to exist"
|
109
125
|
end
|
110
126
|
|
111
|
-
def
|
127
|
+
def refute_path(file_or_dir)
|
112
128
|
refute File.exists?(file_or_dir), "Expected path '#{file_or_dir}' to exist"
|
113
129
|
end
|
114
130
|
|
115
|
-
def
|
116
|
-
|
117
|
-
|
118
|
-
|
131
|
+
def assert_or_refute_ansible(assert_or_refute)
|
132
|
+
absolute_target_path = "#{TEST_PATH}/#{@target_path}"
|
133
|
+
|
134
|
+
assert_path "#{absolute_target_path}/services"
|
135
|
+
send("#{assert_or_refute.to_s}_path",
|
136
|
+
"#{absolute_target_path}/inventory")
|
137
|
+
send("#{assert_or_refute.to_s}_path",
|
138
|
+
"#{absolute_target_path}/secrets")
|
139
|
+
end
|
140
|
+
|
141
|
+
def assert_ansible_yaml(file_path)
|
142
|
+
begin
|
143
|
+
file = IO.read(file_path)
|
144
|
+
invalid_ansible_yaml = file.match(/^([^#].\w): {/)
|
145
|
+
|
146
|
+
if invalid_ansible_yaml
|
147
|
+
assert false, "Invalid yaml syntax found near:\n #{invalid_ansible_yaml}\n\nYou need to include quotes around values that start with jinja template tags:\n Example, foo: '{{ bar }}'"
|
148
|
+
return
|
149
|
+
end
|
119
150
|
|
120
|
-
|
151
|
+
assert YAML.load(file)
|
152
|
+
rescue Psych::SyntaxError => ex
|
153
|
+
assert false, ex.message
|
154
|
+
end
|
121
155
|
end
|
122
156
|
|
123
|
-
def
|
124
|
-
|
157
|
+
def capture_orats(command)
|
158
|
+
out, err = capture_subprocess_io do
|
159
|
+
orats "#{command} #{@target_path}", flags: @extra_flags
|
160
|
+
end
|
161
|
+
|
162
|
+
[out, err]
|
125
163
|
end
|
126
164
|
|
127
|
-
def
|
128
|
-
|
165
|
+
def log_rails_test_results(out)
|
166
|
+
out_lines = out.split("\n")
|
129
167
|
|
130
|
-
|
131
|
-
|
168
|
+
out_lines.delete_if do |line|
|
169
|
+
line.include?('Sidekiq') || line.start_with?('.') ||
|
170
|
+
line.include?('Running') || line.include?('Run options') ||
|
171
|
+
line.empty?
|
172
|
+
end
|
132
173
|
|
133
|
-
|
174
|
+
puts
|
175
|
+
puts '-'*80
|
176
|
+
puts 'Results of running `bundle exec rake test` on the generated test app:'
|
177
|
+
puts '-'*80
|
178
|
+
puts out_lines.join("\n\n").rstrip
|
179
|
+
puts '-'*80
|
180
|
+
puts
|
134
181
|
end
|
135
182
|
end
|