mobile_workflow 0.10.2 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +3 -1
- data/app/controllers/concerns/mobile_workflow/param_parser.rb +6 -3
- data/app/controllers/concerns/mobile_workflow/s3_storable.rb +18 -12
- data/app/controllers/mobile_workflow/sns_notifications_controller.rb +25 -22
- data/app/helpers/mobile_workflow/application_helper.rb +2 -0
- data/app/jobs/mobile_workflow/add_attachment_job.rb +2 -1
- data/app/jobs/mobile_workflow/application_job.rb +2 -0
- data/app/mailers/mobile_workflow/application_mailer.rb +2 -0
- data/app/models/concerns/mobile_workflow/attachable.rb +3 -3
- data/app/models/concerns/mobile_workflow/displayable/steps/form.rb +12 -69
- data/app/models/concerns/mobile_workflow/displayable/steps/list.rb +6 -3
- data/app/models/concerns/mobile_workflow/displayable/steps/map.rb +8 -4
- data/app/models/concerns/mobile_workflow/displayable/steps/question.rb +14 -8
- data/app/models/concerns/mobile_workflow/displayable/steps/stack.rb +22 -75
- data/app/models/concerns/mobile_workflow/displayable/steps/styled_content/grid.rb +10 -21
- data/app/models/concerns/mobile_workflow/displayable/steps/styled_content/stack.rb +8 -28
- data/app/models/concerns/mobile_workflow/displayable.rb +10 -8
- data/bin/mwf +11 -10
- data/config/initializers/add_frozen_string_literal.rb +4 -3
- data/config/routes.rb +2 -0
- data/lib/generators/mobile_workflow/controller_generator.rb +26 -21
- data/lib/generators/mobile_workflow/install/install_generator.rb +55 -52
- data/lib/generators/mobile_workflow/install/templates/app/helpers/application_helper.rb +2 -0
- data/lib/generators/mobile_workflow/install/templates/app/models/ability.rb +2 -0
- data/lib/generators/mobile_workflow/install/templates/app/models/application_record.rb +2 -0
- data/lib/generators/mobile_workflow/install/templates/create_users.rb +2 -0
- data/lib/generators/mobile_workflow/install/templates/spec/factories/users.rb +2 -0
- data/lib/generators/mobile_workflow/model_generator.rb +7 -3
- data/lib/mobile_workflow/cli/app_builder.rb +147 -140
- data/lib/mobile_workflow/cli/app_server_cleaner.rb +19 -14
- data/lib/mobile_workflow/cli/app_server_generator.rb +53 -49
- data/lib/mobile_workflow/cli/aws_backend.rb +82 -74
- data/lib/mobile_workflow/cli/dokku_backend.rb +58 -55
- data/lib/mobile_workflow/cli/heroku_backend.rb +54 -49
- data/lib/mobile_workflow/cli.rb +9 -7
- data/lib/mobile_workflow/deprecated.rb +34 -0
- data/lib/mobile_workflow/displayable.rb +10 -9
- data/lib/mobile_workflow/engine.rb +3 -1
- data/lib/mobile_workflow/open_api_spec/parser.rb +25 -24
- data/lib/mobile_workflow/railtie.rb +3 -1
- data/lib/mobile_workflow/tasks/s3.rake +5 -3
- data/lib/mobile_workflow/tasks/set_env.rake +30 -31
- data/lib/mobile_workflow/version.rb +3 -1
- data/lib/mobile_workflow.rb +5 -2
- metadata +21 -21
- data/app/models/concerns/mobile_workflow/displayable/steps/pie_chart.rb +0 -11
@@ -1,149 +1,156 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
template 'Gemfile.erb', 'Gemfile'
|
9
|
-
end
|
10
|
-
|
11
|
-
def procfiles
|
12
|
-
copy_file 'Procfile', 'Procfile'
|
13
|
-
copy_file 'Procfile.dev', 'Procfile.dev'
|
14
|
-
end
|
15
|
-
|
16
|
-
def rspec_generator
|
17
|
-
generate 'rspec:install'
|
18
|
-
end
|
19
|
-
|
20
|
-
def factory_bot
|
21
|
-
inject_into_file 'spec/rails_helper.rb', after: "RSpec.configure do |config|\n" do
|
22
|
-
"\tconfig.include FactoryBot::Syntax::Methods\n"
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MobileWorkflow
|
4
|
+
module Cli
|
5
|
+
class AppBuilder < Rails::AppBuilder
|
6
|
+
def readme
|
7
|
+
template 'README.md.erb', 'README.md'
|
23
8
|
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def migrate_db
|
27
|
-
rails_command("db:drop")
|
28
|
-
rails_command("db:create")
|
29
|
-
rails_command("db:migrate")
|
30
|
-
end
|
31
9
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
file 'app/assets/config/manifest.js', <<-CODE
|
36
|
-
//= link administrate/application.css
|
37
|
-
//= link administrate/application.js
|
38
|
-
CODE
|
39
|
-
|
40
|
-
file 'app/controllers/admin/application_controller.rb', <<-CODE
|
41
|
-
module Admin
|
42
|
-
class ApplicationController < Administrate::ApplicationController
|
43
|
-
http_basic_authenticate_with(name: ENV["ADMIN_USER"], password: ENV["ADMIN_PASSWORD"])
|
44
|
-
end
|
45
|
-
end
|
46
|
-
CODE
|
10
|
+
def gemfile
|
11
|
+
template 'Gemfile.erb', 'Gemfile'
|
12
|
+
end
|
47
13
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
rails_command 'active_storage:install'
|
53
|
-
copy_file 'storage.s3.yml', 'config/storage.yml'
|
54
|
-
gsub_file 'config/environments/production.rb', 'config.active_storage.service = :local', 'config.active_storage.service = :amazon'
|
55
|
-
end
|
56
|
-
|
57
|
-
def mobile_workflow_generator(open_api_spec_path)
|
58
|
-
copy_file open_api_spec_path, 'config/open_api_spec.json'
|
59
|
-
gen_opts = ""
|
60
|
-
gen_opts += "--doorkeeper_oauth" if options[:doorkeeper_oauth]
|
61
|
-
generate "mobile_workflow:install #{gen_opts}"
|
62
|
-
end
|
63
|
-
|
64
|
-
def format_source
|
65
|
-
`rufo .`
|
66
|
-
end
|
67
|
-
|
68
|
-
def generate_dot_env
|
69
|
-
admin_user = 'admin'
|
70
|
-
admin_password = SecureRandom.base64(12)
|
71
|
-
|
72
|
-
file '.env', <<-CODE
|
73
|
-
ADMIN_USER=#{admin_user}
|
74
|
-
ADMIN_PASSWORD=#{admin_password}
|
75
|
-
CODE
|
76
|
-
end
|
14
|
+
def procfiles
|
15
|
+
copy_file 'Procfile', 'Procfile'
|
16
|
+
copy_file 'Procfile.dev', 'Procfile.dev'
|
17
|
+
end
|
77
18
|
|
78
|
-
|
79
|
-
|
80
|
-
|
19
|
+
def rspec_generator
|
20
|
+
generate 'rspec:install'
|
21
|
+
end
|
81
22
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
23
|
+
def factory_bot
|
24
|
+
inject_into_file 'spec/rails_helper.rb', after: "RSpec.configure do |config|\n" do
|
25
|
+
"\tconfig.include FactoryBot::Syntax::Methods\n"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def migrate_db
|
30
|
+
rails_command('db:drop')
|
31
|
+
rails_command('db:create')
|
32
|
+
rails_command('db:migrate')
|
33
|
+
end
|
34
|
+
|
35
|
+
def administrate_generator
|
36
|
+
generate 'administrate:install'
|
37
|
+
|
38
|
+
file 'app/assets/config/manifest.js', <<~CODE
|
39
|
+
//= link administrate/application.css
|
40
|
+
//= link administrate/application.js
|
41
|
+
CODE
|
42
|
+
|
43
|
+
file 'app/controllers/admin/application_controller.rb', <<~CODE
|
44
|
+
module Admin
|
45
|
+
class ApplicationController < Administrate::ApplicationController
|
46
|
+
http_basic_authenticate_with(name: ENV["ADMIN_USER"], password: ENV["ADMIN_PASSWORD"])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
CODE
|
50
|
+
|
51
|
+
generate 'administrate:routes'
|
52
|
+
end
|
53
|
+
|
54
|
+
def active_storage
|
55
|
+
rails_command 'active_storage:install'
|
56
|
+
copy_file 'storage.s3.yml', 'config/storage.yml'
|
57
|
+
gsub_file 'config/environments/production.rb', 'config.active_storage.service = :local',
|
58
|
+
'config.active_storage.service = :amazon'
|
59
|
+
end
|
60
|
+
|
61
|
+
def mobile_workflow_generator(open_api_spec_path)
|
62
|
+
copy_file open_api_spec_path, 'config/open_api_spec.json'
|
63
|
+
gen_opts = ''
|
64
|
+
gen_opts += '--doorkeeper_oauth' if options[:doorkeeper_oauth]
|
65
|
+
generate "mobile_workflow:install #{gen_opts}"
|
66
|
+
end
|
67
|
+
|
68
|
+
def format_source
|
69
|
+
`rufo .`
|
70
|
+
end
|
71
|
+
|
72
|
+
def generate_dot_env
|
73
|
+
admin_user = 'admin'
|
74
|
+
admin_password = SecureRandom.base64(12)
|
75
|
+
|
76
|
+
file '.env', <<~CODE
|
77
|
+
ADMIN_USER=#{admin_user}
|
78
|
+
ADMIN_PASSWORD=#{admin_password}
|
79
|
+
CODE
|
80
|
+
end
|
81
|
+
|
82
|
+
def rubocop
|
83
|
+
copy_file '.rubocop.yml'
|
84
|
+
command = 'rubocop --auto-gen-config'
|
85
|
+
|
86
|
+
puts "Running: #{command}"
|
87
|
+
output = `#{command}`
|
88
|
+
puts "Output: #{output}"
|
89
|
+
end
|
90
|
+
|
91
|
+
def simplecov
|
92
|
+
append_to_file 'spec/rails_helper.rb',
|
93
|
+
"\n# Config for Test Coverage\nrequire 'simplecov'\nSimpleCov.start\nSimpleCov.minimum_coverage 80\n"
|
94
|
+
append_to_file '.gitignore', "\n# Ignore test coverage reports\n/coverage\n"
|
95
|
+
end
|
96
|
+
|
97
|
+
def rollbar
|
98
|
+
generate 'rollbar'
|
99
|
+
gsub_file 'config/initializers/rollbar.rb', 'if Rails.env.test?', 'if Rails.env.test? || Rails.env.development?'
|
100
|
+
copy_file 'config/initializers/mobile_workflow_rollbar.rb'
|
101
|
+
gsub_file 'app/jobs/application_job.rb', 'class ApplicationJob < ActiveJob::Base',
|
102
|
+
"class ApplicationJob < ActiveJob::Base\n include Rollbar::ActiveJob\n"
|
103
|
+
end
|
104
|
+
|
105
|
+
def git_commit(message = 'Initial commit')
|
106
|
+
git add: '.'
|
107
|
+
git commit: %( -m '#{message}')
|
108
|
+
end
|
109
|
+
|
110
|
+
def s3_backend(region)
|
111
|
+
@region = region
|
112
|
+
aws_backend.create!
|
113
|
+
aws_backend.write_env
|
114
|
+
|
115
|
+
if options[:heroku]
|
116
|
+
heroku_backend.sync_dotenv
|
117
|
+
sleep 10 # Wait for the server to restart
|
118
|
+
aws_backend.create_topic_subscription(heroku_backend.notifications_endpoint)
|
119
|
+
elsif options[:dokku]
|
120
|
+
dokku_backend.sync_dotenv
|
121
|
+
aws_backend.create_topic_subscription(dokku_backend.notifications_endpoint)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def heroku
|
126
|
+
heroku_backend.create!
|
127
|
+
heroku_backend.configure_activestorage if options[:s3_storage]
|
128
|
+
heroku_backend.deploy
|
129
|
+
heroku_backend.seed_db
|
110
130
|
heroku_backend.sync_dotenv
|
111
|
-
sleep 10 # Wait for the server to restart
|
112
|
-
aws_backend.create_topic_subscription(heroku_backend.notifications_endpoint)
|
113
|
-
elsif options[:dokku]
|
114
|
-
dokku_backend.sync_dotenv
|
115
|
-
aws_backend.create_topic_subscription(dokku_backend.notifications_endpoint)
|
116
131
|
end
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
dokku_backend
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
end
|
140
|
-
|
141
|
-
def dokku_backend
|
142
|
-
@dokku_backend ||= DokkuBackend.new(app_name: app_name, dokku_host: @dokku_host)
|
143
|
-
end
|
144
|
-
|
145
|
-
def heroku_backend
|
146
|
-
@heroku_backend ||= HerokuBackend.new(app_name: app_name)
|
132
|
+
|
133
|
+
def dokku(dokku_host)
|
134
|
+
@dokku_host = dokku_host
|
135
|
+
dokku_backend.create!
|
136
|
+
dokku_backend.configure_activestorage if options[:s3_storage]
|
137
|
+
dokku_backend.deploy
|
138
|
+
dokku_backend.sync_dotenv
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
def aws_backend
|
144
|
+
@aws_backend ||= AwsBackend.new(app_name: app_name, region: @region)
|
145
|
+
end
|
146
|
+
|
147
|
+
def dokku_backend
|
148
|
+
@dokku_backend ||= DokkuBackend.new(app_name: app_name, dokku_host: @dokku_host)
|
149
|
+
end
|
150
|
+
|
151
|
+
def heroku_backend
|
152
|
+
@heroku_backend ||= HerokuBackend.new(app_name: app_name)
|
153
|
+
end
|
147
154
|
end
|
148
155
|
end
|
149
|
-
end
|
156
|
+
end
|
@@ -1,24 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rails/generators'
|
2
4
|
require 'rails/generators/rails/app/app_generator'
|
3
5
|
require 'json'
|
4
6
|
require 'active_support/core_ext/hash/indifferent_access'
|
5
7
|
|
6
|
-
module MobileWorkflow
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
module MobileWorkflow
|
9
|
+
module Cli
|
10
|
+
class AppServerCleaner < Thor
|
11
|
+
class_option :version, type: :boolean, aliases: '-v', desc: 'Show version number and quit'
|
12
|
+
class_option :help, type: :boolean, aliases: '-h', desc: 'Show this help message and quit'
|
13
|
+
|
14
|
+
class_option :heroku, type: :boolean, default: false, desc: 'Clean Heroku app'
|
15
|
+
class_option :s3_storage, type: :boolean, default: false,
|
16
|
+
desc: 'Clean an s3 backend for attachment upload and storage'
|
17
|
+
class_option :aws_region, type: :string, default: 'us-east-1', desc: 'Specify a region to create AWS resources in'
|
14
18
|
|
15
|
-
|
19
|
+
default_task :clean
|
16
20
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
desc 'rails destroy:app_server APP_NAME', 'Destroy App server'
|
22
|
+
def clean(app_name)
|
23
|
+
`rm -rf #{app_name}`
|
24
|
+
AwsBackend.new(app_name: app_name, region: options[:aws_region]).destroy! if options[:s3_storage]
|
25
|
+
HerokuBackend.new(app_name: app_name).destroy! if options[:heroku]
|
26
|
+
end
|
22
27
|
end
|
23
28
|
end
|
24
29
|
end
|
@@ -1,60 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rails/generators'
|
2
4
|
require 'rails/generators/rails/app/app_generator'
|
3
5
|
require 'json'
|
4
6
|
require 'active_support/core_ext/hash/indifferent_access'
|
5
7
|
|
6
|
-
module MobileWorkflow
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
def self.banner
|
28
|
-
"mwf rails create:app_server <directory> <OpenAPI Spec file path> [options]"
|
29
|
-
end
|
8
|
+
module MobileWorkflow
|
9
|
+
module Cli
|
10
|
+
class AppServerGenerator < Rails::Generators::AppGenerator
|
11
|
+
hide!
|
12
|
+
class_option :skip_test, type: :boolean, default: true, desc: 'Skip Test Unit'
|
13
|
+
class_option :force, type: :boolean, default: true, desc: 'Force overwrite'
|
14
|
+
class_option :skip_webpack_install, type: :boolean, default: true, desc: 'Skip webpacker installation'
|
15
|
+
class_option :skip_bootsnap, type: :boolean, default: true, desc: 'Skip Bootsnap'
|
16
|
+
|
17
|
+
class_option :version, type: :boolean, aliases: '-v', desc: 'Show version number and quit'
|
18
|
+
class_option :help, type: :boolean, aliases: '-h', desc: 'Show this help message and quit'
|
19
|
+
|
20
|
+
class_option :heroku, type: :boolean, default: false, desc: 'Create Heroku app'
|
21
|
+
|
22
|
+
class_option :dokku, type: :boolean, default: false, desc: 'Create Dokku app'
|
23
|
+
class_option :dokku_host, type: :string, desc: 'Specify the Dokku host machine e.g. 18.131.127.164'
|
24
|
+
|
25
|
+
class_option :s3_storage, type: :boolean, default: false,
|
26
|
+
desc: 'Create an s3 backend for attachment upload and storage'
|
27
|
+
class_option :aws_region, type: :string, default: 'us-east-1', desc: 'Specify a region to create AWS resources in'
|
30
28
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
build :rspec_generator
|
36
|
-
build :factory_bot
|
37
|
-
build :simplecov
|
38
|
-
build :rollbar
|
39
|
-
build :active_storage if options[:s3_storage]
|
40
|
-
build :mobile_workflow_generator, ARGV[1]
|
41
|
-
build :migrate_db
|
42
|
-
build :administrate_generator
|
43
|
-
build :format_source
|
44
|
-
build :generate_dot_env
|
45
|
-
build :rubocop
|
46
|
-
build :git_commit
|
47
|
-
build :heroku if options[:heroku]
|
48
|
-
build :dokku, options[:dokku_host] if options[:dokku]
|
49
|
-
build :s3_backend, options[:aws_region] if options[:s3_storage]
|
29
|
+
class_option :doorkeeper_oauth, type: :boolean, default: false, desc: 'Use Doorkeeper gem for OAuth login'
|
30
|
+
|
31
|
+
def self.banner
|
32
|
+
'mwf rails create:app_server <directory> <OpenAPI Spec file path> [options]'
|
50
33
|
end
|
51
|
-
end
|
52
|
-
|
53
|
-
protected
|
54
34
|
|
55
|
-
|
56
|
-
|
35
|
+
def finish_template
|
36
|
+
super
|
37
|
+
after_bundle do
|
38
|
+
build :procfiles
|
39
|
+
build :rspec_generator
|
40
|
+
build :factory_bot
|
41
|
+
build :simplecov
|
42
|
+
build :rollbar
|
43
|
+
build :active_storage if options[:s3_storage]
|
44
|
+
build :mobile_workflow_generator, ARGV[1]
|
45
|
+
build :migrate_db
|
46
|
+
build :administrate_generator
|
47
|
+
build :format_source
|
48
|
+
build :generate_dot_env
|
49
|
+
build :rubocop
|
50
|
+
build :git_commit
|
51
|
+
build :heroku if options[:heroku]
|
52
|
+
build :dokku, options[:dokku_host] if options[:dokku]
|
53
|
+
build :s3_backend, options[:aws_region] if options[:s3_storage]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
protected
|
58
|
+
|
59
|
+
def get_builder_class
|
60
|
+
::MobileWorkflow::Cli::AppBuilder
|
61
|
+
end
|
57
62
|
end
|
58
|
-
|
59
63
|
end
|
60
64
|
end
|
@@ -1,80 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'json'
|
2
4
|
|
3
|
-
module MobileWorkflow
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
def bucket_name
|
15
|
-
@aws_name
|
16
|
-
end
|
17
|
-
|
18
|
-
def create
|
19
|
-
bucket_configuration = ''
|
20
|
-
bucket_configuration += "--create-bucket-configuration LocationConstraint=#{@region}" unless @region.eql? 'us-east-1'
|
21
|
-
aws_command "aws s3api create-bucket --bucket #{@aws_name} --acl private --region #{@region} #{bucket_configuration}"
|
22
|
-
@topic_arn = aws_command("aws sns create-topic --name #{@aws_name} --region #{@region}")["TopicArn"]
|
23
|
-
aws_command "aws iam create-user --user-name #{@aws_name}"
|
24
|
-
aws_command "aws iam put-user-policy --user-name #{@aws_name} --policy-name s3 --policy-document '{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":[\"s3:PutObject\",\"s3:PutObjectAcl\",\"s3:GetObject\", \"s3:DeleteObject\"],\"Resource\":[\"arn:aws:s3:::#{@aws_name}/*\"]}, {\"Effect\": \"Allow\", \"Action\": \"s3:ListBucket\", \"Resource\": \"arn:aws:s3:::#{@aws_name}\"}]}'"
|
25
|
-
aws_command "aws iam put-user-policy --user-name #{@aws_name} --policy-name sns --policy-document '{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":[\"sns:ConfirmSubscription\"],\"Resource\":[\"#{@topic_arn}\"]}]}'"
|
26
|
-
aws_command "aws sns set-topic-attributes --topic-arn #{@topic_arn} --region #{@region} --attribute-name Policy --attribute-value '{\"Version\": \"2012-10-17\", \"Id\": \"s3\", \"Statement\": [{\"Sid\": \"#{@aws_name}-s3-sid\", \"Effect\": \"Allow\", \"Principal\": {\"AWS\": \"*\"}, \"Action\": \"SNS:Publish\", \"Resource\": \"#{@topic_arn}\", \"Condition\": {\"ArnEquals\": {\"aws:SourceArn\": \"arn:aws:s3:::#{@aws_name}\"}}}]}'"
|
27
|
-
aws_command "aws s3api put-bucket-notification-configuration --bucket #{@aws_name} --notification-configuration '{\"TopicConfigurations\": [{\"TopicArn\": \"#{@topic_arn}\", \"Events\": [\"s3:ObjectCreated:*\"]}]}'"
|
28
|
-
aws_credentials_json = aws_command("aws iam create-access-key --user-name #{@aws_name}")["AccessKey"]
|
29
|
-
@access_id, @secret_key = aws_credentials_json["AccessKeyId"], aws_credentials_json["SecretAccessKey"]
|
30
|
-
return @access_id, @secret_key
|
31
|
-
end
|
32
|
-
|
33
|
-
def put_env
|
34
|
-
puts "AWS_ACCESS_ID=#{access_id}"
|
35
|
-
puts "AWS_SECRET_KEY=#{secret_key}"
|
36
|
-
puts "AWS_REGION=#{region}"
|
37
|
-
puts "AWS_BUCKET_NAME=#{bucket_name}"
|
38
|
-
end
|
39
|
-
|
40
|
-
def write_env
|
41
|
-
open('.env', 'a') { |f|
|
42
|
-
f.puts "AWS_ACCESS_ID=#{access_id}"
|
43
|
-
f.puts "AWS_SECRET_KEY=#{secret_key}"
|
44
|
-
f.puts "AWS_REGION=#{region}"
|
45
|
-
f.puts "AWS_BUCKET_NAME=#{bucket_name}"
|
46
|
-
}
|
47
|
-
end
|
48
|
-
|
49
|
-
def create_topic_subscription(endpoint)
|
50
|
-
aws_command "aws sns subscribe --topic-arn #{@topic_arn} --region #{@region} --protocol https --notification-endpoint #{endpoint}"
|
51
|
-
end
|
52
|
-
|
53
|
-
def destroy
|
54
|
-
aws_command "aws s3api delete-bucket --bucket #{@aws_name} --region #{@region}"
|
55
|
-
|
56
|
-
aws_command("aws sns list-topics --region #{@region}")["Topics"].each do |topic|
|
57
|
-
topic_arn = topic["TopicArn"]
|
58
|
-
aws_command "aws sns delete-topic --topic-arn '#{topic_arn}' --region #{@region}" if topic_arn.end_with?(@aws_name)
|
5
|
+
module MobileWorkflow
|
6
|
+
module Cli
|
7
|
+
class AwsBackend
|
8
|
+
attr_accessor :access_id, :secret_key, :region, :bucket_name
|
9
|
+
|
10
|
+
def initialize(app_name:, region: 'us-east-1')
|
11
|
+
@app_name = app_name
|
12
|
+
@aws_name = @app_name.gsub('_', '-')
|
13
|
+
@region = region
|
59
14
|
end
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
15
|
+
|
16
|
+
def bucket_name
|
17
|
+
@aws_name
|
18
|
+
end
|
19
|
+
|
20
|
+
def create
|
21
|
+
bucket_configuration = ''
|
22
|
+
unless @region.eql? 'us-east-1'
|
23
|
+
bucket_configuration += "--create-bucket-configuration LocationConstraint=#{@region}"
|
24
|
+
end
|
25
|
+
aws_command "aws s3api create-bucket --bucket #{@aws_name} --acl private --region #{@region} #{bucket_configuration}"
|
26
|
+
@topic_arn = aws_command("aws sns create-topic --name #{@aws_name} --region #{@region}")['TopicArn']
|
27
|
+
aws_command "aws iam create-user --user-name #{@aws_name}"
|
28
|
+
aws_command "aws iam put-user-policy --user-name #{@aws_name} --policy-name s3 --policy-document '{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":[\"s3:PutObject\",\"s3:PutObjectAcl\",\"s3:GetObject\", \"s3:DeleteObject\"],\"Resource\":[\"arn:aws:s3:::#{@aws_name}/*\"]}, {\"Effect\": \"Allow\", \"Action\": \"s3:ListBucket\", \"Resource\": \"arn:aws:s3:::#{@aws_name}\"}]}'"
|
29
|
+
aws_command "aws iam put-user-policy --user-name #{@aws_name} --policy-name sns --policy-document '{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":[\"sns:ConfirmSubscription\"],\"Resource\":[\"#{@topic_arn}\"]}]}'"
|
30
|
+
aws_command "aws sns set-topic-attributes --topic-arn #{@topic_arn} --region #{@region} --attribute-name Policy --attribute-value '{\"Version\": \"2012-10-17\", \"Id\": \"s3\", \"Statement\": [{\"Sid\": \"#{@aws_name}-s3-sid\", \"Effect\": \"Allow\", \"Principal\": {\"AWS\": \"*\"}, \"Action\": \"SNS:Publish\", \"Resource\": \"#{@topic_arn}\", \"Condition\": {\"ArnEquals\": {\"aws:SourceArn\": \"arn:aws:s3:::#{@aws_name}\"}}}]}'"
|
31
|
+
aws_command "aws s3api put-bucket-notification-configuration --bucket #{@aws_name} --notification-configuration '{\"TopicConfigurations\": [{\"TopicArn\": \"#{@topic_arn}\", \"Events\": [\"s3:ObjectCreated:*\"]}]}'"
|
32
|
+
aws_credentials_json = aws_command("aws iam create-access-key --user-name #{@aws_name}")['AccessKey']
|
33
|
+
@access_id = aws_credentials_json['AccessKeyId']
|
34
|
+
@secret_key = aws_credentials_json['SecretAccessKey']
|
35
|
+
[@access_id, @secret_key]
|
36
|
+
end
|
37
|
+
|
38
|
+
def put_env
|
39
|
+
puts "AWS_ACCESS_ID=#{access_id}"
|
40
|
+
puts "AWS_SECRET_KEY=#{secret_key}"
|
41
|
+
puts "AWS_REGION=#{region}"
|
42
|
+
puts "AWS_BUCKET_NAME=#{bucket_name}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def write_env
|
46
|
+
open('.env', 'a') do |f|
|
47
|
+
f.puts "AWS_ACCESS_ID=#{access_id}"
|
48
|
+
f.puts "AWS_SECRET_KEY=#{secret_key}"
|
49
|
+
f.puts "AWS_REGION=#{region}"
|
50
|
+
f.puts "AWS_BUCKET_NAME=#{bucket_name}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def create_topic_subscription(endpoint)
|
55
|
+
aws_command "aws sns subscribe --topic-arn #{@topic_arn} --region #{@region} --protocol https --notification-endpoint #{endpoint}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def destroy
|
59
|
+
aws_command "aws s3api delete-bucket --bucket #{@aws_name} --region #{@region}"
|
60
|
+
|
61
|
+
aws_command("aws sns list-topics --region #{@region}")['Topics'].each do |topic|
|
62
|
+
topic_arn = topic['TopicArn']
|
63
|
+
if topic_arn.end_with?(@aws_name)
|
64
|
+
aws_command "aws sns delete-topic --topic-arn '#{topic_arn}' --region #{@region}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
aws_command "aws iam delete-user-policy --user-name #{@aws_name} --policy-name s3"
|
69
|
+
aws_command "aws iam delete-user-policy --user-name #{@aws_name} --policy-name sns"
|
70
|
+
aws_command("aws iam list-access-keys --user-name #{@aws_name}")['AccessKeyMetadata'].each do |accessKeyMetadata|
|
71
|
+
aws_command "aws iam delete-access-key --user-name #{@aws_name} --access-key #{accessKeyMetadata['AccessKeyId']}"
|
72
|
+
end
|
73
|
+
aws_command "aws iam delete-user --user-name #{@aws_name}"
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def aws_command(command)
|
79
|
+
puts "Running: #{command}"
|
80
|
+
output = `#{command}`
|
81
|
+
return nil if output.nil? || output.strip == ''
|
82
|
+
|
83
|
+
puts "Output: #{output}"
|
84
|
+
JSON.parse(output)
|
65
85
|
end
|
66
|
-
aws_command "aws iam delete-user --user-name #{@aws_name}"
|
67
|
-
end
|
68
|
-
|
69
|
-
private
|
70
|
-
def aws_command(command)
|
71
|
-
puts "Running: #{command}"
|
72
|
-
output = `#{command}`
|
73
|
-
return nil if output == nil || output.strip == ""
|
74
|
-
|
75
|
-
puts "Output: #{output}"
|
76
|
-
JSON.parse(output)
|
77
86
|
end
|
78
|
-
|
79
87
|
end
|
80
|
-
end
|
88
|
+
end
|