app42 0.5.3

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.
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