vpsmatrix 0.1.8 → 0.1.9

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: 4ee00ed13e94cab82e94a6c870d0dfcbb3234c13
4
- data.tar.gz: 3165664532216efb285190265b023b1129760790
3
+ metadata.gz: 54867d7225856e252da6399526ba5b786654ffbc
4
+ data.tar.gz: d414d15e0e2e1355c31bd1f4ff076a3a466c3e53
5
5
  SHA512:
6
- metadata.gz: a1762ce0ca5fa7b6e8de06a7dedb25ed341b2282a89185a24b6262b4d95a37b38a9e34ff55ffab3ae92907f864bdacda4ce5ec795e93e3d29c3be4a57469b4d3
7
- data.tar.gz: 4d33d9302a4c3af3263b45c8af7bcef7dd43131f3a55a8ea0d7cec3d2c862536ee57d4a823ccfbdbfea556ed4d18782e0dce120821237a25a6941fb3b5b642b7
6
+ metadata.gz: c23a6ae2568b00297addaa9f87fb865c7eadf0655c3fb65796b367b54f95d0887b108f6c779f5fdc6c10792d6865f5493ea5593c3be95c0e101a4c2f4f1d513d
7
+ data.tar.gz: 0ab2a5ff899c097f6c0a9c8435e5ab709afd9eac946d9bd1ddacba53d806e1d5477037a5d76c3030b461b7d9ca9b37e7b3e8d6fe8c54557f8865e9dcf80ea131
data/lib/vpsmatrix.rb CHANGED
@@ -2,5 +2,7 @@ require "vpsmatrix/version"
2
2
  require "vpsmatrix/starter"
3
3
 
4
4
  module Vpsmatrix
5
+ API_SERVER = "https://api.vpsmatrix.net"
6
+ API_TEST_SERVER = "http://localhost:3000"
5
7
  # Your code goes here...
6
8
  end
@@ -1,11 +1,10 @@
1
1
  require 'yaml'
2
2
 
3
- class Config
4
-
5
- def initialize
6
- @file_path = "config/vpsx.yml"
3
+ class Conf
4
+ def initialize(home=nil)
5
+ @file_path = ".vpsx.yml"
6
+ @file_path = "#{ENV['HOME']}/.vpsx.yml" if home
7
7
  unless File.exists? @file_path
8
- Dir.mkdir "config" unless Dir.exists? "config"
9
8
  File.open(@file_path, 'w') do |file|
10
9
  file.write "comment: 'Config file for VPS Matrix services'"
11
10
  end
