ocp_registry 0.0.1.alpha → 0.0.5.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/lib/ocp_registry.rb +1 -0
  2. data/lib/ocp_registry/api_controller.rb +106 -16
  3. data/lib/ocp_registry/application_manager.rb +185 -23
  4. data/lib/ocp_registry/cloud_manager/mock/mock.rb +7 -13
  5. data/lib/ocp_registry/common.rb +3 -1
  6. data/lib/ocp_registry/config.rb +5 -1
  7. data/lib/ocp_registry/db/002_create_settings_table.rb +13 -0
  8. data/lib/ocp_registry/db/003_alter_comments_column_in_applications_table.rb +13 -0
  9. data/lib/ocp_registry/db/004_add_from_field_for_settings.rb +13 -0
  10. data/lib/ocp_registry/mail_client.rb +2 -2
  11. data/lib/ocp_registry/models.rb +2 -1
  12. data/lib/ocp_registry/models/registry_application.rb +19 -0
  13. data/lib/ocp_registry/models/registry_setting.rb +7 -0
  14. data/lib/ocp_registry/version.rb +1 -1
  15. data/mail_template/approve_admin.erb +3 -2
  16. data/mail_template/approve_user.erb +3 -4
  17. data/mail_template/cancel_admin.erb +13 -0
  18. data/mail_template/cancel_user.erb +13 -0
  19. data/mail_template/modify.erb +25 -0
  20. data/mail_template/refuse_admin.erb +4 -3
  21. data/mail_template/refuse_user.erb +4 -4
  22. data/mail_template/request_admin.erb +3 -2
  23. data/mail_template/request_user.erb +3 -3
  24. data/public/comment_dialog.css +11 -0
  25. data/public/common.css +34 -71
  26. data/public/head_message.css +11 -0
  27. data/public/images/portrait_admin.png +0 -0
  28. data/public/images/portrait_applicant.png +0 -0
  29. data/public/{jquery-1.10.2.min.js → jquery/jquery-1.10.2.min.js} +0 -0
  30. data/public/{jquery-1.10.2.min.map → jquery/jquery-1.10.2.min.map} +0 -0
  31. data/public/{jquery.json-2.4.min.js → json/jquery.json-2.4.min.js} +0 -0
  32. data/public/page_specific.css +15 -0
  33. data/public/post.css +37 -0
  34. data/public/qTIp/jquery.qtip.min.css +2 -0
  35. data/public/qTIp/jquery.qtip.min.js +3 -0
  36. data/public/tenant_opt_dialog.css +3 -0
  37. data/public/tenant_options.css +18 -0
  38. data/public/util.js +14 -0
  39. data/spec/spec_common.rb +25 -0
  40. data/spec/unit/config_spec.rb +117 -0
  41. data/views/admin_review.erb +306 -0
  42. data/views/applicant_review.erb +223 -0
  43. data/views/apply.erb +84 -133
  44. data/views/base.erb +56 -6
  45. data/views/comment_list.erb +12 -0
  46. data/views/inform_comment_dialog.erb +10 -0
  47. data/views/post.erb +28 -0
  48. data/views/reject_comment_dialog.erb +10 -0
  49. data/views/tenant_options.erb +244 -0
  50. data/views/view.erb +44 -7
  51. metadata +35 -8
  52. data/views/review.erb +0 -141
  53. data/views/show.erb +0 -96
@@ -16,6 +16,7 @@ require "yajl"
16
16
  require "securerandom"
17
17
  require "uri"
18
18
  require "erb"
19
+ require "json"
19
20
 
20
21
  require "ocp_registry/yaml_helper"
21
22
  require "ocp_registry/runner"
@@ -7,38 +7,39 @@ module Ocp::Registry
7
7
 
8
8
  not_found do
9
9
  exception = request.env["sinatra.error"]
10
- @logger.debug(request.path_info)
11
- @logger.error(exception.message)
10
+ @logger.info("[RECEIVED] #{request.request_method} : #{request.url} - #{request.ip}")
11
+ @logger.info(exception.message)
12
12
  do_response({:status => "not_found"}, nil)
13
13
  end
14
14
 
15
15
  error do
16
16
  exception = request.env["sinatra.error"]
