app42 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +119 -0
  6. data/Rakefile +5 -0
  7. data/TODO.txt +36 -0
  8. data/app42.gemspec +41 -0
  9. data/bin/app42 +15 -0
  10. data/lib/app42.rb +23 -0
  11. data/lib/app42/base/constants.rb +33 -0
  12. data/lib/app42/base/help.rb +717 -0
  13. data/lib/app42/base/http_helper.rb +46 -0
  14. data/lib/app42/base/message.rb +35 -0
  15. data/lib/app42/base/shell.rb +39 -0
  16. data/lib/app42/base/util.rb +304 -0
  17. data/lib/app42/client/app42_rest_client.rb +451 -0
  18. data/lib/app42/client/rest_util.rb +66 -0
  19. data/lib/app42/command/app.rb +194 -0
  20. data/lib/app42/command/authorize.rb +29 -0
  21. data/lib/app42/command/base.rb +660 -0
  22. data/lib/app42/command/client.rb +232 -0
  23. data/lib/app42/command/config.rb +185 -0
  24. data/lib/app42/command/info.rb +101 -0
  25. data/lib/app42/command/service.rb +196 -0
  26. data/lib/app42/command/user.rb +140 -0
  27. data/lib/app42/command/user_key.rb +68 -0
  28. data/lib/app42/version.rb +13 -0
  29. data/spec/app42/base/constants_spec.rb +11 -0
  30. data/spec/app42/command/app_spec.rb +103 -0
  31. data/spec/app42/command/base_spec.rb +7 -0
  32. data/spec/app42/command/config_spec.rb +20 -0
  33. data/spec/app42/command/info_spec.rb +27 -0
  34. data/spec/app42/command/service_spec.rb +98 -0
  35. data/spec/app42/command/user_spec.rb +7 -0
  36. data/spec/app42/command/user_token_spec.rb +40 -0
  37. data/spec/app42/version_spec.rb +7 -0
  38. data/spec/app42_spec.rb +2 -0
  39. data/spec/data/info.yml +16 -0
  40. data/spec/data/services.yml +25 -0
  41. data/spec/data/state.yml +16 -0
  42. data/spec/data/user_services.yml +18 -0
  43. data/spec/spec_helper.rb +18 -0
  44. metadata +257 -0