@@ -0,0 +1,109 @@
1
+ module Helpers
2
+ # simple prompt with defined text
3
+ # return user's input
4
+ def prompt(default, *args)
5
+ print(*args)
6
+ result = gets.strip.gsub("\n", '')
7
+ return result.empty? ? default : result
8
+ end
9
+
10
+ # create put request, ssl and api_key optional
11
+ def send_put_request endpoint, params={}, api_key=nil, ssl=false
12
+ uri = URI.parse(endpoint)
13
+
14
+ Net::HTTP.start(uri.host, uri.port) do |http|
15
+ http.use_ssl = true if ssl
16
+ request = Net::HTTP::Put.new(uri.request_uri)
17
+ request['authorization'] = "Token token=#{api_key}" if api_key
18
+ request.set_form_data(params)
19
+ http.request request
20
+ end
21
+ end
22
+
23
+ # create get request, ssl and api_key optional
24
+ def send_get_request endpoint, params={}, api_key=nil, ssl=false #https://api.vpsmatrix.net/uploads/get_file_list
25
+ uri = URI.parse(endpoint)
26
+ uri.query = URI.encode_www_form(params)
27
+ http = Net::HTTP.new(uri.host, uri.port)
28
+ http.use_ssl = true if ssl
29
+ req = Net::HTTP::Get.new(uri.path)
30
+ req['authorization'] = "Token token=#{api_key}" if api_key
31
+ http.request(req)
32
+ end
33
+
34
+ # user can choose which VPS to use or create new one (get one from pool of prepared VPS)
35
+ def resolve_vps api_key
36
+ res = send_get_request "#{Vpsmatrix::API_TEST_SERVER}/vps/list_available", {}, api_key
37
+
38
+ if res.code == "200"
39
+ vps_list = JSON.parse res.body
40
+ vps_string = vps_list.map {|vps| "#{vps["id"]}: #{vps["hostname"]} at #{vps["ip"]}"}
41
+ vps_id = prompt nil, vps_string.join("\n") + "\n"
42
+ chosen_vps = vps_list.select {|vps| vps["id"].to_s == vps_id}.first
43
+ if chosen_vps.empty?
44
+ puts "No such vps exists. Use existing id please." # TODO let's user continue somehow (run prompt again?)
45
+ abort
46
+ else
47
+ # TODO is there more efficient way how to write to YML file? This just opens and closes file again and again. Maybe open it at beginning?
48
+ @app_config.write("host", chosen_vps["ip"])
49
+ @app_config.write("host_id", chosen_vps["id"])
50
+ end
51
+ #puts chosen_vps["hostname"]
52
+ else
53
+ puts "Check your api_key in ~/.vpsx.yml; call support"
54
+ end
55
+ end
56
+
57
+ # user may choose how to get files to VPS (git or directory upload)
58
+ def resolve_upload_strategy
59
+ # TODO add possibility to choose which remote to use
60
+ upload_strategy = prompt("1", "How you want to upload files? \n1: Git (origin remote will be used)\n2: Copy all files in folder [NOT IMPLEMENTED]\n")
61
+ if upload_strategy == "1"
62
+ puts "You have no git repository." && abort unless Dir.exist?(".git")
63
+ remote = `git remote get-url origin`.gsub("\n", '')
64
+ @app_config.write("upload_strategy", "git")
65
+ @app_config.write("git_url", remote)
66
+ puts "#{remote} will be used."
67
+ elsif upload_strategy == "2"
68
+ @app_config.write("upload_strategy", "stream")
69
+ puts "All files in this directory will be streamed to server."
70
+ else
71
+ puts "You chose invalid option!" && abort
72
+ end
73
+ end
74
+
75
+ # choose which database will be used and where (same VPS, remote VPS, remote service)
76
+ def resolve_database
77
+ # let user choose where database is
78
+ ## mysql is installed with root user without pass
79
+ # TODO add more database types as well 'postgres'
80
+ database = prompt("1", "Where database should be stored? \n1: Same VPS\n Other options not available now\n")
81
+ if database == "1"
82
+ @app_config.write("database", "current_vps")
83
+ else
84
+ puts "You chose invalid option!" && abort
85
+ end
86
+ end
87
+
88
+ # choose domain which will be added to nginx
89
+ def resolve_domain
90
+ domain = prompt("example.com", "Add domain where app will run (will be used in nginx configuration)\n")
91
+ @app_config.write("domain", domain)
92
+ end
93
+
94
+ # will create user with app name on VPS; generate ssh key for him and possibly upload your pub key.
95
+ def create_app_user api_key
96
+ upload_ssh_key = prompt("Y", "Do you want to upload your public ssh key to app user on VPS? (Y/n)\n")
97
+ # TODO consider situation when there is no pub key
98
+ pub_ssh = upload_ssh_key == "Y" ? File.read("#{ENV['HOME']}/.ssh/id_rsa.pub") : ""
99
+
100
+ options = @app_config.content.merge({ssh_key: pub_ssh})
101
+ result = send_put_request "#{Vpsmatrix::API_TEST_SERVER}/vps/create_new_user", options, api_key
102
+ if result.code == "200"
103
+ result.body
104
+ else
105
+ puts "Check your api_key in ~/.vpsx.yml; call support" && abort
106
+ end
107
+ end
108
+
109
+ end
@@ -1,65 +1,157 @@
1
1
  require 'digest'
2
2
  require 'net/http'
3
3
  require 'uri'