17
- @logger.error(exception)
17
+ @logger.info(exception)
18
18
  status(500)
19
19
  do_response({:status => "error"}, nil)
20
20
  end
21
21
 
22
22
  error Ocp::Registry::Error do
23
23
  error = request.env["sinatra.error"]
24
+ @logger.info(error.message)
24
25
  status(error.code)
25
26
  do_response({:status => "error", :message => error.message},nil)
26
27
  end
27
28
 
28
29
  # get application list
29
30
  get '/v1/applications' do
31
+ @logger.info("[RECEIVED] #{request.request_method} : #{request.url} - #{request.ip}")
30
32
  email = params[:email]
31
33
  protected! unless email
32
- data = []
33
-
34
- result = @application_manager.list(email)
35
-
36
- result.each do |app|
37
- data << app.to_hash
38
- end
39
34
  if email
40
- do_response(data, :list)
35
+ data = {:status => "error", :message => "Sorry, list all applications of a specific user is not supported any more since security risks"}
36
+ do_response(data)
41
37
  else
38
+ data = []
39
+ result = @application_manager.list
40
+ result.each do |app|
41
+ data << app.to_hash
42
+ end
42
43
  do_response(data, :list, :review => true)
43
44
  end
44
45
  end
@@ -49,6 +50,7 @@ module Ocp::Registry
49
50
 
50
51
  # check project name
51
52
  post '/v1/applications/check' do
53
+ @logger.info("[RECEIVED] #{request.request_method} : #{request.url} - #{request.ip}")
52
54
  if project = params[:project]
53
55
  result = @application_manager.existed_tenant?(project)
54
56
  do_response(!result, nil)
@@ -57,27 +59,51 @@ module Ocp::Registry
57
59
 
58
60
  # get an application detail
59
61
  get '/v1/applications/:id' do
62
+ @logger.info("[RECEIVED] #{request.request_method} : #{request.url} - #{request.ip}")
60
63
  if(params[:id] == "default")
61
64
  do_response(@application_manager.default, :apply)
62
65
  else
63
66
  application = @application_manager.show(params[:id])
64
67
  if("true" == params[:review])
65
68
  protected!
66
- do_response(application.to_hash, :review)
69
+ if "true" == params[:modified]
70
+ data = application.to_hash(:lazy_load => false, :limit => 20)
71
+ view = :admin_review
72
+ else
73
+ data = application.to_hash(:lazy_load => false, :limit => 10)
74
+ view = :admin_review
75
+ end
67
76
  else
68
- do_response(application.to_hash, :view)
77
+ if "true" == params[:modified]
78
+ data = application.to_hash(:lazy_load => false, :limit => 20)
79
+ view = :applicant_review
80
+ else
81
+ data = application.to_hash(:lazy_load => false, :limit => 10)
82
+ view = :view
83
+ end
69
84
  end
85
+ do_response(data,view)
70
86
  end
71
87
  end
72
88
 
73
89
  # create an application
74
90
  post '/v1/applications' do
75
91
  app_info = Yajl.load(request.body.read)
76
- puts app_info
92
+
93
+ check_fields = ["email","project","settings"]
94
+ valid, fields = validate_not_null(check_fields,app_info)
95
+ return do_response({:status => "error", :message => "Filed [#{fields.join(", ")}] can not be null"}) unless valid
96
+
97
+ check_fields = ["email"]
98
+ valid, fields = validate_email(check_fields,app_info)
99
+ return do_response({:status => "error", :message => "Field [#{fields.join(", ")}] is not a valid email address"}) unless valid
100
+
101
+ @logger.info("[RECEIVED] #{request.request_method} : #{request.url} - #{request.ip} : #{app_info}")
102
+
77
103
  if app_info.kind_of?(Hash) && app_info['settings'].kind_of?(Hash)
78
- default = Yajl::load(@application_manager.default[:settings])
104
+ default = Yajl::load(@application_manager.default[:registry_settings].first[:settings])
79
105
  settings = default.merge(app_info['settings'])
80
- app_info[:settings] = json(settings)
106
+ app_info["settings"] = json(settings)
81
107
  end
82
108
  application = @application_manager.create(app_info)
83
109
  app_info = application.to_hash
@@ -87,12 +113,15 @@ module Ocp::Registry
87
113
  # approve an application