@@ -0,0 +1,196 @@
1
+
2
+ module App42::Command
3
+ class Service < Base
4
+
5
+ # list all available service of requested user
6
+ def get_services
7
+ build_get_request params, 'info', 'services'
8
+ end
9
+
10
+ # ask service name to user
11
+ def get_service
12
+ service_hash = {}
13
+
14
+ get_services['services'].select {|each_service| service_hash["#{each_service['id']}"] = each_service['name'] + ' ' + each_service['version']}
15
+ service = input "Select Service", service_hash.values, true
16
+
17
+ service_id = nil
18
+ service_hash.each_pair{|s| service_id = s[0] if s[1] == service}
19
+ return service_id
20
+ end
21
+
22
+ def get_user_services#:nodoc:
23
+ build_get_request params, 'service', nil
24
+ end
25
+
26
+ # ask service name to user
27
+ def ask_service_name
28
+ service_name = input "Enter Service Name", [], true
29
+ valid_service_name = validate_app_and_service_name "Service name", service_name.strip
30
+ valid_service_name ? (return valid_service_name) : ask_service_name
31
+ end
32
+
33
+ # ask old password to user
34
+ def ask_old_password
35
+ input "Enter Old Password", [], true
36
+ end
37
+
38
+ # ask source id to user which he want to bind to service
39
+ def ask_source_ip what
40
+ ip = input "#{Message::BIND_NOTE}", [], true if what.to_s == 'bind'
41
+ ip = input "#{Message::UNBIND_NOTE}", [], true if what.to_s == 'unbind'
42
+ if ip_address_valid? ip
43
+ return ip
44
+ else
45
+ message "#{Message::IP_NOT_VALID}", true, 'red'
46
+ ask_source_ip what
47
+ end
48
+ end
49
+
50
+ # ask database name to user
51
+ def ask_database_name
52
+ database_name = input "Enter Database Name", [], true
53
+ valid_database_name = validate_database_name "Database name", database_name
54
+ valid_database_name ? (return valid_database_name) : ask_database_name
55
+ end
56
+
57
+ # ask users service name to user
58
+ def ask_user_service_name
59
+ service_list = []
60
+ get_user_services['services'].select {|service| service_list << service['name'] }
61
+ input "Select Service", service_list, true
62
+ end
63
+
64
+
65
+ # ask service name to user
66
+ def get_service_name
67
+ service_name = ask_service_name
68
+ service_name = service_name_availability service_name
69
+ service_name ? (return service_name) : get_service_name
70
+ end
71
+
72
+ # collect all required data from user to create new service
73
+ def create
74
+ service_name = get_service_name
75
+
76
+ service = get_service
77
+
78
+ database = ask_database_name
79
+
80
+ vm_type = get_vm_types
81
+
82
+ iaas = get_iaas_providers
83
+
84
+ os = get_os_for_service iaas, vm_type, service
85
+
86
+ vmconfig = get_vmconfig vm_type, iaas
87
+
88
+ create_service service, service_name , database, vm_type, iaas, vmconfig, os
89
+
90
+ end
91
+
92
+ # collect service name from user and proceed service delete request
93
+ def delete
94
+ @options[:service] = ask_service_name if @options[:service].nil?
95
+ response = delete_service @options[:service] if is_service_exist? @options[:service]
96
+ exit! if response
97
+ end
98
+
99
+ # collect service name from user and proceed service resetPassword request
100
+ def reset_pass
101
+ @options[:service] = ask_service_name if @options[:service].nil?
102
+ old_password = ask_old_password if is_service_exist? @options[:service]
103
+ res = reset_password @options[:service], old_password
104
+ (puts message "Your new password is: #{res['service']['password']}", false, 'green') && exit! if res
105
+ end
106
+
107
+ # collect service name,source IP and access time from user and proceed service resetPassword request
108
+ def service_bind
109
+ @options[:service] = ask_service_name if @options[:service].nil?
110
+ source_ip = ask_source_ip 'bind' if is_service_exist? @options[:service]
111
+ create_service_tunnel @options[:service], source_ip
112
+ end
113
+
114
+ # collect service name and source IP from user and proceed service unbind request
115
+ def service_unbind
116
+ @options[:service] = ask_service_name if @options[:service].nil?
117
+ source_ip = ask_source_ip 'unbind' if is_service_exist? @options[:service]
118
+ res = delete_service_tunnel @options[:service], source_ip
119
+ exit! if res
120
+ end
121
+
122
+ # list details of specific service
123
+ def service_bindInfo
124
+ @options[:service] = ask_user_service_name if @options[:service].nil?
125
+ query_params = params
126
+ query_params.store('serviceName', @options[:service])
127
+ service_info = build_get_request query_params, 'service', "tunnel/#{@options[:service]}"
128
+
129
+ rows, rows_header_final, rows_header = [], [], nil
130
+ if service_info && service_info['service']
131
+ rows_header = service_info['service'].keys
132
+ rows << service_info['service'].values
133
+
134
+ rows_header.map { |e| rows_header_final << camel_case_to_whitespace(e) }
135
+
136
+ table = Terminal::Table.new :title => Paint["=== #{@options[:service]} Details ===", :green], :headings => rows_header_final, :rows => rows
137
+ puts table
138
+ end
139
+ end
140
+
141
+ # list all available service on app42pass
142
+ def app42pass_services
143
+ rows, rows_header_final, rows_header = [], [], nil
144
+ services = get_services
145
+ if services && services['services']
146
+ services['services'].each do |e|
147
+ e.delete('id')
148
+ rows_header = e.keys
149
+ rows << e.values
150
+ end #unless services.nil?
151
+
152
+ rows_header.map { |e| rows_header_final << camel_case_to_whitespace(e) }
153
+
154
+ table = Terminal::Table.new :title => Paint["=== App42 PaaS Services ===", :green], :headings => rows_header_final, :rows => rows
155
+ puts table
156
+ end
157
+ end
158
+
159
+ # list all available service on app42pass
160
+ def services
161
+ rows, rows_header_final, rows_header = [], [], nil
162
+ services = get_user_services
163
+ if services && services['services']
164
+ services['services'].each do |e|
165
+ rows_header = e.keys
166
+ rows << e.values
167
+ end
168
+
169
+ rows_header.map { |e| rows_header_final << camel_case_to_whitespace(e) }
170
+
171
+ table = Terminal::Table.new :title => Paint["=== Service List ===", :green], :headings => rows_header_final, :rows => rows
172
+ puts table
173
+ end
174
+ end
175
+
176
+ # list details of specific service
177
+ def info
178
+ @options[:service] = ask_user_service_name if @options[:service].nil?
179
+ query_params = params
180
+ query_params.store('serviceName', @options[:service])
181
+ service_info = build_get_request query_params, 'service', "#{@options[:service]}"
182
+
183
+ rows, rows_header_final, rows_header = [], [], nil
184
+ if service_info && service_info['service']
185
+ rows_header = service_info['service'].keys
186
+ rows << service_info['service'].values
187
+
188
+ rows_header.map { |e| rows_header_final << camel_case_to_whitespace(e) }
189
+
190
+ table = Terminal::Table.new :title => Paint["=== #{@options[:service]} Details ===", :green], :headings => rows_header_final, :rows => rows
191
+ puts table
192
+ end
193
+ end
194
+
195
+ end
196
+ end
@@ -0,0 +1,140 @@
1
+
2
+ require 'highline/import'
3
+ require "interact"
4
+ require 'paint'
5
+ require 'fileutils'
6
+
7
+ module App42
8
+ module Command
9
+ class User
10
+
11
+ include App42::Command::UserToken
12
+ include App42::Base::Util
13
+ include Interactive
14
+
15
+ # @return
16
+ # dup argument to get a non-frozen string
17
+ def initialize(options={} )
18
+ @options = options.dup
19
+ end
20
+
21
+ # list local api and secret key
22
+ def keys
23
+ if check_key_file?
24
+ puts message "#{Message::KEYS}", false, 'green'
25
+ api_key, secret_key = get_keys
26
+ puts "API Key = #{api_key}"
27
+ puts "Secret Key = #{secret_key}"
28
+ else
29
+ message "#{Message::KEYS_NOT_FIND}", true, 'red'
30
+ # TODO, should be dynamic
31
+ App42::Base::Help.addKeys
32
+ end
33
+
34
+ end
35
+
36
+ # clear local credentials
37
+ def clear
38
+ if App42::Command::Auth.logged_in? then
39
+ begin
40
+ ans = ask "Do you want to delete existing keys?", :default => true
41
+ print_new_line
42
+ if ans == true
43
+ key_file = remove_key_file
44
+ puts message "#{Message::KEYS_CLEARED}", false, 'green'
45
+ else
46
+ exit!
47
+ end
48
+ rescue
49
+ message "#{Message::SOMETHING_WRONG}", false, 'red'
50
+ end
51
+ else
52
+ puts message "#{Message::KEYS_NOT_FIND}", false, 'red'
53
+ end
54
+ end
55
+
56
+ # Configure app42 credentials
57
+ def add
58
+ update_key if App42::Command::Auth.logged_in?
59
+ api_key, secret_key = collect_app42_credentials
60
+ if is_api_key_valid? api_key, secret_key
61
+ configure_app42 api_key, secret_key
62
+ print Paint["Adding keys...", :yellow]
63
+ puts Paint["done", :green]
64
+ else
65
+ puts Paint["#{Message::WRONG_KEY}", :red]
66
+ remove_key_file
67
+ print_new_line
68
+ exit!
69
+ end
70
+ end
71
+
72
+ # update existing key
73
+ def update_key
74
+ puts message "#{Message::KEYS_EXIST}", false, 'red'
75
+ ans = ask "\nDo you want to update existing keys?", :default => true
76
+ print_new_line
77
+ ans == true ? (return) : (exit!)
78
+ end
79
+
80
+ def is_api_key_valid? api_key, secret_key #:nodoc:
81
+ key_validate_params = {
82
+ 'apiKey'=> api_key,
83
+ 'version' => VERSION,
84
+ 'timeStamp' => Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S.%LZ")
85
+ }
86
+ api_key_valid = validate_api_and_secret_key key_validate_params, 'info', 'authenticate', secret_key
87
+ return api_key_valid['success']
88
+ end
89
+
90
+ # validate api and secret key
91
+ def validate_api_and_secret_key query_params, resource, action, secret_key
92
+ url = resource_url(resource, action)
93
+ sign = App42::Client::RestUtil.new.sign(secret_key, query_params )
94
+ response = App42::Client::App42RestClient.new.get(sign, url, query_params)
95
+ end
96
+
97
+ # collect keys for keys:add
98
+ # Get api key
99
+ # Get secret key
100
+ def collect_app42_credentials
101
+ api_key = @options[:api] if @options[:api]
102
+ secret_key = @options[:secret] if @options[:secret]
103
+ message '=== Enter your App42PaaS keys ===', true, 'blue' if api_key.nil? && secret_key.nil?
104
+ api_key = get_api_key if api_key.nil?
105
+ secret_key = get_secret_key if secret_key.nil?
106
+ return api_key, secret_key
107
+ end
108
+
109
+ # collect api key from client
110
+ def get_api_key(prompt = Paint["Enter API Key:", :bright])
111
+ api_key = @options[:api_key] if @options[:api_key]
112
+ api_key = ask(prompt) {|q| q.echo = true} if api_key.nil?
113
+ return api_key.strip
114
+ end
115
+
116
+ # collect secret key from client
117
+ def get_secret_key(prompt = Paint["Enter Secret Key:", :bright])
118
+ secret_key = @options[:secret_key] if @options[:secret_key]
119
+ secret_key = ask(prompt) {|q| q.echo = true} if secret_key.nil?
120
+ return secret_key.strip
121
+ end
122
+
123
+ private
124
+
125
+ # make sure, have configuration file
126
+ # configure api and secrete key
127
+ def configure_app42 api_key, secret_key
128
+ if api_key && secret_key
129
+ begin
130
+ ensure_config_dir
131
+ local_app42_key api_key, secret_key
132
+ rescue Exception => e
133
+ puts e
134
+ end
135
+ end
136
+ end
137
+
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,68 @@
1
+
2
+ require 'fileutils'
3
+ require 'yaml'
4
+
5
+ module App42
6
+ module Command
7
+ module UserToken
8
+
9
+ # make sure configuration root directory exist?
10
+ # create new dir unless file.exist?
11
+ def ensure_config_dir
12
+ FileUtils.mkdir_p(config_path) unless File.exist? config_path
13
+ end
14
+
15
+ # Load yaml config file
16
+ # make sure file contain api and secret key
17
+ def check_key_file?
18
+ info = YAML.load_file(key_path) if File.exist? key_path
19
+ true unless info.nil? || info['api_key'].nil? || info['secret_key'].nil?
20
+ end
21
+
22
+ # Load yaml config file
23
+ # read api and secret key
24
+ def get_keys
25
+ keys = YAML.load_file(key_path) if File.exist? key_path
26
+ return nil, nil if keys.nil? || keys.empty?
27
+ return keys['api_key'], keys['secret_key'] unless keys.empty? || keys.nil?
28
+ end
29
+
30
+ # expand key file path
31
+ # And open in write mode and configure api and secret key
32
+ def local_app42_key api_key, secret_key
33
+ key_file = File.expand_path(App42::KEYS_FILE)
34
+
35
+ File.open(key_file, "w") { |f|
36
+ f.puts "api_key:"
37
+ f.puts " #{api_key}"
38
+ f.puts "secret_key:"
39
+ f.puts " #{secret_key}"
40
+ }
41
+ end
42
+
43
+ # Extract key path
44
+ # and remove from configuration file
45
+ def remove_key_file
46
+ FileUtils.rm_f(key_path)
47
+ end
48
+
49
+ # Expand key path
50
+ def key_path
51
+ File.expand_path(App42::KEYS_FILE)
52
+ end
53
+
54
+ # Extract app42pass config dir path
55
+ # and remove from configuration file
56
+ def config_path
57
+ File.expand_path(App42::CONFIG_DIR)
58
+ end
59
+
60
+ # collect key path from constants
61
+ # mkdir key file
62
+ def ensure_key_file
63
+ FileUtils.mkdir_p(key_path) unless File.exist? key_path
64
+ end
65
+
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,13 @@
1
+ module App42
2
+ module Version
3
+ module VERSION
4
+ MAJOR = 0
5
+ MINOR = 5
6
+ TINY = 3
7
+ PRE = "alpha"
8
+
9
+ STRING = [MAJOR, MINOR, TINY].compact.join('.')
10
+ VERSION = STRING
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+ require 'app42/base/constants'
3
+ describe App42 do
4
+
5
+ describe 'Constants' do
6
+ it 'should return correct HOST url' do
7
+ App42::HOST.should == 'http://54.218.127.212:8081/paas/1.0'
8
+ end
9
+ end
10
+
11
+ end
@@ -0,0 +1,103 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'App42::Command' do
4
+ describe "App" do
5
+
6
+ before(:all) do
7
+ @app_name = 'demo'
8
+ @new_app_name = 'demo1'
9
+ @existing_app_name = 'demo'
10
+ @iaas = 1
11
+ @vm_type = 'Shared'
12
+ @runtime = 4
13
+ @framework = 4
14
+ @web_server = 4
15
+ @os = 1
16
+ @vm_config = 1
17
+ @instance = 1
18
+ end
19
+
20
+ context "With valid input data" do
21
+
22
+ it 'Should return app name available' do
23
+ response = App42::Command::Base.new.app_url_availability @new_app_name, @iaas, @vm_type
24
+ response.should eql true
25
+ end
26
+
27
+ it 'Should setup infrastructure' do
28
+ response = App42::Command::Base.new.create_infrastructure @app_name, @iaas, @vm_type, @runtime, @framework, @web_server, @os, @vm_config
29
+ response.should eql true
30
+ end
31
+
32
+ it 'should list all apps' do
33
+ response = App42::Command::App.new.apps
34
+ end
35
+
36
+ it 'Should scale app by instance 1:' do
37
+ response = App42::Command::Base.new.scale_or_descale_app 'scale', @instance, @app_name
38
+ response.should eql true
39
+ end
40
+
41
+ it 'Should descale app by instance 1:' do
42
+ response = App42::Command::Base.new.scale_or_descale_app 'descale', @instance, @app_name
43
+ response.should eql true
44
+ end
45
+
46
+ it 'Should start app:' do
47
+ response = App42::Command::Base.new.app_operation 'start', @app_name
48
+ response.should eql true
49
+ end
50
+
51
+ it 'Should stop app:' do
52
+ response = App42::Command::Base.new.app_operation 'stop', @app_name
53
+ response.should eql true
54
+ end
55
+
56
+ it 'Should restart app:' do
57
+ response = App42::Command::Base.new.app_operation 'restart', @app_name
58
+ response.should eql true
59
+ end
60
+
61
+ it 'Should return correct app information json' do
62
+ respone = App42::Command::Base.new.app_information 'info', @app_name
63
+ path = "#{APP_ROOT}/app42/spec/data/info.yml"
64
+ info = YAML.load_file(path)
65
+ respone.should eql info
66
+ end
67
+
68
+ it 'Should return correct app state json' do
69
+ respone = App42::Command::Base.new.app_information 'state', @app_name
70
+ path = "#{APP_ROOT}/app42/spec/data/state.yml"
71
+ info = YAML.load_file(path)
72
+ respone.should eql info
73
+ end
74
+
75
+ it 'Should delete app:' do
76
+ response = App42::Command::Base.new.app_operation 'delete', @app_name
77
+ response.should eql true
78
+ end
79
+ end
80
+
81
+ context "Check app name availability with existing app name" do
82
+ it 'Should return rest exception: App with name demo is not available.' do
83
+ response = App42::Command::Base.new.app_url_availability @existing_app_name, @iaas, @vm_type
84
+ puts response
85
+ end
86
+ end
87
+
88
+ context "Setup-infra with existing app name" do
89
+ it 'Should return rest exception: App with name demo is not available.' do
90
+ response = App42::Command::Base.new.create_infrastructure @existing_app_name, @iaas, @vm_type, @runtime, @framework, @web_server, @os, @vm_config
91
+ response.should eql true
92
+ end
93
+ end
94
+
95
+ context "Setup-infra with existing app name" do
96
+ it 'Should return rest exception: App with name demo is not available.' do
97
+ response = App42::Command::Base.new.create_infrastructure @existing_app_name, @iaas, @vm_type, @runtime, @framework, @web_server, @os, @vm_config
98
+ response.should eql true
99
+ end
100
+ end
101
+
102
+ end
103
+ end