4
+ require 'json'
4
5
  require 'securerandom'
5
6
  require_relative 'config'
6
7
  require_relative 'upload_progress'
7
8
 
9
+ require_relative 'helpers'
10
+ include Helpers
11
+
8
12
  class Starter
9
13
 
10
14
 
15
+
11
16
  def self.start args
17
+ if ARGV[0]=~/^-/
18
+ switches = ARGV.shift
19
+ if switches == '-hv' || switches == '-vh'
20
+ puts "vpsx #{Vpsmatrix::VERSION}"
21
+ usage
22
+ elsif
23
+ switches == '-v'
24
+ puts "vpsx #{Vpsmatrix::VERSION}"
25
+ exit
26
+ else
27
+ usage
28
+ end
29
+ end
30
+
12
31
  @environment = args.shift
13
32
  @action = args.shift
14
33
 
15
- environments = %w{demo prod}
16
- fail "\nUnknown environment. Available environments: #{environments.join(', ')}" unless environments.include?(@environment)
17
- actions = %w{deploy}
18
- fail "\nUknown action. Available actions: #{actions.join(', ')}" unless actions.include?(@action)
19
- Starter.new.send("#{@environment}_#{@action}")
34
+ #environments = %w{demo prod}
35
+ #fail "\nUnknown environment. Available environments: #{environments.join(', ')}" unless environments.include?(@environment)
36
+ #actions = %w{deploy init}
37
+ #fail "\nUknown action. Available actions: #{actions.join(', ')}" unless actions.include?(@action)
38
+ case @action
39
+ when "deploy"
40
+ Starter.new.send("#{@environment}_#{@action}")
41
+ when "config"
42
+ Starter.new.send(@action)
43
+ else
44
+ usage
45
+ end
46
+ end
47
+
48
+
49
+ # Login user; create if not existing; add api_key to ~/.vpsx.yml for future use
50
+ def login
51
+ # check ~/.vpsx.yml for api key
52
+ @config = Conf.new("home")
53
+ return @config.content['api_key'] if Conf.new("home").content['api_key']
54
+
55
+ puts "Getting api key"
56
+ email = prompt(nil, "Insert email: ")
57
+ p email
58
+ password = prompt(nil, "Insert password (provide new if new user): ")
59
+ res = send_put_request "#{API_TEST_SERVER}/login", {email: email, password: password}
60
+ json = JSON.parse(res.body)
61
+ case
62
+ when json["result"] == "ok"
63
+ # save api_key to ~/.vpsx.yml
64
+ puts json["api_key"]
65
+ @config.write 'api_key', json["api_key"]
66
+ @config.content['api_key']
67
+ when json["result"] == "new_account"
68
+ puts "Confirm your e-mail and run this script again"
69
+ # TODO find way how to get back after user confirmed mail (run login again?)
70
+ abort
71
+ else
72
+ puts "There is something very bad, call help."
73
+ abort
74
+ end
75
+ end
76
+
77
+ # Configure how app is
78
+ def config
79
+ @app_config = Conf.new
80
+ api_key = login
81
+
82
+ resolve_vps(api_key)
83
+ resolve_upload_strategy
84
+
85
+ app_name = `pwd`.split("/").last.gsub("\n", "")
86
+ @app_config.write("app_name", app_name)
87
+ ## create service user
88
+ # API will check existing "service" user in VPS -> for communication between user's VPSs
89
+ # if not it will be created with ssh keys -> these keys will be saved to ~/.vpsx.yml (used for all other VPS)
90
+ # take private ssh key from existing server
91
+
92
+ # TODO check if user exists
93
+ ssh_key_for_git = create_app_user(api_key)
94
+ puts ssh_key_for_git
95
+
96
+ resolve_database
97
+ resolve_domain
98
+
99
+ ## TODO solve this
100
+ ## ask user for any ENV variables he may need? Like mailgun? mail server? redis? anything else?
101
+ # pass ENV variables to set settings of projects
20
102
  end
21
103
 
