naifa 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1329fb6a9bb4e66cdda6324051f3e96db9c580a4
4
- data.tar.gz: 728f6f2db1382efb334a7401735d7612b8628f1f
3
+ metadata.gz: b7dd8770b81f31bf68ccefd8075c47684e96e673
4
+ data.tar.gz: 83d07884667956748f511303493df74252d1f69b
5
5
  SHA512:
6
- metadata.gz: 5d5bd7b6421a6c83d74dae4f4dc4c5c13717e7b4fb6e87531ee4398d72e688f8296acaaac693052aeb214230825beedaaea3cb292b1442faffa7c411932107db
7
- data.tar.gz: a6767db22a22bdc2bfe3bf3c9e5f600520e854a6b97aef24ab5516b0f7d7dd5db5d5192eb44b87ef217af9a30eab59de88a26364edb843efb4b2fa0179caad52
6
+ metadata.gz: 16f3c9bbbde9428b2687903b42652d49ce459999d3b33718787292446c0dd939f7b0fa84988bf164731313b6a43d4c5086e83e3ba28154385ee612b6dcabf363
7
+ data.tar.gz: 796136b7e1980256f88b147e0b92acd52e09b796a988c35690d8efd059f66a9c5db2085eca5ed6fcd5e2e14197534c94b1cf06ceb701c5379b8c1f0e9c640272
data/README.md CHANGED
@@ -34,79 +34,104 @@ You should now update some of the settings to meet your app configurations.
34
34
 
35
35
  The .naifa file contains settings that will have an influence in the available command options.
36
36
 
37
- The current default settings are the following:
37
+ The current default generated settings are the following:
38
38
  ```
39
39
  ---
40
- version: 1.0
40
+ version: 1.1
41
41
  db:
42
42
  plugin: :postgres
43
43
  settings:
44
44
  filename: db_backup
45
- backup:
46
- path: "./data/db_dumps"
47
- db_name: ''
48
- environment: :staging
45
+ path: "./data/db_dumps"
46
+ environments:
49
47
  production:
50
48
  type: :heroku
49
+ remote: production
51
50
  staging:
52
51
  type: :heroku
52
+ remote: staging
53
53
  development:
54
54
  type: :docker
55
55
  app_name: db
56
56
  database: ''
57
57
  username: "\\$POSTGRES_USER"
58
58
  path: "/db_dumps/"
59
+ backup:
60
+ environment: :staging
59
61
  restore:
60
- path: "./data/db_dumps"
61
62
  environment: :development
63
+ s3:
64
+ plugin: :s3
65
+ settings:
66
+ environments:
67
+ production:
68
+ bucket: s3://production_bucket_name/
62
69
  staging:
63
- type: :heroku
70
+ bucket: s3://staging_bucket_name/
64
71
  development:
65
- type: :docker
66
- app_name: db
67
- database: ''
68
- username: "\\$POSTGRES_USER"
69
- path: "/db_dumps/"
72
+ bucket: s3://development_bucket_name/
73
+ sync:
74
+ origin: :staging
75
+ destination: :development
76
+ sync_options:
77
+ - "--delete"
78
+ - "--acl public-read"
70
79
  ```
71
80
 
72
81
  Taking this into account, you'll be able to run the following commands
73
82
 
74
- ### sync
83
+ ### postgres sync
75
84
 
76
85
  ```
77
- $ naifa sync db
86
+ $ naifa db sync
78
87
  ```
79
88
 
80
89
  This will sync your staging postgres db in heroku to your development postgres in docker
81
90
 
82
91
  ```
83
- $ naifa sync db production
92
+ $ naifa db sync production
84
93
  ```
85
94
 
86
95
  This will sync your production postgres db in heroku to your development postgres in docker
87
96
 
88
- ### backup
97
+ ### postgres backup
89
98
 
90
99
  ```
91
- $ naifa backup db
100
+ $ naifa db backup
92
101
  ```
93
102
 
94
103
  This will backup your staging postgres db in heroku to './data/db_dumps/db_backup'
95
104
 
96
105
  ```
97
- $ naifa backup db production
106
+ $ naifa db backup production
98
107
  ```
99
108
 
100
109
  This will backup your postgres postgres db in heroku to './data/db_dumps/db_backup'
101
110
 
102
- ### restore
111
+ ### postgres restore
103
112
 
104
113
  ```
105
- $ naifa restore db
114
+ $ naifa db restore
106
115
  ```
107
116
 
108
117
  This will restore the backup in './data/db_dumps/db_backup' to your development postgres
109
118
 