88
114
  post '/v1/applications/:id/approve' do
89
115
  protected!
116
+ @logger.info("[RECEIVED] #{request.request_method} : #{request.url} - #{request.ip}")
90
117
  result = @application_manager.approve(params[:id])
91
118
  do_response(result.to_hash, nil)
92
119
  end
93
120
 
94
121
  # refuse an application
95
122
  post '/v1/applications/:id/refuse' do
123
+ @logger.info("[RECEIVED] #{request.request_method} : #{request.url} - #{request.ip}")
124
+
96
125
  protected!
97
126
  body = Yajl.load(request.body.read)
98
127
  comments = nil
@@ -101,6 +130,41 @@ module Ocp::Registry
101
130
  do_response(result.to_hash, nil)
102
131
  end
103
132
 
133
+ post '/v1/applications/:id/settings' do
134
+ setting = Yajl.load(request.body.read)
135
+ @logger.info("[RECEIVED] #{request.request_method} : #{request.url} - #{request.ip} : #{setting}")
136
+
137
+ setting = {} if setting.nil?
138
+
139
+ if setting["from"] && setting["from"].strip.upcase == "ADMIN"
140
+ protected!
141
+ setting["from"] = "ADMIN"
142
+ else
143
+ setting["from"] = "USER"
144
+ end
145
+ result = @application_manager.add_setting_for(params[:id],setting)
146
+ do_response(result.to_hash)
147
+ end
148
+
149
+ get '/v1/applications/:id/settings' do
150
+ @logger.info("[RECEIVED] #{request.request_method} : #{request.url} - #{request.ip}")
151
+
152
+ result = @application_manager.list_settings(params[:id])
153
+
154
+ data = []
155
+ result.each do |setting|
156
+ data << setting.to_hash
157
+ end
158
+
159
+ do_response(data)
160
+ end
161
+
162
+ post '/v1/applications/:id/cancel' do
163
+ @logger.info("[RECEIVED] #{request.request_method} : #{request.url} - #{request.ip}")
164
+
165
+ result = @application_manager.cancel(params[:id])
166
+ do_response(result.to_hash)
167
+ end
104
168
 
105
169
  def initialize
106
170
  super
@@ -114,8 +178,10 @@ module Ocp::Registry
114
178
 
115
179
  def do_response(data, view = nil, mark = nil)
116
180
  if request.accept?('application/json') || view.nil? || (data.is_a?(Hash)&&'error' == data[:status])
181
+ @logger.info("[RESPONSE] JSON : json - #{data}")
117
182
  json(data)
118
183
  else
184
+ @logger.info("[RESPONSE] VIEW : #{view.to_s} - #{data}")
119
185
  erb :base do
120
186
  erb view ,:locals => {:data => data ,:mark => mark}
121
187
  end
@@ -142,5 +208,29 @@ module Ocp::Registry
142
208
  Yajl::Encoder.encode(payload)
143
209
  end
144
210
 
211
+ def validate_not_null(fields=[], source={})
212
+ validate(fields, source){|value| !value.nil? }
213
+ end
214
+
215
+ def validate_email(fields=[], source={})
216
+ validate(fields, source){|value| value =~ Ocp::Registry::Common::EMAIL_REGEX}
217
+ end
218
+
219
+ def validate(fields,source)
220
+ return true if fields.empty?
221
+ return false ,fields if source.empty? || !block_given?
222
+
223
+ not_pass = []
224
+ fields.each do |field|
225
+ not_pass << field unless yield source[field]
226
+ end
227
+
228
+ if not_pass.empty?
229
+ return true, []
230
+ else
231
+ return false , not_pass
232
+ end
233
+ end
234
+
145
235
  end
146
236
  end
@@ -9,29 +9,163 @@ module Ocp::Registry
9
9
  @logger = Ocp::Registry.logger
10
10
  end
11
11
 
12
- def list(email=nil)
12
+ def list(email = nil)
13
13
  if email
14
14
  results = Ocp::Registry::Models::RegistryApplication.reverse_order(:created_at).where(:email => email)
15
+ @logger.debug("List applications for user - #{email}")
15
16
  else
16
17
  results = Ocp::Registry::Models::RegistryApplication.reverse_order(:created_at).all