22
- #desc 'demo deploy', 'run demo deploy to deploy app to VPS Matrix demo server'
23
104
  def prod_deploy
24
- fail "Not implemented yet."
105
+ # TODO should be more sofisticated -> now in case of problems during .vpsx.yml creation there is no possibility to go back to questionnaire
106
+ # TODO do some checks of validity of .vpsx.yml !!!
107
+ return puts("There is no config file. Run vpsx config first.") && abort unless File.exist?(".vpsx.yml") # && is_valid?
108
+
109
+ @app_config = Conf.new
110
+ api_key = login # use api for all the rest of communication
111
+
112
+ # send to API and install on chosen VPS
113
+ puts 'Deploying app'
114
+ uri = URI.parse("#{Vpsmatrix::API_TEST_SERVER}/uploads/deploy_to_production")
115
+
116
+ Net::HTTP.start(uri.host, 3000, :read_timeout => 500) do |http|
117
+ req = Net::HTTP::Put.new(uri)
118
+ req.add_field("Content-Type","multipart/form-data;")
119
+ req.add_field('Transfer-Encoding', 'chunked')
120
+ req['authorization'] = "Token token=#{api_key}"
121
+ req.set_form_data(@app_config.content)
122
+
123
+ http.request req do |response|
124
+ puts ""
125
+ response.read_body do |chunk|
126
+ print chunk
127
+ end
128
+ if response.code != '200'
129
+ puts response.code
130
+ end
131
+ end
132
+ end
25
133
  end
26
134
 
135
+ #desc 'demo deploy', 'run demo deploy to deploy app to VPS Matrix demo server'
27
136
  def demo_deploy
28
137
 
29
- unless Config.new.content['ssh_key']
30
- Config.new.write 'ssh_key', SecureRandom.hex
138
+ unless Conf.new.content['ssh_key']
139
+ Conf.new.write 'ssh_key', SecureRandom.hex
31
140
  end
32
141
 
33
142
  @app_name = Dir.pwd.split(File::SEPARATOR).last
34
- unless Config.new.content['api_key'] && Config.new.content['api_key'].length == 32
143
+ unless Conf.new.content['api_key'] && Conf.new.content['api_key'].length == 32
35
144
  # ask for it to server
36
145
  # TODO check if server returns api_key
37
146
  api_key = send_get_request "https://api.vpsmatrix.net/uploads/get_api_key"
38
147
  if api_key.response.code == '200'
39
- Config.new.write 'api_key', api_key.response.body
148
+ Conf.new.write 'api_key', api_key.response.body
40
149
  end
41
150
  end
42
151
 
43
152
  #register_email
44
153
  read_files
45
154
  stream_file
46
-
47
- # https://api.vpsmatrix.net/uploads/get_new_files
48
-
49
- # detect rails? DB in (pg, mysql, sqlite, nodb)?
50
- # no? - do you wish us to check it?
51
-
52
- # send SSH key and API KEY to API app
53
-
54
- # -> OK
55
- # upload app to API, use rsync or something easy
56
-
57
-
58
- # -> return error message (no account, etc.)
59
-
60
- # run deploy on API app
61
- # receive DONE deploy -> show URL
62
-
63
155
  end
64
156
 
65
157
  def read_files
@@ -98,7 +190,7 @@ class Starter
98
190
  # stream version
99
191
  Net::HTTP.start(uri.host, uri.port, use_ssl: true, :read_timeout => 500) do |http|
100
192
  req = Net::HTTP::Put.new(uri)
101
- req.add_field("Content-Type","multipart/form-data; boundary=#{@multipart_boundary}; ssh_key=#{Config.new.content['ssh_key']}; api_key=#{Config.new.content['api_key']}")
193
+ req.add_field("Content-Type","multipart/form-data; boundary=#{@multipart_boundary}; ssh_key=#{Conf.new.content['ssh_key']}; api_key=#{Conf.new.content['api_key']}")
102
194
  req.add_field('Transfer-Encoding', 'chunked')
103
195
  req.basic_auth("test_app", "test_app")
