vpsmatrix 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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