taperole 1.6.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -0
  3. data/CONTRIBUTING.md +8 -0
  4. data/README.md +33 -4
  5. data/Rakefile +6 -0
  6. data/Vagrantfile +6 -7
  7. data/bin/tape +2 -89
  8. data/lib/taperole/commands/ansible.rb +56 -0
  9. data/lib/taperole/commands/installer.rb +19 -0
  10. data/lib/taperole/commands/tape.rb +32 -0
  11. data/lib/taperole/core/ansible_runner.rb +86 -0
  12. data/lib/taperole/core/installer.rb +87 -0
  13. data/lib/taperole/core/notifier.rb +47 -0
  14. data/lib/taperole/helpers/files.rb +76 -0
  15. data/lib/taperole/helpers/logging.rb +37 -0
  16. data/lib/taperole/notifiers/slack.rb +83 -0
  17. data/lib/taperole/version.rb +3 -0
  18. data/lib/taperole.rb +24 -0
  19. data/requirements.yml +1 -1
  20. data/roles/backend_checkout/tasks/main.yml +1 -0
  21. data/roles/delayed_job/tasks/main.yml +0 -15
  22. data/roles/deployer_user/tasks/keys.yml +6 -6
  23. data/roles/deployer_user/tasks/main.yml +0 -3
  24. data/roles/monit_install/tasks/main.yml +6 -0
  25. data/roles/monit_install/templates/monitrc.j2 +290 -0
  26. data/roles/nginx/tasks/main.yml +3 -4
  27. data/roles/nginx/templates/nginx_unicorn.j2 +1 -0
  28. data/roles/node/tasks/main.yml +2 -1
  29. data/roles/ruby/tasks/main.yml +3 -11
  30. data/roles/unicorn_install/tasks/main.yml +0 -3
  31. data/roles/unicorn_install/templates/unicorn.rb.j2 +1 -1
  32. data/roles/unicorn_install/templates/unicorn_init.j2 +1 -1
  33. data/roles/unicorn_install/templates/unicorn_monit.j2 +1 -1
  34. data/spec/commands/installer_spec.rb +117 -0
  35. data/spec/spec_helper.rb +24 -0
  36. data/taperole.gemspec +8 -1
  37. data/templates/base/deploy.example.yml +1 -0
  38. data/templates/base/hosts.example +1 -1
  39. data/templates/base/omnibox.example.yml +15 -0
  40. data/templates/base/rake.example.yml +18 -0
  41. data/templates/base/tape_vars.example.yml +9 -8
  42. data/templates/static_html/omnibox.example.yml +13 -0
  43. data/test/base_docker_box/Dockerfile +1 -1
  44. data/test/rails/Dockerfile +3 -3
  45. data/test/rails/start_rails.sh +1 -0
  46. data/test/rails/tape_vars.yml +2 -2
  47. data/vendor/ANXS.postgresql/.travis.yml +27 -12
  48. data/vendor/ANXS.postgresql/README.md +1 -1
  49. data/vendor/ANXS.postgresql/Vagrantfile +7 -2
  50. data/vendor/ANXS.postgresql/meta/.galaxy_install_info +1 -1
  51. data/vendor/ANXS.postgresql/meta/main.yml +1 -1
  52. data/vendor/ANXS.postgresql/tasks/configure.yml +10 -10
  53. data/vendor/ANXS.postgresql/tasks/databases.yml +27 -27
  54. data/vendor/ANXS.postgresql/tasks/install_yum.yml +2 -2
  55. data/vendor/ANXS.postgresql/tasks/users.yml +4 -4
  56. data/vendor/ANXS.postgresql/tasks/users_privileges.yml +3 -3
  57. data/vendor/ANXS.postgresql/tests/Dockerfile-centos6 +20 -0
  58. data/vendor/ANXS.postgresql/tests/Dockerfile-ubuntu14.04 +17 -0
  59. data/vendor/ANXS.postgresql/tests/playbook.yml +1 -1
  60. data/vendor/ANXS.postgresql/tests/vars.yml +2 -0
  61. data/vendor/Stouts.backup/.bumpversion.cfg +1 -1
  62. data/vendor/Stouts.backup/.travis.yml +0 -1
  63. data/vendor/Stouts.backup/CONTRIBUTORS +2 -0
  64. data/vendor/Stouts.backup/README.md +1 -0
  65. data/vendor/Stouts.backup/defaults/main.yml +3 -3
  66. data/vendor/Stouts.backup/meta/.galaxy_install_info +1 -1
  67. data/vendor/Stouts.backup/runtests.sh +65 -0
  68. data/vendor/Stouts.backup/tasks/backup.yml +3 -0
  69. data/vendor/Stouts.backup/tasks/configure.yml +13 -12
  70. data/vendor/Stouts.backup/tasks/install.deb.yml +6 -8
  71. data/vendor/Stouts.backup/tasks/install.red.yml +28 -0
  72. data/vendor/Stouts.backup/tasks/remove.yml +3 -3
  73. data/vendor/Stouts.backup/templates/cron.j2 +1 -1
  74. data/vendor/Stouts.backup/templates/duply.sh.j2 +219 -218
  75. data/vendor/Stouts.backup/templates/pre.j2 +6 -0
  76. data/vendor/Stouts.backup/templates/restore.j2 +6 -0
  77. data/vendor/Stouts.backup/vars/Debian.yml +3 -0
  78. data/vendor/Stouts.backup/vars/Ubuntu.yml +1 -0
  79. metadata +67 -10
  80. data/lib/tape/ansible_runner.rb +0 -130
  81. data/lib/tape/info.rb +0 -9
  82. data/lib/tape/installer.rb +0 -160
  83. data/lib/tape/notifiers/slack.rb +0 -79
  84. data/lib/tape/overwriter.rb +0 -14
  85. data/lib/tape/qemu_provisioner.rb +0 -167
  86. data/lib/tape.rb +0 -127
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cd21b5c1b7d9532c3a6225c43fc6225726196307
4
- data.tar.gz: 1b30b5918731df5a64930e0fc7705ea9e05a53ca
3
+ metadata.gz: 21ca9a88b00c6e0ed2f77b29937b871038b3f911
4
+ data.tar.gz: 4768be3843152356b7add30fbe8e5e3dedfcaad2
5
5
  SHA512:
6
- metadata.gz: accd791072ff897618d73a8a0d7b412feacdc3ab40740ddc5dd9939092ba1f7695d3f3cf5629fc6f61fca0848c061453d1499cec2262e0792799c1a92f937bf6
7
- data.tar.gz: 8109633af31ad2bbc309aff92848c9c94f870048a1039eb2f9f33ce8ff481648d858b9c0e8886e114b75ce6d28a3fa6217ac19c7e88041bd1a6b6eca72a0b003
6
+ metadata.gz: e3c6f367b84e1b0b339fd4f768cf079e36279e3e35b310924de4d04836a4637a4706b4cb635bc1d09c895518a40f78ca04755250610b04618a2636531c117fd9
7
+ data.tar.gz: 5e1b9437c2ebfc85bdb591af65f4040ead65ec91977c7d3678c416ee86a1af4449fec373754284e33a580c0568a2e86a6b99c8a1f2790372e4cebacfd7c96a77
data/.travis.yml CHANGED
@@ -6,5 +6,8 @@ services:
6
6
  - docker
7
7
 
8
8
  script:
9
+ - gem build taperole.gemspec
10
+ - gem install --dev taperole
11
+ - rake spec
9
12
  - docker build -f test/rails/Dockerfile -t imagetest .
10
13
  - docker run -i -t $(docker images -q imagetest) /start_rails.sh | grep "Hello"