104
196
  File.open('tmp/files_to_send', 'rb') do |io|
@@ -121,29 +213,6 @@ class Starter
121
213
  end
122
214
  end
123
215
 
124
- def send_put_request
125
- uri = URI.parse("https://api.vpsmatrix.net/uploads/send_new_files")
126
-
127
- # no stream version
128
- Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
129
- request = Net::HTTP::Put.new(uri.request_uri)
130
- request.basic_auth("test_app", "test_app")
131
- request.set_form_data({"file" => File.read("tmp/files_to_send")})
132
- http.request request
133
- end
134
- end
135
-
136
- def send_get_request endpoint, params={} #https://api.vpsmatrix.net/uploads/get_file_list
137
- uri = URI.parse(endpoint)
138
- uri.query = URI.encode_www_form(params)
139
- http = Net::HTTP.new(uri.host, uri.port)
140
- http.use_ssl = true
141
- req = Net::HTTP::Get.new(uri.path)
142
- req.basic_auth("test_app", "test_app")
143
- http.request(req)
144
- #res = Net::HTTP.get_response(uri)
145
- end
146
-
147
216
  def read_dirs
148
217
  working_dir = Dir.pwd
149
218
  list_of_files = Dir.glob "#{working_dir}/**/*"
@@ -157,48 +226,24 @@ class Starter
157
226
  dirs_string
158
227
  end
159
228
 
160
-
161
- def register_email
162
- puts 'Thank you very much for using vpsmatrix. You are awesome!
163
-
164
- We are just a month in this world and still working on
165
- full implementation of CLI functionality. We wish deployment to be the
166
- easiest step in development for everybody.
167
- '
168
- puts
169
- print 'Do you want to help us improve our solution [y/n] '
170
-
171
- reply=$stdin.gets.chop
172
-
173
- if reply.downcase == 'y'
174
-
175
- puts 'At this point we would love to get your email address so we can kindly
176
- inform you when we are ready to present working functionality. And we are
177
- eager to hear how you feel ideal deployment should look like
178
- at ideas@vpsmatrix.com !'
179
-
229
+ def self.usage
180
230
  puts
181
- print 'Your email: '
182
-
183
- email = $stdin.gets.chop
184
-
185
- uri = URI.parse("https://api.vpsmatrix.net/registration/gem")
186
- Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
187
- request = Net::HTTP::Post.new(uri)
188
- request.set_form_data({"email" => email})
189
- response = http.request(request)
190
- puts response.body
191
- end
192
-
193
-
194
- puts 'Thank you very much. Speak to you soon!'
195
-
196
- else
231
+ puts 'Usage:'
232
+ puts 'vpsx [-options] [environment action]'
233
+ puts
234
+ puts ' Available environments: demo'
235
+ puts ' Available actions: deploy'
197
236
  puts
198
- puts 'Thank you very much. We hope we meet in future where we will be more ready to help you ;)'
237
+ puts 'Options:'
238
+ puts ' -h print this help'
239
+ puts ' -v print version'
240
+ puts
241
+ puts 'Example:'
242
+ puts ' rails new fooapp'
243
+ puts ' cd fooapp'
244
+ puts ' rails g scaffold foo'
245
+ puts ' vpsx demo deploy'
246
+ exit
199
247
  end
200
- puts
201
-
202
248
 
203
- end
204
249
  end
@@ -1,3 +1,3 @@
1
1
  module Vpsmatrix
2
- VERSION = "0.1.8"
2
+ VERSION = "0.1.9"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vpsmatrix
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - mousse
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-08 00:00:00.000000000 Z
11
+ date: 2017-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,7 @@ files:
52
52
  - bin/vpsx
53
53
  - lib/vpsmatrix.rb
54
54
  - lib/vpsmatrix/config.rb
55
+ - lib/vpsmatrix/helpers.rb
55
56
  - lib/vpsmatrix/starter.rb
56
57
  - lib/vpsmatrix/upload_progress.rb
57
58
  - lib/vpsmatrix/version.rb