18
+ @logger.debug("List applications for ADMIN")
17
19
  end
18
-
19
20
  results
20
21
  end
21
22
 
23
+ def cancel(app_id)
24
+
25
+ app_info = get_application(app_id)
26
+
27
+ unless app_info.state == 'PENDING'
28
+ return {:status => "error", :message => "Application [#{app_info.project}] - [#{app_id}] has been #{app_info.state}"}
29
+ end
30
+
31
+ Ocp::Registry::Models::RegistryApplication.where(:id => app_id).update(:state => 'CANCELED', :end_at => Time.now.utc.to_s)
32
+
33
+ app_info = get_application(app_id)
34
+
35
+ @logger.debug("[CANCELED] project [#{app_info.project}] - [#{app_info.id}] at [#{app_info.end_at}]")
36
+
37
+ if @mail_manager
38
+ admin_msg = {
39
+ :app_info => app_info
40
+ }
41
+ mail = prepare_mail_properties(:cancel_admin, @mail_manager.admin_emails, admin_msg)
42
+ @mail_manager.send_mail(mail)
43
+ user_msg = {
44
+ :app_info => app_info
45
+ }
46
+ mail = prepare_mail_properties(:cancel_user, app_info.email, user_msg)
47
+ @mail_manager.send_mail(mail)
48
+ end
49
+
50
+ app_info
51
+ end
52
+
53
+ def list_settings(app_id)
54
+
55
+ Ocp::Registry::Models::RegistrySetting.reverse_order(:version).where(:registry_application_id => app_id)
56
+
57
+ end
58
+
22
59
  def show(app_id)
60
+
23
61
  app_info = get_application(app_id)
62
+
24
63
  return {:status => "error", :message => "Application with id - [#{app_id}] is not existed"} if app_info.nil?
64
+
65
+ app_info
66
+ end
67
+
68
+ def add_setting_for(app_id, setting)
69
+
70
+ app_info = get_application(app_id)
71
+
72
+ last_setting = Ocp::Registry::Models::RegistrySetting.where(:registry_application_id => app_id).order_by(:version).last
73
+
74
+ if last_setting.from == setting["from"]
75
+ wait_for = setting["from"] == "ADMIN" ? app_info.email : "Administrator"
76
+ return {:status => "error", :message => "Please wait for #{wait_for} review your last updates at #{last_setting.updated_at}"}
77
+ end
78
+
79
+ change_set = []
80
+ if setting && setting["settings"]
81
+ src = Yajl::load(last_setting.settings)
82
+ dest = setting["settings"]
83
+
84
+ merged = src.merge(dest) do |key, v1, v2|
85
+ if v1 != v2
86
+ change = {
87
+ :key => key,
88
+ :from => v1,
89
+ :to => v2
90
+ }
91
+ change_set << change
92
+ end
93
+ v2
94
+ end
95
+ return {:status => "error", :message => "No changes in settings are found"} if change_set.empty?
96
+
97
+ set = Yajl::Encoder.encode(merged)
98
+ comments = "#{setting["comments"]}" if setting["comments"]
99
+
100
+ @logger.info("Project [#{app_info.project}] - [#{app_info.id}] setting changed : #{change_set}")
101
+ else
102
+ set = last_setting.settings
103
+ comments = "ACCEPT"
104
+ comments += " - #{setting["comments"]}" if setting["comments"]
105
+
106
+ @logger.info("Project [#{app_info.project}] - [#{app_info.id}] setting accepted : #{set}")
107
+ end
108
+
109
+
110
+ update_time = Time.now.utc.to_s
111
+ last_setting.comments = comments
112
+ last_setting.updated_at = update_time
113
+ last_setting.save_changes
114
+
115
+ @logger.debug("Project [#{app_info.project}] - [#{app_info.id}] setting [#{last_setting.id}] comments - [#{comments}]")
116
+
117
+ new_setting = Ocp::Registry::Models::RegistrySetting.new(:registry_application_id => app_id,
118
+ :updated_at => update_time,
119
+ :settings => set,
120
+ :version => (last_setting.version + 1),
121
+ :from => setting["from"])
122
+ new_setting.save
123
+
124
+ @logger.info("Project [#{app_info.project}] - [#{app_info.id}] current setting is #{new_setting.id} - #{new_setting.settings}")
125
+
126
+ if @mail_manager
127
+ if setting["from"] == "ADMIN"
128
+ link = gen_app_uri(app_id, :modified => true)
129
+ mail_to = app_info.email
130
+ else
131
+ link = gen_app_uri(app_id, :modified => true, :review => true)
132
+ mail_to = @mail_manager.admin_emails
133
+ end
134
+
135
+ msg = {
136
+ :from => setting["from"] == "ADMIN" ? "Administrator" : app_info.email ,
137
+ :name => setting["from"] == "ADMIN" ? "User from #{app_info.email}" : "Administrator" ,
138
+ :change_set => change_set ,
139
+ :app_info => app_info ,
140
+ :comments => comments ,
141
+ :time => update_time ,
142
+ :application_link => link
143
+ }
144
+
145
+ mail = prepare_mail_properties(:modify, mail_to, msg)
146
+ @mail_manager.send_mail(mail)
147
+ end
148
+
25
149
  app_info