119
+ ### s3 sync
120
+
121
+ ```
122
+ $ naifa s3 sync
123
+ ```
124
+
125
+ This will sync your staging s3 bucket with your development s3 bucket
126
+
127
+ ```
128
+ $ naifa s3 sync production staging
129
+ ```
130
+
131
+ This will sync your production s3 bucket with your staging s3 bucket
132
+
133
+ NOTE: sync_options allow you to specify [aws s3 sync](http://docs.aws.amazon.com/cli/latest/reference/s3/sync.html) command options.
134
+
110
135
  ## Advanced
111
136
 
112
137
  Imagine that you have 2 databases with different settings and configurations
@@ -114,78 +139,68 @@ You can update you configuration file by adding another entry like in the exampl
114
139
 
115
140
  ```
116
141
  ---
117
- version: 1.0
142
+ version: 1.1
118
143
  db:
119
144
  plugin: :postgres
120
145
  settings:
121
146
  filename: db_backup
122
- backup:
123
- path: "./data/db_dumps"
124
- db_name: ''
125
- environment: :staging
147
+ path: "./data/db_dumps"
148
+ environments:
126
149
  production:
127
150
  type: :heroku
151
+ remote: production
128
152
  staging:
129
153
  type: :heroku
154
+ remote: staging
130
155
  development:
131
156
  type: :docker
132
157
  app_name: db
133
- database: dev_db
158
+ database: ''
134
159
  username: "\\$POSTGRES_USER"
135
160
  path: "/db_dumps/"
161
+ backup:
162
+ environment: :staging
136
163
  restore:
137
- path: "./data/db_dumps"
138
164
  environment: :development
139
- staging:
140
- type: :heroku
141
- development:
142
- type: :docker
143
- app_name: db
144
- database: dev_db
145
- username: "\\$POSTGRES_USER"
146
- path: "/db_dumps/"
147
165
  db_local:
148
166
  plugin: :postgres
149
167
  settings:
150
168
  filename: db_backup
151
- backup:
152
- path: "./data/db_dumps"
153
- db_name: ''
154
- environment: :staging
169
+ path: "./data/db_dumps"
170
+ environments:
155
171
  production:
156
172
  type: :heroku
173
+ remote: production
157
174
  staging:
158
175
  type: :heroku
176
+ remote: staging
159
177
  development:
160
178
  type: :local
161
179
  database: dev_db1
162
- username: postgres
180
+ username: "\\$POSTGRES_USER"
181
+ password: pass
182
+ path: "/db_dumps/"
183
+ backup:
184
+ environment: :staging
163
185
  restore:
164
- path: "./data/db_dumps"
165
186
  environment: :development
166
- staging:
167
- type: :heroku
168
- development:
169
- type: :local
170
- database: dev_db1
171
- username: postgres
172
187
  ```
173
188
 
174
189
  This configuration will allow you to run the commands like this:
175
190
 
176
191
  ```
177
- $ naifa sync db
178
- $ naifa sync db_local
192
+ $ naifa db sync
193
+ $ naifa db_local sync
179
194
  ```
180
195
 
181
196
  ## Roadmap
182
197
 
183
198
  * Add tests
184
199
  * Add documentation
185
- * Add AWS S3 sync between environments
200
+ * -Add AWS S3 sync between environments-
186
201
  * Add MySQL sync, backup and restore
187
202
  * Add MongoDB sync, backup and restore
188
- * Rethink the commands to more dynamic depending on the plugin
203
+ * -Rethink the commands to more dynamic depending on the plugin-
189
204
  * Add logs and better error handling
190
205
 
191
206
  ## Development
data/lib/naifa/cli.rb CHANGED
@@ -1,46 +1,28 @@
1
1
  module Naifa
2
2
  require 'thor'
3
- class CLI < Thor
4
-
5
- desc "init <filename>", "Initializes <filename=.naifa> config file with all default settings"
6
- def init(filename='.naifa')
7
- File.write(filename, Naifa::Config.generate_full_default_settings.to_h.to_yaml)
8
- end
9
-
10
- desc "sync <what> <from> <to>", "Syncs <what> from <from> to <to>"
11
- def sync(what, from=nil, to=nil)
12
- what_config = Naifa::Config.settings[what.to_sym] || {}
13
3
 
14
- options = {backup: {}, restore: {}}
15
- options[:backup][:environment] = from unless from.nil?
16
- options[:restore][:environment] = to unless to.nil?
17
-
18
- case what_config[:plugin]
19
- when :postgres
20
- Naifa::Postgres.sync(what_config.fetch(:settings,{}).deep_merge(options))
21
- end
4
+ module PluginsCLI
5
+ Naifa::Config.settings.each do |sub_comm, settings|
6
+ class_eval <<-EORUBY
7
+ class #{sub_comm.to_s.capitalize} < #{Naifa::Plugins::registry[settings[:plugin]][:cli].to_s}
8
+ @settings_key = :#{sub_comm}
9
+ end
10
+ EORUBY
22
11
  end
12
+ end
23
13
 
24
- desc "backup <what> <from>", "Backup <what> from <from>"
25
- def backup(what, from=nil)
26
- what_config = Naifa::Config.settings[what.to_sym] || {}
27
- options = from.nil? ? {} : {backup: {environment: from}}
14
+ class CLI < Thor
28
15
 
29
- case what_config[:plugin]
30
- when :postgres
31
- Naifa::Postgres.backup(what_config.fetch(:settings,{}).deep_merge(options))
32
- end
16
+ desc "init <filename>", "Initializes <filename=.naifa> config file with all default settings"
17
+ def init(filename='.naifa')
18
+ File.write(filename, Naifa::Config.generate_example_settings.to_h.to_yaml)
33
19
  end
34
20
 
35
- desc "restore <what> <to>", "Restore <what> to <to>"
36
- def restore(what, to=nil)
37
- what_config = Naifa::Config.settings[what.to_sym] || {}
38
- options = to.nil? ? {} : {restore: {environment: to}}
39
-
40
- case what_config[:plugin]
41
- when :postgres
42
- Naifa::Postgres.restore(what_config.fetch(:settings,{}).deep_merge(options))
43
- end
21
+ Naifa::Config.settings.each do |sub_comm, settings|
22
+ class_eval <<-EORUBY
23
+ desc "#{sub_comm} SUBCOMMAND ...ARGS", "#{Naifa::Plugins::registry[settings[:plugin]][:description].to_s}"
24
+ subcommand "#{sub_comm}", PluginsCLI::#{sub_comm.to_s.capitalize}
25
+ EORUBY
44
26
  end
45
27
  end
46
28
  end
data/lib/naifa/config.rb CHANGED
@@ -3,27 +3,31 @@ module Naifa
3
3
  require 'yaml'
4
4
  require 'active_support/core_ext/hash/indifferent_access'
5
5
 
6
- SETTINGS_VERSION = 1.0
6
+ SETTINGS_VERSION = 1.1
7
7
  DEFAULT_SETTINGS = {
8
8
  db: {
9
9
  :plugin => :postgres
10
+ },
11
+ s3: {
12
+ :plugin => :s3
10
13
  }
11
14
  }.with_indifferent_access.freeze
12
15
 
13
16
  def self.settings
14
17
  @settings ||= begin
15
18
  loaded_settings = YAML.load(File.read('.naifa')).with_indifferent_access if File.exists?('.naifa')
16
- if !loaded_settings.nil? && loaded_settings[:version] != SETTINGS_VERSION
19
+ if !loaded_settings.nil? && loaded_settings.delete(:version) != SETTINGS_VERSION
17
20
  raise 'Configuration file version is not supported. Please upgrade!'
18
21
  end
19
22
  loaded_settings
20
- end || DEFAULT_SETTINGS
23
+ end || {}
21
24
  end
22
25
 
23
- def self.generate_full_default_settings
26
+ def self.generate_example_settings
24
27
  full_settings = {'version' => SETTINGS_VERSION}.with_indifferent_access
25
28
  .merge(DEFAULT_SETTINGS)
26
- full_settings[:db][:settings] = Naifa::Postgres::DEFAULT_SETTINGS
29
+ full_settings[:db][:settings] = Naifa::Plugins::Postgres::DEFAULT_SETTINGS
30
+ full_settings[:s3][:settings] = Naifa::Plugins::S3::DEFAULT_SETTINGS
27
31
  full_settings.to_hash
28
32
  end
29
33
 
data/lib/naifa/heroku.rb CHANGED
@@ -9,9 +9,7 @@ module Naifa
9
9
  end
10
10
 
11
11
  def self.sync(from=:production, to=:staging)
12
- puts "Heroku Sync from: #{from} to: #{to}"
13
12
  res = capture(from)
14
- # puts build_restore_command("`#{build_public_url_command(from)}`", to)
15
13
  Kernel.system(build_restore_command("`#{build_public_url_command(from)}`", to)) if res
16
14
  end
17
15
 
@@ -0,0 +1,47 @@
1
+ module Naifa
2
+ module Plugins
3
+ class Postgres
4
+ require 'thor'
5
+
6
+ class CLI < Thor
7
+ @settings_key = nil
8
+ class << self
9
+ attr_reader :settings_key
10
+ end
11
+
12
+ desc "sync <from> <to>", "Syncs from <from> to <to>"
13
+ def sync(from=nil, to=nil)
14
+ config = Naifa::Config.settings[settings_key] || {}
15
+
16
+ options = {backup: {}, restore: {}}
17
+ options[:backup][:environment] = from unless from.nil?
18
+ options[:restore][:environment] = to unless to.nil?
19
+
20
+ Postgres.sync(config.fetch(:settings,{}).deep_merge(options))
21
+ end
22
+
23
+ desc "backup <from>", "Backup from <from>"
24
+ def backup(from=nil)
25
+ config = Naifa::Config.settings[settings_key] || {}
26
+ options = from.nil? ? {} : {backup: {environment: from}}
27
+
28
+ Postgres.backup(config.fetch(:settings,{}).deep_merge(options))
29
+ end
30
+
31
+ desc "restore <to>", "Restore to <to>"
32
+ def restore(to=nil)
33
+ config = Naifa::Config.settings[settings_key] || {}
34
+ options = to.nil? ? {} : {restore: {environment: to}}
35
+
36
+ Postgres.restore(config.fetch(:settings,{}).deep_merge(options))
37
+ end
38
+
39
+ no_commands do
40
+ def settings_key
41
+ self.class.settings_key
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,70 @@
1
+ module Naifa
2
+ module Plugins
3
+ class Postgres
4
+ DEFAULT_FILENAME = 'db_backup'.freeze
5
+ DEFAULT_SETTINGS = {
6
+ filename: DEFAULT_FILENAME,
7
+ path: './data/db_dumps',
8
+ environments: {
9
+ production: {
10
+ type: :heroku,
11
+ remote: 'production'
12
+ },
13
+ staging: {
14
+ type: :heroku,
15
+ remote: 'staging'
16
+ },
17
+ development: {
18
+ type: :docker,
19
+ app_name: 'db',
20
+ database: '',
21
+ username: '\$POSTGRES_USER',
22
+ path: '/db_dumps/'
23
+ }
24
+ },
25
+ backup: {
26
+ environment: :staging
27
+ },
28
+ restore: {
29
+ environment: :development
30
+ }
31
+ }.with_indifferent_access.freeze
32
+
33
+ # DEFAULT_SETTINGS = {
34
+ # filename: DEFAULT_FILENAME,
35
+ # backup: {
36
+ # path: './data/db_dumps',
37
+ # db_name: '',
38
+ # environment: :staging,
39
+ # production: {
40
+ # type: :heroku
41
+ # },
42
+ # staging: {
43
+ # type: :heroku
44
+ # },
45
+ # development: {
46
+ # type: :docker,
47
+ # app_name: 'db',
48
+ # database: '',
49
+ # username: '\$POSTGRES_USER',
50
+ # path: '/db_dumps/'
51
+ # }
52
+ # },
53
+ # restore: {
54
+ # path: './data/db_dumps',
55
+ # environment: :development,
56
+ # staging: {
57
+ # type: :heroku
58
+ # },
59
+ # development: {
60
+ # type: :docker,
61
+ # app_name: 'db',
62
+ # database: '',
63
+ # username: '\$POSTGRES_USER',
64
+ # path: '/db_dumps/'
65
+ # }
66
+ # }
67
+ # }.with_indifferent_access.freeze
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,240 @@
1
+ module Naifa
2
+
3
+ module Plugins
4
+ class Postgres
5
+ require 'naifa/plugins/postgres/cli'
6
+ require 'naifa/plugins/postgres/settings'
7
+ require 'active_support'
8
+ require 'active_support/core_ext/hash/deep_merge'
9
+ require 'active_support/core_ext/object/blank'
10
+ require 'naifa/utils'
11
+
12
+ def self.restore(options={})
13
+ filename = options.fetch(:filename, DEFAULT_FILENAME)
14
+
15
+ _restore(filename, options)
16
+ end
17
+
18
+ def self.backup(options={})
19
+ filename = options.fetch(:filename, DEFAULT_FILENAME)
20
+
21
+ _backup(filename, options)
22
+ end
23
+
24
+ def self.sync(options={})
25
+ options ||= {}
26
+ filename = options.fetch(:filename, DEFAULT_FILENAME)
27
+
28
+ backup_settings = options.fetch(:backup, {})
29
+ restore_settings = options.fetch(:restore, {})
30
+ environments_settings = options.fetch(:environments, {})
31
+
32
+ if backup_settings[:environment].blank? ||
33
+ environments_settings[backup_settings[:environment]].blank? ||
34
+ restore_settings[:environment].blank? ||
35
+ environments_settings[restore_settings[:environment]].blank?
36
+
37
+ raise Thor::Error, "Sync (Backup and Restore) environments are not defined"
38
+ end
39
+
40
+ if environments_settings[backup_settings[:environment]][:type] == :heroku &&
41
+ environments_settings[restore_settings[:environment]][:type] == :heroku
42
+
43
+ Heroku::Postgres.sync(
44
+ environments_settings[backup_settings[:environment]][:remote].presence || backup_settings[:environment],
45
+ environments_settings[restore_settings[:environment]][:remote].presence || restore_settings[:environment]
46
+ )
47
+ else
48
+ _backup(filename, options)
49
+ _restore(filename, options)
50
+ end
51
+ end
52
+
53
+ def self._backup(filename, options={})
54
+ options ||= {}
55
+ backup_settings = options[:backup]
56
+ environments_settings = options[:environments]
57
+
58
+ if backup_settings[:environment].blank? ||
59
+ environments_settings[backup_settings[:environment]].blank?
60
+
61
+ raise Thor::Error, "Backup environment is not defined"
62
+ end
63
+
64
+ environment_settings = environments_settings[backup_settings[:environment]]
65
+
66
+ case environment_settings[:type]
67
+ when :remote
68
+ if environment_settings[:host].blank? ||
69
+ environment_settings[:username].blank? ||
70
+ environment_settings[:database].blank? ||
71
+ (environment_settings[:path].presence || options[:path].presence).blank?
72
+
73
+ raise Thor::Error, "Backup remote environment #{backup_settings[:environment]} is not correctly configured"
74
+ end
75
+
76
+ command_line = build_backup_command(
77
+ environment_settings[:host],
78
+ environment_settings[:username],
79
+ environment_settings[:database],
80
+ File.join(
81
+ environment_settings[:path].presence || options[:path].presence,
82
+ filename
83
+ )
84
+ )
85
+ Kernel.system(command_line)
86
+ when :local
87
+ if environment_settings[:username].blank? ||
88
+ environment_settings[:database].blank? ||
89
+ (environment_settings[:path].presence || options[:path].presence).blank?
90
+
91
+ raise Thor::Error, "Backup local environment #{backup_settings[:environment]} is not correctly configured"
92
+ end
93
+
94
+ command_line = build_backup_command(
95
+ 'localhost',
96
+ environment_settings[:username],
97
+ environment_settings[:database],
98
+ File.join(
99
+ environment_settings[:path].presence || options[:path].presence,
100
+ filename
101
+ )
102
+ )
103
+ Kernel.system(command_line)
104
+ when :heroku
105
+ if (environment_settings[:path].presence || options[:path].presence).blank?
106
+ raise Thor::Error, "Backup heroku environment #{backup_settings[:environment]} is not correctly configured"
107
+ end
108
+
109
+ Heroku::Postgres.backup(
110
+ File.join(
111
+ environment_settings[:path].presence || options[:path].presence,
112
+ filename
113
+ ),
114
+ environment_settings[:remote].presence || backup_settings[:environment]
115
+ )
116
+ when :docker
117
+ if environment_settings[:username].blank? ||
118
+ environment_settings[:database].blank? ||
119
+ (environment_settings[:path].presence || options[:path].presence).blank? ||
120
+ environment_settings[:app_name].blank?
121
+
122
+ raise Thor::Error, "Restore docker environment #{backup_settings[:environment]} is not correctly configured"
123
+ end
124
+
125
+ command_line = build_backup_command(
126
+ 'localhost',
127
+ environment_settings[:username],
128
+ environment_settings[:database],
129
+ File.join(
130
+ environment_settings[:path].presence || options[:path].presence,
131
+ filename
132
+ )
133
+ )
134
+ Utils.docker_compose_exec_command(
135
+ environment_settings[:app_name].presence,
136
+ command_line
137
+ )
138
+ else
139
+ raise Thor::Error, "Backup unsupported type"
140
+ end
141
+ end
142
+
143
+ private_class_method :_backup
144
+
145
+ def self._restore(filename, options={})
146
+ options ||= {}
147
+
148
+ restore_settings = options[:restore]
149
+ environments_settings = options[:environments]
150
+
151
+ if restore_settings[:environment].blank? ||
152
+ environments_settings[restore_settings[:environment]].blank?
153
+
154
+ raise Thor::Error, "Restore environment is not defined"
155
+ end
156
+
157
+ environment_settings = environments_settings[restore_settings[:environment]]
158
+
159
+ case environment_settings[:type]
160
+ when :remote
161
+ if environment_settings[:host].blank? ||
162
+ environment_settings[:username].blank? ||
163
+ environment_settings[:database].blank? ||
164
+ (environment_settings[:path].presence || options[:path].presence).blank?
165
+
166
+ raise Thor::Error, "Restore remote environment #{restore_settings[:environment]} is not correctly configured"
167
+ end
168
+
169
+ command_line = build_restore_command(
170
+ environment_settings[:host],
171
+ environment_settings[:username],
172
+ environment_settings[:database],
173
+ File.join(
174
+ environment_settings[:path].presence || options[:path].presence,
175
+ filename
176
+ )
177
+ )
178
+ Kernel.system(command_line)
179
+ when :local
180
+ if environment_settings[:username].blank? ||
181
+ environment_settings[:database].blank? ||
182
+ (environment_settings[:path].presence || options[:path].presence).blank?
183
+
184
+ raise Thor::Error, "Restore local environment #{restore_settings[:environment]} is not correctly configured"
185
+ end
186
+
187
+ command_line = build_restore_command(
188
+ 'localhost',
189
+ environment_settings[:username],
190
+ environment_settings[:database],
191
+ File.join(
192
+ environment_settings[:path] || options[:path],
193
+ filename
194
+ )
195
+ )
196
+ Kernel.system(command_line)
197
+ when :docker
198
+ if environment_settings[:username].blank? ||
199
+ environment_settings[:database].blank? ||
200
+ (environment_settings[:path].presence || options[:path].presence).blank? ||
201
+ environment_settings[:app_name].blank?
202
+
203
+ raise Thor::Error, "Restore docker environment #{restore_settings[:environment]} is not correctly configured"
204
+ end
205
+
206
+ command_line = build_restore_command(
207
+ 'localhost',
208
+ environment_settings[:username],
209
+ environment_settings[:database],
210
+ File.join(
211
+ environment_settings[:path].presence || options[:path].presence,
212
+ filename
213
+ )
214
+ )
215
+ Utils.docker_compose_exec_command(
216
+ environment_settings[:app_name],
217
+ command_line
218
+ )
219
+ else
220
+ raise Thor::Error, "Restore unsupported type"
221
+ end
222
+ end
223
+
224
+ private_class_method :_restore
225
+
226
+ def self.build_restore_command(host, username, database, filename)
227
+ "pg_restore --verbose --clean --no-acl --no-owner -h #{host} -U #{username} -d #{database} #{filename}"
228
+ end
229
+
230
+ private_class_method :build_restore_command
231
+
232
+ def self.build_backup_command(host, username, database, filename)
233
+ "pg_dump -Fc -h #{host} -U #{username} -d #{database} > #{filename}"
234
+ end
235
+
236
+ private_class_method :build_backup_command
237
+
238
+ end
239
+ end
240
+ end
@@ -0,0 +1,31 @@
1
+ module Naifa
2
+ module Plugins
3
+ class S3
4
+ require 'thor'
5
+
6
+ class CLI < Thor
7
+ @settings_key = nil
8
+ class << self
9
+ attr_reader :settings_key
10
+ end
11
+
12
+ desc "sync <from> <to>", "Syncs from <from> to <to>"
13
+ def sync(from=nil, to=nil)
14
+ config = Naifa::Config.settings[settings_key] || {}
15
+
16
+ options = {sync: {}}
17
+ options[:sync][:origin] = from unless from.nil?
18
+ options[:sync][:destination] = to unless to.nil?
19
+
20
+ S3.sync(config.fetch(:settings,{}).deep_merge(options))
21
+ end
22
+
23
+ no_commands do
24
+ def settings_key
25
+ self.class.settings_key
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,24 @@
1
+ module Naifa
2
+ module Plugins
3
+ class S3
4
+ DEFAULT_SETTINGS = {
5
+ environments: {
6
+ production: {
7
+ bucket: 's3://production_bucket_name/'
8
+ },
9
+ staging: {
10
+ bucket: 's3://staging_bucket_name/'
11
+ },
12
+ development: {
13
+ bucket: 's3://development_bucket_name/'
14
+ }
15
+ },
16
+ sync: {
17
+ origin: :staging,
18
+ destination: :development,
19
+ sync_options: ['--delete', '--acl public-read']
20
+ }
21
+ }.with_indifferent_access.freeze
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,51 @@
1
+ module Naifa
2
+
3
+ module Plugins
4
+ class S3
5
+ require 'naifa/plugins/s3/cli'
6
+ require 'naifa/plugins/s3/settings'
7
+ require 'active_support'
8
+ require 'active_support/core_ext/hash/deep_merge'
9
+ require 'active_support/core_ext/object/blank'
10
+ require 'naifa/utils'
11
+
12
+ def self.sync(options={})
13
+ options ||= {}
14
+
15
+ sync_settings = options[:sync]
16
+ environments_settings = options[:environments]
17
+
18
+ if sync_settings.blank? ||
19
+ sync_settings[:origin].blank? ||
20
+ sync_settings[:destination].blank?
21
+
22
+ raise Thor::Error, "Sync settings are not defined"
23
+ end
24
+
25
+ origin = sync_settings[:origin]
26
+ destination = sync_settings[:destination]
27
+
28
+ if environments_settings.blank? ||
29
+ environments_settings[origin].blank? || environments_settings[origin][:bucket].blank? ||
30
+ environments_settings[destination].blank? || environments_settings[destination][:bucket].blank?
31
+
32
+ raise Thor::Error, "Sync environments not set"
33
+ end
34
+
35
+ command = build_sync_command(
36
+ environments_settings[origin][:bucket],
37
+ environments_settings[destination][:bucket],
38
+ sync_settings.fetch(:sync_options, [])
39
+ )
40
+
41
+ Kernel.system(command)
42
+ end
43
+
44
+ def self.build_sync_command(from_bucket, to_bucket, sync_options=[])
45
+ command = "aws s3 sync #{from_bucket} #{to_bucket}"
46
+ command << " #{sync_options.join(' ')}" if sync_options.present?
47
+ command
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,23 @@
1
+ module Naifa
2
+ require 'naifa/plugins/postgres'
3
+ require 'naifa/plugins/s3'
4
+
5
+ module Plugins
6
+ REGISTRY = {
7
+ postgres: {
8
+ cli: Naifa::Plugins::Postgres::CLI,
9
+ description: 'Sync, backup and restore postgres dbs'
10
+ },
11
+ s3: {
12
+ cli: Naifa::Plugins::S3::CLI,
13
+ description: 'Syncs s3 buckets'
14
+ }
15
+ }.with_indifferent_access.freeze
16
+
17
+ def registry
18
+ REGISTRY
19
+ end
20
+
21
+ module_function :registry
22
+ end
23
+ end
data/lib/naifa/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Naifa
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/lib/naifa.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'naifa/version'
2
2
  require 'naifa/config'
3
3
  require 'naifa/heroku'
4
- require 'naifa/postgres'
4
+ require 'naifa/plugins'
5
5
 
6
6
  module Naifa
7
7
  # Your code goes here...
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: naifa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Filipe Dias
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-03-07 00:00:00.000000000 Z
11
+ date: 2017-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -94,8 +94,8 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.19'
97
- description: |2
98
- Naifa is a tool aimed at providing a collection of commands that simplify the development workflow.
97
+ description: " Naifa is a tool aimed at providing a collection of commands that
98
+ simplify the development workflow.\n"
99
99
  email:
100
100
  - f.dias@runtime-revolution.com
101
101
  executables:
@@ -118,7 +118,13 @@ files:
118
118
  - lib/naifa/cli.rb
119
119
  - lib/naifa/config.rb
120
120
  - lib/naifa/heroku.rb
121
- - lib/naifa/postgres.rb
121
+ - lib/naifa/plugins.rb
122
+ - lib/naifa/plugins/postgres.rb
123
+ - lib/naifa/plugins/postgres/cli.rb
124
+ - lib/naifa/plugins/postgres/settings.rb
125
+ - lib/naifa/plugins/s3.rb
126
+ - lib/naifa/plugins/s3/cli.rb
127
+ - lib/naifa/plugins/s3/settings.rb
122
128
  - lib/naifa/utils.rb
123
129
  - lib/naifa/version.rb
124
130
  - naifa.gemspec
@@ -142,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
148
  version: '0'
143
149
  requirements: []
144
150
  rubyforge_project:
145
- rubygems_version: 2.4.5.2
151
+ rubygems_version: 2.5.1
146
152
  signing_key:
147
153
  specification_version: 4
148
154
  summary: Naifa is a tool aimed at providing a collection of commands that simplify
@@ -1,180 +0,0 @@
1
- module Naifa
2
- require 'naifa/utils'
3
-
4
- class Postgres
5
- require 'active_support/core_ext/hash/deep_merge'
6
-
7
- DEFAULT_SETTINGS = {
8
- filename: 'db_backup',
9
- backup: {
10
- path: './data/db_dumps',
11
- db_name: '',
12
- environment: :staging,
13
- production: {
14
- type: :heroku
15
- },
16
- staging: {
17
- type: :heroku
18
- },
19
- development: {
20
- type: :docker,
21
- app_name: 'db',
22
- database: '',
23
- username: '\$POSTGRES_USER',
24
- path: '/db_dumps/'
25
- }
26
- },
27
- restore: {
28
- path: './data/db_dumps',
29
- environment: :development,
30
- staging: {
31
- type: :heroku
32
- },
33
- development: {
34
- type: :docker,
35
- app_name: 'db',
36
- database: '',
37
- username: '\$POSTGRES_USER',
38
- path: '/db_dumps/'
39
- }
40
- }
41
- }.with_indifferent_access.freeze
42
-
43
- def self.restore(options={})
44
- filename = options.fetch(:filename, DEFAULT_SETTINGS[:filename])
45
- restore_settings = DEFAULT_SETTINGS[:restore].deep_merge(options.fetch(:restore, {}))
46
-
47
- _restore(filename, restore_settings)
48
- end
49
-
50
- def self.backup(options={})
51
- filename = options.fetch(:filename, DEFAULT_SETTINGS[:filename])
52
- backup_settings = DEFAULT_SETTINGS[:backup].deep_merge(options.fetch(:backup, {}))
53
-
54
- _backup(filename, backup_settings)
55
- end
56
-
57
- def self.sync(options={})
58
- filename = options.fetch(:filename, DEFAULT_SETTINGS[:filename])
59
-
60
- backup_settings = DEFAULT_SETTINGS[:backup].deep_merge(options.fetch(:backup, {}))
61
- restore_settings = DEFAULT_SETTINGS[:restore].deep_merge(options.fetch(:restore, {}))
62
-
63
- return false if backup_settings[:environment].nil? ||
64
- backup_settings[backup_settings[:environment]].nil? ||
65
- restore_settings[:environment].nil? ||
66
- restore_settings[restore_settings[:environment]].nil?
67
-
68
- if backup_settings[backup_settings[:environment]][:type] == :heroku &&
69
- restore_settings[restore_settings[:environment]][:type] == :heroku
70
-
71
- Heroku::Postgres.sync(
72
- backup_settings[:environment],
73
- restore_settings[:environment]
74
- )
75
- else
76
- res = _backup(filename, backup_settings)
77
- _restore(filename, restore_settings) if res
78
- end
79
- end
80
-
81
- def self._backup(filename, options)
82
- environment = options[:environment]
83
- return false if environment.nil? || options[environment].nil?
84
-
85
- case options[environment][:type]
86
- when :remote
87
- command_line = build_backup_command(
88
- options[environment][:host],
89
- options[environment][:username] || options[:username],
90
- options[environment][:database] || options[:database],
91
- File.join(
92
- options[environment][:path] || options[:path],
93
- filename
94
- )
95
- )
96
- Kernel.system(command_line)
97
- when :local
98
- command_line = build_backup_command(
99
- 'localhost',
100
- options[environment][:username] || options[:username],
101
- options[environment][:database] || options[:database],
102
- File.join(
103
- options[environment][:path] || options[:path],
104
- filename
105
- )
106
- )
107
- Kernel.system(command_line)
108
- when :heroku
109
- Heroku::Postgres.backup(
110
- File.join(
111
- options[environment][:path] || options[:path],
112
- filename
113
- ),
114
- environment
115
- )
116
- end
117
- end
118
-
119
- private_class_method :_backup
120
-
121
- def self._restore(filename, options={})
122
- environment = options[:environment]
123
- return false if environment.nil? || options[environment].nil?
124
-
125
- case options[environment][:type]
126
- when :remote
127
- command_line = build_restore_command(
128
- options[environment][:host],
129
- options[environment][:username] || options[:username],
130
- options[environment][:database] || options[:database],
131
- File.join(
132
- options[environment][:path] || options[:path],
133
- filename
134
- )
135
- )
136
- Kernel.system(command_line)
137
- when :local
138
- command_line = build_restore_command(
139
- 'localhost',
140
- options[environment][:username] || options[:username],
141
- options[environment][:database] || options[:database],
142
- File.join(
143
- options[environment][:path] || options[:path],
144
- filename
145
- )
146
- )
147
- Kernel.system(command_line)
148
- when :docker
149
- command_line = build_restore_command(
150
- 'localhost',
151
- options[environment][:username] || options[:username],
152
- options[environment][:database] || options[:database],
153
- File.join(
154
- options[environment][:path] || options[:path],
155
- filename
156
- )
157
- )
158
- Utils.docker_compose_exec_command(
159
- options[environment][:app_name],
160
- command_line
161
- )
162
- end
163
- end
164
-
165
- private_class_method :_restore
166
-
167
- def self.build_restore_command(host, username, database, filename)
168
- "pg_restore --verbose --clean --no-acl --no-owner -h #{host} -U #{username} -d #{database} #{filename}"
169
- end
170
-
171
- private_class_method :build_restore_command
172
-
173
- def self.build_backup_command(host, username, database, filename)
174
- "pg_dump -Fc -h #{host} -U #{username} -d #{database} > #{filename}"
175
- end
176
-
177
- private_class_method :build_backup_command
178
-
179
- end
180
- end