data/CONTRIBUTING.md CHANGED
@@ -5,6 +5,14 @@
5
5
  ###Workflow
6
6
  We use [Waffle.io](https://waffle.io/smashingboxes/tape) to manage our workflow for this project. Please respect the workflow and move PRs that are ready to be mereged into the 'Ready' column.
7
7
 
8
+ ####Testing
9
+
10
+ There are two main ways we test taperole. The first is basic unit tests, via rspec. Those can be run via:
11
+
12
+ `rake test`
13
+
14
+ The second way is a kind of integration test. We use tape to stand up a basic vanilla rails app (leveraging docker) and then check that a curl returns the correct thing. There isn't an easy way to run this locally, but it is set up on travis to run automatically.
15
+
8
16
  ###PR Structure
9
17
 
10
18
  Please give details regarding your PR in the following format. It really helps with review and quickens the speed at which your changes are merged in
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  # Infrastructure Management
4
4
 
5
5
  ## Deploying & provisioning with tape
6
- **Use Unbuntu trusty64 (14.04 x64)**
6
+ **Use Unbuntu trusty64 (16 x64)**
7
7
 
8
8
  **Enable ssh access via root user**
9
9
 
@@ -45,9 +45,30 @@ All default configurations found in `vars/defaults.yml` can be overridden in you
45
45
  **Default Ruby Version** 2.3.0
46
46
 
47
47
  ### Backups
48
- Backups are handled via [duply](http://duply.net/) and occur every night at 4am under the root user. You can configure your backup schedule and target where you want your backups stored at within your `taperole/tape_vars.yml` file.
48
+ Backups are handled via [duply](http://duply.net/) and are configured via the [Stouts.backup](https://github.com/Stouts/Stouts.backup) ansible galaxy role. Bacups occur every night at 4am under the root user. You can configure your backup schedule and target where you want your backups stored at within your `taperole/tape_vars.yml` file.
49
49
 
50
- By default, all servers in your [production] group will have backups enabled
50
+ The default location for backups is the `/var/lib/postgresql/backups` directory.
51
+
52
+ All servers in your [production] group will have backups enabled by default.
53
+
54
+ Detailed configurations can be made in your tape_vars.yml file.
55
+
56
+ ```
57
+ # Store Backups on S3
58
+ backup_dir: s3+http://[aws_access_key:aws_secret_access_key]@bucket_name[/folder]
59
+
60
+ # Store Backups on Seperate server via rsync
61
+ backup_dir: s3+http://[aws_access_key:aws_secret_access_key]@bucket_name[/folder]
62
+
63
+ # Adjust Cron Job Schedule (default is every night at 4am)
64
+ backup_schedule: "* */4 * * *"
65
+
66
+ # Change Which Servers are backed up
67
+ backup_hosts:
68
+ - production
69
+ - staging
70
+ - qa
71
+ ```
51
72
 
52
73
  ### Custom roles
53
74
  You can add app specific ansible roles to `<app_root>/roles`.
@@ -93,7 +114,7 @@ localhost:2222 ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key
93
114
  The port number might be different if other vagrant machines are running, run `vagrant ssh-config` to find the correct configuration.
94
115
  You can specify a port using the `ansible_ssh_port` in your hosts inventory file.
95
116
 
96
- 3. Update `tape_vars.yml` with information to a [rails app you want to deploy](https://github.com/BrandonMathis/vanilla-rails-app)
117
+ 3. Update `tape_vars.yml` with information to a rails app you want to deploy
97
118
  4. `tape ansible everything -l vagrant`
98
119
 
99
120
  ### With Docker
@@ -235,6 +256,14 @@ This will git pull the latest changes from the tracking branch you specified and
235
256
 
236
257
  This command runs all Ansible roles specified in the deploy.yml playbook.
237
258
 
259
+ ### Rake tasks
260
+
261
+ To run ad-hoc rake tasks, you can use the following:
262
+
263
+ ```
264
+ tape ansible rake --task users:rank
265
+ ```
266
+
238
267
  ## Slack integration
239
268
 
240
269
  Tape includes built-in support for posting messages to slack at the beginning and end of deployments.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/Vagrantfile CHANGED
@@ -2,25 +2,24 @@
2
2
  # vi: set ft=ruby :
3
3
 
4
4
  Vagrant.configure 2 do |config|
5
- config.vm.box = 'ubuntu/trusty64'
5
+ config.vm.box = "ubuntu/xenial64"
6
6
 
7
- name = %x[basename `git rev-parse --show-toplevel`].chomp
7
+ name = %x[basename `git rev-parse --show-toplevel`].chomp.gsub(/[^0-9a-z ]/i, '')
8
8
  config.vm.define "#{name}_vagrant_box"
9
+ config.vm.hostname = "#{name}"
9
10
 
10
- # private_ip = "192.168.13.37"
11
- # config.vm.network(:private_network, :ip => private_ip)
11
+ private_ip = "192.168.13.37"
12
+ config.vm.network(:private_network, :ip => private_ip)
12
13
 
13
- # TODO free me from the bonds of this ip
14
14
  config.vm.network 'forwarded_port', guest: 443, host: 8080
15
15
  config.vm.network 'private_network', type: 'dhcp'
16
16
 
17
- config.ssh.insert_key = false
18
17
  config.ssh.shell = 'bash -c "BASH_ENV=/etc/profile exec bash"'
19
18
 
20
19
  config.vm.provision :shell, inline: <<-SCRIPT
21
20
  sudo su
22
21
  mkdir -p ~/.ssh/
23
- cp /home/vagrant/.ssh/authorized_keys ~/.ssh/
22
+ cp /home/ubuntu/.ssh/authorized_keys ~/.ssh/
24
23
  chmod 600 ~/.ssh/authorized_keys
25
24
  SCRIPT
26
25
  end
data/bin/tape CHANGED
@@ -1,92 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $LOAD_PATH << File.join(__dir__, '..', 'lib')
3
+ require 'taperole'
4
4
 
5
- require 'optparse'
6
- require 'ostruct'
7
- require 'tape'
8
-
9
- options = OpenStruct.new
10
- opt_parser = OptionParser.new do |opts|
11
- opts.banner = "Usage: tape <module> <action> [options]"
12
-
13
- opts.on("-v", "--[no-]verbose", "Be loud") {|v| options.verbose = v}
14
- opts.on("--ask-vault-pass", "Ask for Ansible vault password") { options.vault = true }
15
-
16
- opts.on("-i", "--inventory [INVENTORY_FILE]",
17
- String, "Do actions with the given inventory file") do |i|
18
- options.inventory_file = i
19
- end
20
-
21
- opts.on('-n', "--name [NAME]",
22
- String, "The name of the machine to operate on") do |n|
23
- options.name = n
24
- end
25
-
26
- opts.on('-p', "--port [PORT]",
27
- Integer, "The port that the machine is listening on for SSH connections") do |p|
28
- options.port = p
29
- end
30
-
31
- opts.on('-bBOOK', "--book=PLAYBOOK",
32
- String, "A custom playbook to run") do |p|
33
- options.book = p
34
- end
35
-
36
- opts.on("-h", "--help", "Show this help") do
37
- STDERR.puts opts
38
- exit 0
39
- end
40
-
41
- opts.on("-l", "--limit [PATTERN]",
42
- String, "Limits ansible runs to hosts matching PATTERN") do |p|
43
- options.host_pattern = p
44
- end
45
-
46
- opts.on("-t", "--tags [TAGS]",
47
- String, "only run plays and tasks tagged with these values") do |t|
48
- options.tags = t
49
- end
50
-
51
- opts.on("-r", "--role=ROLE_NAME",
52
- String, "name of the role to operate on") do |r|
53
- options.role = r
54
- end
55
-
56
- opts.separator ''
57
- opts.separator "MODULES"
58
- TapeBoxer.registered_modules.values.each do |exec_module|
59
- opts.separator " #{exec_module.name.to_s.upcase}"
60
- exec_module.klass.actions.values.each do |action|
61
- opts.separator " #{action.name}: #{action.description}"
62
- end
63
- end
64
- end
65
-
66
-
67
- opt_parser.parse!(ARGV)
68
-
69
- fail_without = ->(&block){
70
- val = block.call
71
-
72
- if val
73
- return val
74
- else
75
- STDERR.puts(opt_parser.help)
76
- exit 1
77
- end
78
- }
79
-
80
- module_name = fail_without.call{ ARGV.shift }.to_sym
81
- action_name = fail_without.call{ ARGV.shift }.to_sym
82
-
83
- exec_module = fail_without.call{TapeBoxer.registered_modules[module_name]}
84
-
85
- begin
86
- exec_module.klass.new(options).execute_action(action_name)
87
- rescue TapeBoxer::InvalidAction,
88
- TapeBoxer::ActionError, TapeBoxer::UnspecifiedOption => e
89
-
90
- STDERR.puts(e.message)
91
- exit 2
92
- end
5
+ Taperole::Commands::Tape.start(ARGV)
@@ -0,0 +1,56 @@
1
+ module Taperole
2
+ module Commands
3
+ class Ansible < Thor
4
+ include Taperole::AnsibleRunner
5
+ include Taperole::Helpers::Logging
6
+
7
+ class_option :limit,
8
+ type: :string,
9
+ aliases: :l,
10
+ desc: 'Limits ansible runs to hosts matching the given pattern'
11
+ class_option :task,
12
+ type: :string,
13
+ aliases: :T,
14
+ desc: 'Name of the rake task to execute'
15
+ class_option :inventory,
16
+ aliases: :i,
17
+ type: :string,
18
+ desc: 'Do actions with the given inventory file'
19
+ class_option :name,
20
+ aliases: :n,
21
+ type: :string,
22
+ desc: 'The name of the machine to operate on'
23
+ class_option :port,
24
+ aliases: :p,
25
+ type: :numeric,
26
+ desc: 'The port that the machine is listening on for SSH connections'
27
+ class_option :tags,
28
+ aliases: :t,
29
+ type: :string,
30
+ desc: 'Only run plays and tasks tagged with these values'
31
+ class_option :role,
32
+ aliases: :r,
33
+ type: :string,
34
+ desc: 'Name of the role to operate on'
35
+
36
+ class_option :'ask-vault-pass', type: :boolean, desc: 'Ask for Ansible vault password'
37
+
38
+ class_option :book,
39
+ aliases: :b,
40
+ type: :string,
41
+ desc: 'A custom playbook to run'
42
+
43
+ desc 'everything', 'Initial setup of a server'
44
+ def everything
45
+ Taperole::Notifier.register_notifiers(options)
46
+ valid_preconfigs ? ansible(options: options) : puts("Not a Rails or JS app")
47
+ end
48
+
49
+ desc 'deploy', 'Deploy the latest version of the app'
50
+ def deploy
51
+ Taperole::Notifier.register_notifiers(options)
52
+ ansible_deploy(args: '-t be_deploy,fe_deploy', options: options)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,19 @@
1
+ module Taperole
2
+ module Commands
3
+ class Installer < Thor
4
+ include Taperole::Installer
5
+ include Taperole::Helpers::Logging
6
+
7
+ option :vagrant, type: :boolean
8
+ desc 'install', 'Creates all necessary hosts and config files'
9
+ def install
10
+ install_tape
11
+ end
12
+
13
+ desc 'uninstall', 'Cleans up files generated by the installer'
14
+ def uninstall
15
+ uninstall_tape
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,32 @@
1
+ require 'thor'
2
+
3
+ module Taperole
4
+ module Commands
5
+ class Tape < Thor
6
+ include Taperole::Helpers::Files
7
+ include Taperole::Helpers::Logging
8
+
9
+ class_option :verbose, type: :boolean
10
+ class_option :debug, type: :boolean
11
+ class_option :quiet, type: :boolean
12
+
13
+ map %w[--version -v] => :__print_version
14
+
15
+ desc "--version, -v", "print the version"
16
+ def __print_version
17
+ puts Taperole::VERSION
18
+ end
19
+
20
+ desc 'ansible [COMMAND]', 'run tapes ansible commands'
21
+ subcommand 'ansible', Ansible
22
+
23
+ desc 'installer [COMMAND]', 'install and uninstall tape'
24
+ subcommand 'installer', Installer
25
+
26
+ desc 'overwrite [ROLE]', 'Overwrite a taperole ansible role'
27
+ def overwrite_role(role)
28
+ FileUtils.cp_r("#{tape_dir}/roles/#{role}", "taperole/roles/")
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,86 @@
1
+ module Taperole
2
+ module AnsibleRunner
3
+ include Taperole::Helpers::Files
4
+
5
+ protected
6
+
7
+ def valid_preconfigs
8
+ if rails_app?
9
+ valid_gems
10
+ elsif fe_app?
11
+ true
12
+ else
13
+ false
14
+ end
15
+ end
16
+
17
+ def valid_gems
18
+ has_gem_in_gemfile?('unicorn')
19
+ end
20
+
21
+ def has_gem_in_gemfile?(name)
22
+ if open('Gemfile').grep(/#{name}/).empty?
23
+ logger.error "💥 ERROR: Add #{name} to your Gemfile!💥 ".red
24
+ false
25
+ else
26
+ true
27
+ end
28
+ end
29
+
30
+ def ansible(args: '', options: {})
31
+ exec_ansible("#{tapefiles_dir}/omnibox.yml", args, options)
32
+ end
33
+
34
+ def ansible_deploy(args: '', options: {})
35
+ exec_ansible("#{tapefiles_dir}/deploy.yml", args, options)
36
+ end
37
+
38
+ def ansible_custom_playbook(args: '', options: {})
39
+ exec_ansible("#{tapefiles_dir}/#{options[:book]}", args, options)
40
+ end
41
+
42
+ def ansible_rake_task(options: {})
43
+ exec_ansible("#{tapefiles_dir}/rake.yml", "--extra-vars \"task=#{options[:task]}\"", options)
44
+ end
45
+
46
+ def exec_ansible(playbook, args, options)
47
+ enforce_roles_path!
48
+ cmd = "ANSIBLE_CONFIG=#{local_dir}/.tape/ansible.cfg ansible-playbook -i"
49
+ cmd += " #{inventory_file(options)} #{playbook} #{args} #{hosts_flag(options)}"
50
+ cmd += " -e tape_dir=#{tape_dir}"
51
+ cmd += ' --ask-vault-pass' if options[:vault]
52
+ cmd += ' -vvvv' if options[:verbose]
53
+ cmd += " -t #{options[:tags]}" if options[:tags]
54
+ logger.info "Executing: #{cmd}" if options[:verbose]
55
+ Taperole::Notifier.notify_observers(:start)
56
+ if Kernel.system(cmd)
57
+ Taperole::Notifier.notify_observers(:success)
58
+ else
59
+ Taperole::Notifier.notify_observers(:fail)
60
+ end
61
+ end
62
+
63
+ def enforce_roles_path!
64
+ Dir.mkdir('.tape') unless Dir.exist?('.tape')
65
+
66
+ File.open("#{local_dir}/.tape/ansible.cfg", 'w') do |f|
67
+ f.puts '[defaults]'
68
+ f.puts "roles_path=.tape/roles:#{tape_dir}/roles:#{tape_dir}/vendor"
69
+ f.puts "inventory=#{tapefiles_dir}/hosts"
70
+ f.puts "retries-dir=/dev/null"
71
+ f.puts "retry_files_enabled = False"
72
+ f.puts '[ssh_connection]'
73
+ f.puts 'ssh_args=-o ForwardAgent=yes'
74
+ end
75
+ end
76
+
77
+ def hosts_flag(options)
78
+ limit = options[:limit]
79
+ "-l #{limit}" if limit
80
+ end
81
+
82
+ def inventory_file(options)
83
+ options[:inventory_file] || "#{tapefiles_dir}/hosts"
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,87 @@
1
+ require 'pathname'
2
+
3
+ module Taperole
4
+ module Installer
5
+ include Taperole::Helpers::Files
6
+ include Thor::Actions
7
+
8
+ protected
9
+
10
+ def install_tape
11
+ add_tape_to_gitignore
12
+ mkdir tapefiles_dir
13
+ create_tape_files
14
+ create_roles_dir
15
+ create_inventory_file
16
+ create_ssh_keys_dir
17
+ handle_vagrantfile
18
+ end
19
+
20
+ def uninstall_tape
21
+ rm "#{tapefiles_dir}/omnibox.yml"
22
+ rm "#{tapefiles_dir}/deploy.yml"
23
+ rm "#{tapefiles_dir}/tape_vars.yml"
24
+ rm "#{tapefiles_dir}/rake.yml"
25
+ rm "#{tapefiles_dir}/roles"
26
+ rm "#{tapefiles_dir}/hosts"
27
+ rm "#{local_dir}/dev_keys"
28
+ rm "#{local_dir}/Vagrantfile"
29
+ end
30
+
31
+ private
32
+
33
+ def add_tape_to_gitignore
34
+ File.open('.gitignore', 'r+') { |f| f.puts '.tape' unless f.read =~ /^\.tape$/ }
35
+ end
36
+
37
+ def create_tape_files
38
+ if fe_app? && !rails_app?
39
+ logger.info '🔎 JS/HTML app detected'.red
40
+ copy_static_app_examples
41
+ elsif rails_app?
42
+ logger.info '🔎 Rails app detected'.red
43
+ copy_basic_examples
44
+ end
45
+ end
46
+
47
+ def copy_static_app_examples
48
+ %w(omnibox deploy tape_vars).each do |base_filename|
49
+ copy_example(
50
+ "templates/static_html/#{base_filename}.example.yml",
51
+ "#{tapefiles_dir}/#{base_filename}.yml"
52
+ )
53
+ end
54
+ end
55
+
56
+ def copy_basic_examples
57
+ %w(omnibox deploy tape_vars rake).each do |base_filename|
58
+ copy_example(
59
+ "templates/base/#{base_filename}.example.yml",
60
+ "#{tapefiles_dir}/#{base_filename}.yml"
61
+ )
62
+ end
63
+ end
64
+
65
+ def create_roles_dir
66
+ mkdir "#{tapefiles_dir}/roles"
67
+ `touch #{tapefiles_dir}/roles/.keep`
68
+ end
69
+
70
+ def create_inventory_file
71
+ copy_example 'templates/base/hosts.example', "#{tapefiles_dir}/hosts"
72
+ end
73
+
74
+ def create_ssh_keys_dir
75
+ mkdir "#{local_dir}/dev_keys"
76
+ end
77
+
78
+ def handle_vagrantfile
79
+ if options[:vagrant].nil?
80
+ options[:vagrant] = ask('Are you going to use vagrant? (y/n): ')
81
+ end
82
+ if options[:vagrant]
83
+ copy_example 'Vagrantfile', 'Vagrantfile'
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,47 @@
1
+ require 'singleton'
2
+ require 'yaml'
3
+
4
+ module Taperole
5
+ class Notifier
6
+ include ::Singleton
7
+
8
+ attr_accessor :observers
9
+
10
+ def initialize
11
+ @observers = []
12
+ end
13
+
14
+ class << self
15
+ include Taperole::Helpers::Files
16
+
17
+ def register_notifiers(options)
18
+ if config["slack_webhook_url"]
19
+ slack_notifier = Taperole::Notifiers::Slack.new(
20
+ config["slack_webhook_url"],
21
+ deploy_info(options)
22
+ )
23
+ instance.observers.push(slack_notifier)
24
+ end
25
+ end
26
+
27
+ def config
28
+ @config ||= YAML.load_file("#{tapefiles_dir}/tape_vars.yml")
29
+ end
30
+
31
+ def deploy_info(options)
32
+ {
33
+ app_name: config["app_name"],
34
+ user: `whoami`.chomp,
35
+ hosts: options[:limit] || 'default',
36
+ repo: config["be_app_repo"] || ''
37
+ }
38
+ end
39
+
40
+ def notify_observers(state)
41
+ instance.observers.each do |observer|
42
+ observer.update(state)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,76 @@
1
+ module Taperole
2
+ module Helpers
3
+ module Files
4
+ def fe_app?
5
+ !Dir["#{local_dir}/package.json"].empty?
6
+ end
7
+
8
+ def rails_app?
9
+ !Dir["#{local_dir}/config.ru"].empty?
10
+ end
11
+
12
+ def tape_dir
13
+ File.realpath(File.join(__dir__, '../../../'))
14
+ end
15
+
16
+ def local_dir
17
+ Dir.pwd
18
+ end
19
+
20
+ def tapefiles_dir
21
+ local_dir + '/taperole'
22
+ end
23
+
24
+ def tapecfg_dir
25
+ local_dir + '/.tape'
26
+ end
27
+
28
+ def rm(file)
29
+ logger.info 'Deleting '.red + file
30
+ FileUtils.rm_r file
31
+ end
32
+
33
+ def mkdir(name)
34
+ file_text = "#{::Pathname.new(name).basename}: "
35
+ begin
36
+ FileUtils.mkdir name
37
+ success(file_text)
38
+ rescue Errno::EEXIST
39
+ exists(file_text)
40
+ rescue StandardError => e
41
+ error(file_text)
42
+ raise e
43
+ end
44
+ end
45
+
46
+ def copy_example(file, cp_file)
47
+ file_text = "#{::Pathname.new(cp_file).basename}: "
48
+ begin
49
+ if File.exist?(cp_file.to_s)
50
+ exists(file_text)
51
+ else
52
+ FileUtils.cp("#{tape_dir}/#{file}", cp_file.to_s)
53
+ success(file_text)
54
+ end
55
+ rescue StandardError => e
56
+ error(file_text)
57
+ raise e
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ def success(file_text)
64
+ logger.info file_text + '✔'.green
65
+ end
66
+
67
+ def error(file_text)
68
+ logger.info file_text + '✘'.red
69
+ end
70
+
71
+ def exists(file_text)
72
+ logger.info file_text + '✘ (Exists)'.yellow
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,37 @@
1
+ require 'logger'
2
+
3
+ module Taperole
4
+ module Helpers
5
+ module Logging
6
+ def initialize(*_args)
7
+ super
8
+ logger.level = logger_level
9
+ logger.formatter = proc do |_severity, _datetime, _progname, msg|
10
+ "#{msg}\n"
11
+ end
12
+ end
13
+
14
+ def logger
15
+ Logging.logger
16
+ end
17
+
18
+ def self.logger
19
+ @logger ||= Logger.new(STDOUT)
20
+ end
21
+
22
+ private
23
+
24
+ def logger_level
25
+ if options[:debug]
26
+ Logger::DEBUG
27
+ elsif options[:verbose]
28
+ Logger::INFO
29
+ elsif options[:quiet]
30
+ Logger::ERROR
31
+ else
32
+ Logger::INFO
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end