26
150
  end
27
151
 
28
152
  def default
29
- @default ||= {
153
+ return @default if @default
154
+
155
+ settings = Yajl::Encoder.encode(@cloud_manager.default_quota)
156
+ default_setting = {
157
+ :settings => settings
158
+ }
159
+ registry_settings = [] << default_setting
160
+
161
+
162
+ @default = {
30
163
  :email => "" ,
31
164
  :project => "" ,
32
165
  :description => "" ,
33
- :settings => Yajl::Encoder.encode(@cloud_manager.default_quota)
166
+ :registry_settings => registry_settings
34
167
  }
168
+
35
169
  end
36
170
 
37
171
  def approve(app_id)
@@ -41,7 +175,7 @@ module Ocp::Registry
41
175
 
42
176
  return {:status => "error", :message => "Application [#{app_info.project}] - [#{app_id}] has been #{app_info.state}"} unless app_info.state == 'PENDING'
43
177
 
44
- unless existed_tenant?(app_info.project, :find_local => false) then
178
+ unless existed_tenant?(app_info.project, :find_local => false)
45
179
  # create project tenant and user
46
180
  tenant = @cloud_manager.create_tenant(app_info.project, app_info.description)
47
181
 
@@ -68,14 +202,24 @@ module Ocp::Registry
68
202
 
69
203
  #assign quota to project
70
204
 
71
- settings = @cloud_manager.set_tenant_quota(tenant.id, Yajl.load(app_info.settings))
205
+ current_setting = app_info.registry_settings_dataset.order_by(:version).last
206
+ settings = @cloud_manager.set_tenant_quota(tenant.id, Yajl.load(current_setting.settings))
207
+
208
+ time = Time.now.utc.to_s
209
+
210
+ current_setting.comments = "APPROVED"
211
+ current_setting.updated_at = time
212
+ current_setting.save_changes
72
213
 
73
214
  Ocp::Registry::Models::RegistryApplication.where(:id => app_id)
74
- .update(:state => 'APPROVED',
75
- :updated_at => Time.now.utc.to_s,
76
- :settings => Yajl::Encoder.encode(settings) )
215
+ .update(:state => 'APPROVED', :end_at => time)
216
+
217
+ @logger.info("Project [#{app_info.project}] - [#{app_info.id}] is [APPROVED] at #{time} - setting : #{settings}")
218
+
77
219
  app_info = get_application(app_id)
220
+
78
221
  if @mail_manager
222
+
79
223
  admin_msg = {
80
224
  :app_info => app_info ,
81
225
  :application_link => gen_app_uri(app_id, :review => true) ,
@@ -83,16 +227,17 @@ module Ocp::Registry
83
227
  }
84
228
  mail = prepare_mail_properties(:approve_admin, @mail_manager.admin_emails, admin_msg)
85
229
  @mail_manager.send_mail(mail)
230
+
86
231
  user_msg = {
87
232
  :app_info => app_info ,
88
233
  :application_link => gen_app_uri(app_id) ,
89
- :applications_link => gen_app_uri(nil, :email => app_info.email) ,
90
234
  :login => Ocp::Registry.cloud_login_url ,
91
235
  :username => username ,
92
236
  :password => password
93
237
  }
94
238
  mail = prepare_mail_properties(:approve_user, app_info.email, user_msg)
95
239
  @mail_manager.send_mail(mail)
240
+
96
241
  end
97
242
  app_info
98
243
  else
@@ -104,19 +249,36 @@ module Ocp::Registry
104
249
 
105
250
  def refuse(app_id,comments)
106
251
  app_info = get_application(app_id)
107
- return {:status => "error", :message => "Application with id - [#{app_id}] is not existed"} if app_info.nil?
108
- return {:status => "error", :message => "Application [#{app_info.project}] - #{app_id} has been #{app_info.state}"} unless app_info.state == 'PENDING'
252
+
253
+ if app_info.nil?
254
+ return {:status => "error", :message => "Application with id - [#{app_id}] is not existed"}
255
+ end
256
+
257
+ unless app_info.state == 'PENDING'
258
+ return {:status => "error", :message => "Application [#{app_info.project}] - #{app_id} has been #{app_info.state}"}
259
+ end
109
260
 
110
261
  comments ||= "no comments"
111
- Ocp::Registry::Models::RegistryApplication.where(:id => app_id)
112
- .update(:state => 'REFUSED',
113
- :updated_at => Time.now.utc.to_s,
114
- :comments => comments)
262
+ time = Time.now.utc.to_s
263
+
264
+ app_info.state = 'REFUSED'
265
+ app_info.end_at = time
266
+ current_setting = app_info.registry_settings_dataset.order_by(:version).last
267
+ current_setting.updated_at = time
268
+
269
+ current_setting.comments = "REFUSED - #{comments}"
270
+
271
+ current_setting.save_changes
272
+ app_info.save_changes
273
+
274
+ @logger.info("Project [#{app_info.project}] - [#{app_info.id}] is [REFUSED] at #{time} - setting : #{current_setting.settings}")
275
+
115
276
  app_info = get_application(app_id)
116
277
 
117
278
  if @mail_manager
118
279
  admin_msg = {
119
280
  :app_info => app_info ,
281
+ :comments => current_setting.comments ,
120
282
  :application_link => gen_app_uri(app_id, :review => true) ,
121
283
  :applications_link => gen_app_uri
122
284
  }
@@ -124,8 +286,8 @@ module Ocp::Registry
124
286
  @mail_manager.send_mail(mail)
125
287
  user_msg = {
126
288
  :app_info => app_info ,
289
+ :comments => current_setting.comments ,
127
290
  :application_link => gen_app_uri(app_id) ,
128
- :applications_link => gen_app_uri(nil, :email => app_info.email)
129
291
  }
130
292
  mail = prepare_mail_properties(:refuse_user, app_info.email, user_msg)
131
293
  @mail_manager.send_mail(mail)
@@ -137,7 +299,12 @@ module Ocp::Registry
137
299
  if existed_tenant?(app_info['project'])
138
300
  {:status => "error", :message => "Project name [#{app_info['project']}] has been used"}
139
301
  else
302
+ setting = app_info.delete("settings")
140
303
  result = Ocp::Registry::Models::RegistryApplication.create(app_info)
304
+ result.add_registry_setting(:settings => setting)
305
+
306
+ @logger.info("Project [#{result.project}] - [#{result.id}] is [CREATED] - setting : #{setting}")
307
+
141
308
  if @mail_manager
142
309
  admin_msg = {
143
310
  :app_info => result ,
@@ -149,7 +316,6 @@ module Ocp::Registry
149
316
  user_msg = {
150
317
  :app_info => result ,
151
318
  :application_link => gen_app_uri(result.id) ,
152
- :applications_link => gen_app_uri(nil, :email => result.email)
153
319
  }
154
320
  mail = prepare_mail_properties(:request_user, result.email, user_msg)
155
321
  @mail_manager.send_mail(mail)
@@ -165,11 +331,7 @@ module Ocp::Registry
165
331
  return true if local_existed
166
332
  end
167
333
  remote_existed = @cloud_manager.get_tenant_by_name(tenant)? true : false
168
- if remote_existed
169
- return true
170
- else
171
- return false
172
- end
334
+ return remote_existed
173
335
  end
174
336
 
175
337
  private