openshift-origin-controller 1.3.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of openshift-origin-controller might be problematic. Click here for more details.

Files changed (180) hide show
  1. data/COPYRIGHT +1 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +12 -0
  4. data/README.md +3 -0
  5. data/Rakefile +9 -0
  6. data/app/controllers/app_events_controller.rb +115 -0
  7. data/app/controllers/application_templates_controller.rb +19 -0
  8. data/app/controllers/applications_controller.rb +214 -0
  9. data/app/controllers/base_controller.rb +367 -0
  10. data/app/controllers/cartridges_controller.rb +48 -0
  11. data/app/controllers/descriptors_controller.rb +23 -0
  12. data/app/controllers/dns_resolvable_controller.rb +35 -0
  13. data/app/controllers/domains_controller.rb +156 -0
  14. data/app/controllers/emb_cart_controller.rb +276 -0
  15. data/app/controllers/emb_cart_events_controller.rb +52 -0
  16. data/app/controllers/environment_controller.rb +11 -0
  17. data/app/controllers/estimates_controller.rb +71 -0
  18. data/app/controllers/gear_groups_controller.rb +53 -0
  19. data/app/controllers/gears_controller.rb +70 -0
  20. data/app/controllers/keys_controller.rb +96 -0
  21. data/app/controllers/legacy_broker_controller.rb +510 -0
  22. data/app/controllers/quickstarts_controller.rb +29 -0
  23. data/app/controllers/user_controller.rb +38 -0
  24. data/app/helpers/cartridge_helper.rb +25 -0
  25. data/app/helpers/legacy_broker_helper.rb +21 -0
  26. data/app/helpers/user_action_logger.rb +38 -0
  27. data/app/models/application.rb +1718 -0
  28. data/app/models/application_template.rb +27 -0
  29. data/app/models/cartridge_cache.rb +51 -0
  30. data/app/models/cloud_user.rb +334 -0
  31. data/app/models/component_instance.rb +228 -0
  32. data/app/models/connection_endpoint.rb +10 -0
  33. data/app/models/district.rb +210 -0
  34. data/app/models/domain.rb +234 -0
  35. data/app/models/gear.rb +376 -0
  36. data/app/models/group_instance.rb +306 -0
  37. data/app/models/key.rb +20 -0
  38. data/app/models/legacy_reply.rb +15 -0
  39. data/app/models/legacy_request.rb +126 -0
  40. data/app/models/link.rb +11 -0
  41. data/app/models/message.rb +10 -0
  42. data/app/models/name_server_cache.rb +46 -0
  43. data/app/models/optional_param.rb +12 -0
  44. data/app/models/param.rb +13 -0
  45. data/app/models/remote_job.rb +57 -0
  46. data/app/models/rest_application.rb +126 -0
  47. data/app/models/rest_application10.rb +106 -0
  48. data/app/models/rest_application12.rb +124 -0
  49. data/app/models/rest_application_estimate.rb +12 -0
  50. data/app/models/rest_application_template.rb +20 -0
  51. data/app/models/rest_cartridge10.rb +41 -0
  52. data/app/models/rest_cartridge11.rb +151 -0
  53. data/app/models/rest_domain.rb +43 -0
  54. data/app/models/rest_domain10.rb +42 -0
  55. data/app/models/rest_estimates.rb +16 -0
  56. data/app/models/rest_gear.rb +14 -0
  57. data/app/models/rest_gear_group.rb +26 -0
  58. data/app/models/rest_key.rb +24 -0
  59. data/app/models/rest_reply.rb +31 -0
  60. data/app/models/rest_user.rb +43 -0
  61. data/app/models/result_io.rb +67 -0
  62. data/app/models/usage_record.rb +37 -0
  63. data/app/models/validators/app_validator.rb +30 -0
  64. data/app/models/validators/key_validator.rb +30 -0
  65. data/app/models/validators/namespace_validator.rb +18 -0
  66. data/config/routes.rb +36 -0
  67. data/lib/controller_engine.rb +7 -0
  68. data/lib/openshift-origin-controller.rb +14 -0
  69. data/lib/openshift/application_container_proxy.rb +241 -0
  70. data/lib/openshift/auth_service.rb +101 -0
  71. data/lib/openshift/data_store.rb +33 -0
  72. data/lib/openshift/dns_service.rb +41 -0
  73. data/lib/openshift/mongo_data_store.rb +671 -0
  74. data/openshift-origin-controller.gemspec +42 -0
  75. data/rubygem-openshift-origin-controller.spec +274 -0
  76. data/test/cucumber/application-estimate.feature +25 -0
  77. data/test/cucumber/cartridge-10gen-mms-agent.feature +28 -0
  78. data/test/cucumber/cartridge-cron.feature +32 -0
  79. data/test/cucumber/cartridge-haproxy.feature +31 -0
  80. data/test/cucumber/cartridge-jenkins-build.feature +12 -0
  81. data/test/cucumber/cartridge-jenkins-client.feature +10 -0
  82. data/test/cucumber/cartridge-lifecycle-diy.feature +21 -0
  83. data/test/cucumber/cartridge-lifecycle-jbossas.feature +61 -0
  84. data/test/cucumber/cartridge-lifecycle-jbosseap.feature +61 -0
  85. data/test/cucumber/cartridge-lifecycle-jbossews10.feature +61 -0
  86. data/test/cucumber/cartridge-lifecycle-jenkins.feature +41 -0
  87. data/test/cucumber/cartridge-lifecycle-nodejs.feature +59 -0
  88. data/test/cucumber/cartridge-lifecycle-perl.feature +40 -0
  89. data/test/cucumber/cartridge-lifecycle-php.feature +106 -0
  90. data/test/cucumber/cartridge-lifecycle-python.feature +40 -0
  91. data/test/cucumber/cartridge-lifecycle-ruby18.feature +49 -0
  92. data/test/cucumber/cartridge-lifecycle-ruby19.feature +41 -0
  93. data/test/cucumber/cartridge-mongodb.feature +31 -0
  94. data/test/cucumber/cartridge-mysql.feature +30 -0
  95. data/test/cucumber/cartridge-php.feature +14 -0
  96. data/test/cucumber/cartridge-phpmyadmin.feature +32 -0
  97. data/test/cucumber/cartridge-postgresql.feature +32 -0
  98. data/test/cucumber/cartridge-runtime-extended-db.feature +64 -0
  99. data/test/cucumber/cartridge-runtime-extended-jboss.feature +24 -0
  100. data/test/cucumber/cartridge-runtime-extended-nodejs.feature +21 -0
  101. data/test/cucumber/cartridge-runtime-extended-perl.feature +18 -0
  102. data/test/cucumber/cartridge-runtime-extended-php.feature +19 -0
  103. data/test/cucumber/cartridge-runtime-extended-python.feature +18 -0
  104. data/test/cucumber/cartridge-runtime-extended-ruby.feature +22 -0
  105. data/test/cucumber/cartridge-runtime-standard-diy.feature +6 -0
  106. data/test/cucumber/cartridge-runtime-standard-jbossas.feature +7 -0
  107. data/test/cucumber/cartridge-runtime-standard-jbosseap.feature +7 -0
  108. data/test/cucumber/cartridge-runtime-standard-jbossews10.feature +7 -0
  109. data/test/cucumber/cartridge-runtime-standard-jenkins.feature +8 -0
  110. data/test/cucumber/cartridge-runtime-standard-nodejs.feature +7 -0
  111. data/test/cucumber/cartridge-runtime-standard-perl.feature +6 -0
  112. data/test/cucumber/cartridge-runtime-standard-php.feature +6 -0
  113. data/test/cucumber/cartridge-runtime-standard-python.feature +6 -0
  114. data/test/cucumber/cartridge-runtime-standard-ruby.feature +19 -0
  115. data/test/cucumber/cartridge-switchyard.feature +36 -0
  116. data/test/cucumber/descriptor.feature +40 -0
  117. data/test/cucumber/embedded.feature +44 -0
  118. data/test/cucumber/idler.feature +75 -0
  119. data/test/cucumber/misc/descriptor/manifest.yml +22 -0
  120. data/test/cucumber/misc/php/db_test.php +21 -0
  121. data/test/cucumber/openshift-node.feature +21 -0
  122. data/test/cucumber/rest-application-templates.feature +31 -0
  123. data/test/cucumber/rest-applications.feature +431 -0
  124. data/test/cucumber/rest-cartridge-types.feature +16 -0
  125. data/test/cucumber/rest-domains.feature +276 -0
  126. data/test/cucumber/rest-gears.feature +38 -0
  127. data/test/cucumber/rest-keys.feature +247 -0
  128. data/test/cucumber/rest-quickstarts.feature +27 -0
  129. data/test/cucumber/rest-workflow.feature +64 -0
  130. data/test/cucumber/step_definitions/api_steps.rb +369 -0
  131. data/test/cucumber/step_definitions/application-estimate-steps.rb +51 -0
  132. data/test/cucumber/step_definitions/application_steps.rb +215 -0
  133. data/test/cucumber/step_definitions/cartridge-10gen-mms-agent_steps.rb +11 -0
  134. data/test/cucumber/step_definitions/cartridge-cron_steps.rb +51 -0
  135. data/test/cucumber/step_definitions/cartridge-haproxy_steps.rb +30 -0
  136. data/test/cucumber/step_definitions/cartridge-jenkins_steps.rb +93 -0
  137. data/test/cucumber/step_definitions/cartridge-lifecycle-nodejs_steps.rb +30 -0
  138. data/test/cucumber/step_definitions/cartridge-mongodb_steps.rb +60 -0
  139. data/test/cucumber/step_definitions/cartridge-mysql_steps.rb +56 -0
  140. data/test/cucumber/step_definitions/cartridge-php_steps.rb +72 -0
  141. data/test/cucumber/step_definitions/cartridge-postgresql_steps.rb +59 -0
  142. data/test/cucumber/step_definitions/cartridge-switchyard_steps.rb +29 -0
  143. data/test/cucumber/step_definitions/client_steps.rb +12 -0
  144. data/test/cucumber/step_definitions/descriptor_step.rb +32 -0
  145. data/test/cucumber/step_definitions/idler_steps.rb +37 -0
  146. data/test/cucumber/step_definitions/node_steps.rb +203 -0
  147. data/test/cucumber/step_definitions/runtime_steps.rb +547 -0
  148. data/test/cucumber/step_definitions/runtime_url_steps.rb +46 -0
  149. data/test/cucumber/step_definitions/trap-user-extended_steps.rb +14 -0
  150. data/test/cucumber/step_definitions/trap-user_steps.rb +58 -0
  151. data/test/cucumber/support/00_setup_helper.rb +106 -0
  152. data/test/cucumber/support/app_helper.rb +243 -0
  153. data/test/cucumber/support/assertions.rb +52 -0
  154. data/test/cucumber/support/command_helper.rb +453 -0
  155. data/test/cucumber/support/dns_helper.rb +54 -0
  156. data/test/cucumber/support/env.rb +5 -0
  157. data/test/cucumber/support/process_helper.rb +44 -0
  158. data/test/cucumber/support/runtime_support.rb +440 -0
  159. data/test/cucumber/support/unused.rb +27 -0
  160. data/test/cucumber/support/user_helper.rb +37 -0
  161. data/test/cucumber/trap-user-extended.feature +53 -0
  162. data/test/cucumber/trap-user.feature +34 -0
  163. data/test/ddns/1.168.192-rev.db.init +13 -0
  164. data/test/ddns/HOWTO.txt +207 -0
  165. data/test/ddns/Kexample.com.+157+06142.key +1 -0
  166. data/test/ddns/Kexample.com.+157+06142.private +7 -0
  167. data/test/ddns/authconfig.rb +14 -0
  168. data/test/ddns/example.com.db.init +23 -0
  169. data/test/ddns/example.com.key +4 -0
  170. data/test/ddns/named.ca +52 -0
  171. data/test/ddns/named.conf +48 -0
  172. data/test/ddns/named.empty +10 -0
  173. data/test/ddns/named.localhost +10 -0
  174. data/test/ddns/named.loopback +11 -0
  175. data/test/ddns/named.rfc1912.zones +42 -0
  176. data/test/ddns/named.root.key +5 -0
  177. data/test/ddns/named_service.rb +127 -0
  178. data/test/unit/bind_dns_service_test.rb +167 -0
  179. data/test/unit/broker_auth_test.rb +28 -0
  180. metadata +545 -0
@@ -0,0 +1,7 @@
1
+ require 'openshift-origin-controller'
2
+ require 'rails'
3
+
4
+ module OpenShift
5
+ class CloudEngine < ::Rails::Engine
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ require "openshift-origin-common"
2
+
3
+ module OpenShift
4
+ module Controller
5
+ require 'controller_engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
6
+ end
7
+ end
8
+
9
+ #require "cloud_user"
10
+ require "openshift/application_container_proxy"
11
+ require "openshift/auth_service"
12
+ require "openshift/dns_service"
13
+ require "openshift/data_store"
14
+ require "openshift/mongo_data_store"
@@ -0,0 +1,241 @@
1
+ module OpenShift
2
+ class ApplicationContainerProxy
3
+ @proxy_provider = OpenShift::ApplicationContainerProxy
4
+
5
+ def self.valid_gear_sizes(user)
6
+ @proxy_provider.valid_gear_sizes_impl(user)
7
+ end
8
+
9
+ def self.valid_gear_sizes_impl(user)
10
+ return ["small"]
11
+ end
12
+
13
+ def self.provider=(provider_class)
14
+ @proxy_provider = provider_class
15
+ end
16
+
17
+ def self.instance(id)
18
+ @proxy_provider.new(id)
19
+ end
20
+
21
+ def self.find_available(node_profile=nil)
22
+ @proxy_provider.find_available_impl(node_profile)
23
+ end
24
+
25
+ def self.find_one(node_profile=nil)
26
+ @proxy_provider.find_one_impl(node_profile)
27
+ end
28
+
29
+ def self.get_blacklisted
30
+ @proxy_provider.get_blacklisted_in_impl
31
+ end
32
+
33
+ def self.get_blacklisted_in_impl
34
+ []
35
+ end
36
+
37
+
38
+ def self.blacklisted?(name)
39
+ @proxy_provider.blacklisted_in_impl?(name)
40
+ end
41
+
42
+ def self.blacklisted_in_impl?(name)
43
+ end
44
+
45
+ def self.get_all_gears
46
+ @proxy_provider.get_all_gears_impl
47
+ end
48
+
49
+ def self.get_all_gears_impl
50
+ end
51
+
52
+ def self.get_all_active_gears
53
+ @proxy_provider.get_all_active_gears_impl
54
+ end
55
+
56
+ def self.get_all_active_gears_impl
57
+ end
58
+
59
+ def self.execute_parallel_jobs(handle)
60
+ @proxy_provider.execute_parallel_jobs_impl(handle)
61
+ end
62
+
63
+ def self.execute_parallel_jobs_impl(handle)
64
+ end
65
+
66
+ attr_accessor :id
67
+ def self.find_available_impl(node_profile=nil)
68
+ end
69
+
70
+ def self.find_one_impl(node_profile=nil)
71
+ end
72
+
73
+ def reserve_uid
74
+ end
75
+
76
+ def unreserve_uid(uid)
77
+ end
78
+
79
+ def get_available_cartridges
80
+ end
81
+
82
+ def create(app, gear)
83
+ end
84
+
85
+ def destroy(app, gear)
86
+ end
87
+
88
+ def add_authorized_ssh_key(app, gear, ssh_key, key_type=nil, comment=nil)
89
+ end
90
+
91
+ def remove_authorized_ssh_key(app, gear, ssh_key, comment=nil)
92
+ end
93
+
94
+ def add_env_var(app, gear, key, value)
95
+ end
96
+
97
+ def remove_env_var(app, gear, key)
98
+ end
99
+
100
+ def add_broker_auth_key(app, gear, iv, token)
101
+ end
102
+
103
+ def remove_broker_auth_key(app, gear)
104
+ end
105
+
106
+ def show_state(app, gear)
107
+ end
108
+
109
+ def configure_cartridge(app, gear, cart, template_git_url=nil)
110
+ end
111
+
112
+ def deconfigure_cartridge(app, gear, cart)
113
+ end
114
+
115
+ def get_public_hostname
116
+ end
117
+
118
+ def get_quota_blocks
119
+ end
120
+
121
+ def get_quota_files
122
+ end
123
+
124
+ def execute_connector(app, gear, cart, connector_name, input_args)
125
+ end
126
+
127
+ def start(app, gear, cart)
128
+ end
129
+
130
+ def stop(app, gear, cart)
131
+ end
132
+
133
+ def force_stop(app, gear, cart)
134
+ end
135
+
136
+ def restart(app, gear, cart)
137
+ end
138
+
139
+ def reload(app, gear, cart)
140
+ end
141
+
142
+ def status(app, gear, cart)
143
+ end
144
+
145
+ def tidy(app, gear, cart)
146
+ end
147
+
148
+ def threaddump(app, gear, cart)
149
+ end
150
+
151
+ def system_messages(app, gear, cart)
152
+ end
153
+
154
+ def expose_port(app, gear, cart)
155
+ end
156
+
157
+ def conceal_port(app, gear, cart)
158
+ end
159
+
160
+ def show_port(app, gear, cart)
161
+ end
162
+
163
+ def add_alias(app, gear, server_alias)
164
+ end
165
+
166
+ def remove_alias(app, gear, server_alias)
167
+ end
168
+
169
+ def update_namespace(app, cart, new_ns, old_ns)
170
+ end
171
+
172
+ def get_quota(gear)
173
+ end
174
+
175
+ def set_quota(gear, storage_in_gb, inodes)
176
+ end
177
+
178
+ def framework_carts
179
+ end
180
+
181
+ def embedded_carts
182
+ end
183
+
184
+ def add_component(app, gear, component)
185
+ end
186
+
187
+ def remove_component(app, gear, component)
188
+ end
189
+
190
+ def start_component(app, gear, component)
191
+ end
192
+
193
+ def stop_component(app, gear, component)
194
+ end
195
+
196
+ def restart_component(app, gear, component)
197
+ end
198
+
199
+ def reload_component(app, gear, component)
200
+ end
201
+
202
+ def component_status(app, gear, component)
203
+ end
204
+
205
+ def has_app?(app_uuid, app_name)
206
+ end
207
+
208
+ def has_embedded_app?(app_uuid, embedded_type)
209
+ end
210
+
211
+ def get_env_var_add_job(app, gear, key, value)
212
+ end
213
+
214
+ def get_env_var_remove_job(app, gear, key)
215
+ end
216
+
217
+ def get_add_authorized_ssh_key_job(app, gear, ssh_key, key_type=nil, comment=nil)
218
+ end
219
+
220
+ def get_remove_authorized_ssh_key_job(app, gear, ssh_key, comment=nil)
221
+ end
222
+
223
+ def get_execute_connector_job(app, gear, cart, connector_name, input_args)
224
+ end
225
+
226
+ def get_broker_auth_key_add_job(app, gear, iv, token)
227
+ end
228
+
229
+ def get_broker_auth_key_remove_job(app, gear)
230
+ end
231
+
232
+ def get_show_state_job(app, gear)
233
+ end
234
+
235
+ def get_show_gear_quota_job(gear)
236
+ end
237
+
238
+ def get_update_gear_quota_job(gear, storage_in_gb, inodes)
239
+ end
240
+ end
241
+ end
@@ -0,0 +1,101 @@
1
+ require 'digest/md5'
2
+
3
+ module OpenShift
4
+ class AuthService
5
+ @oo_auth_provider = OpenShift::AuthService
6
+
7
+ def self.provider=(provider_class)
8
+ @oo_auth_provider = provider_class
9
+ end
10
+
11
+ def self.instance
12
+ @oo_auth_provider.new
13
+ end
14
+
15
+ def initialize(auth_info = nil)
16
+ # This is useful for testing
17
+ @auth_info = auth_info
18
+
19
+ if @auth_info.nil?
20
+ @auth_info = Rails.application.config.auth
21
+ end
22
+
23
+ @salt = @auth_info[:salt]
24
+ @privkeyfile = @auth_info[:privkeyfile]
25
+ @privkeypass = @auth_info[:privkeypass]
26
+ @pubkeyfile = @auth_info[:pubkeyfile]
27
+
28
+ @token_login_key = @auth_info[:token_login_key] || :login
29
+ end
30
+
31
+ # Be careful overriding this method in a subclass. Doing so incorrectly
32
+ # can break node->broker authentication when swapping plugins.
33
+ def generate_broker_key(app)
34
+ cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
35
+ cipher.encrypt
36
+ cipher.key = OpenSSL::Digest::SHA512.new(@salt).digest
37
+ cipher.iv = iv = cipher.random_iv
38
+ token = {:app_name => app.name,
39
+ @token_login_key => app.user.login,
40
+ :creation_time => app.creation_time}
41
+ encrypted_token = cipher.update(token.to_json)
42
+ encrypted_token << cipher.final
43
+
44
+ public_key = OpenSSL::PKey::RSA.new(File.read(@pubkeyfile), @privkeypass)
45
+ encrypted_iv = public_key.public_encrypt(iv)
46
+
47
+ # Base64 encode the iv and token
48
+ encoded_iv = Base64::encode64(encrypted_iv)
49
+ encoded_token = Base64::encode64(encrypted_token)
50
+
51
+ [encoded_iv, encoded_token]
52
+ end
53
+
54
+ # Be careful overriding this method in a subclass. Doing so incorrectly
55
+ # can break node->broker authentication when swapping plugins.
56
+ def validate_broker_key(iv, key)
57
+ key = key.gsub(" ", "+")
58
+ iv = iv.gsub(" ", "+")
59
+ begin
60
+ encrypted_token = Base64::decode64(key)
61
+ cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
62
+ cipher.decrypt
63
+ cipher.key = OpenSSL::Digest::SHA512.new(@salt).digest
64
+ private_key = OpenSSL::PKey::RSA.new(File.read(@privkeyfile), @privkeypass)
65
+ cipher.iv = private_key.private_decrypt(Base64::decode64(iv))
66
+ json_token = cipher.update(encrypted_token)
67
+ json_token << cipher.final
68
+ rescue => e
69
+ $stderr.puts e.message
70
+ $stderr.puts e.backtrace
71
+ Rails.logger.debug "Broker key authentication failed. #{e.backtrace.inspect}"
72
+ raise OpenShift::AccessDeniedException.new
73
+ end
74
+
75
+ token = JSON.parse(json_token)
76
+ username = token[@token_login_key.to_s]
77
+ app_name = token['app_name']
78
+ creation_time = token['creation_time']
79
+
80
+ user = CloudUser.find(username)
81
+ raise OpenShift::AccessDeniedException.new if user.nil?
82
+ app = Application.find(user, app_name)
83
+
84
+ raise OpenShift::AccessDeniedException.new if app.nil? or creation_time != app.creation_time
85
+ return {:username => username, :auth_method => :broker_auth}
86
+ end
87
+
88
+ def authenticate(request, login, password)
89
+ return {:username => login, :auth_method => :login}
90
+ end
91
+
92
+ def login(request, params, cookies)
93
+ if params['broker_auth_key'] && params['broker_auth_iv']
94
+ return {:username => params['broker_auth_key'], :auth_method => :broker_auth}
95
+ else
96
+ data = JSON.parse(params['json_data'])
97
+ return {:username => data["rhlogin"], :auth_method => :login}
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,33 @@
1
+ module OpenShift
2
+ class DataStore
3
+ @oo_ds_provider = OpenShift::DataStore
4
+
5
+ def self.provider=(provider_class)
6
+ @oo_ds_provider = provider_class
7
+ end
8
+
9
+ def self.instance
10
+ @oo_ds_provider.new
11
+ end
12
+
13
+ def find(obj_type, user_id, id)
14
+ Rails.logger.debug "DataStore.find(#{obj_type}, #{user_id}, #{id})\n\n"
15
+ end
16
+
17
+ def find_all(obj_type, user_id=nil)
18
+ Rails.logger.debug "DataStore.find_all(#{obj_type}, #{user_id})\n\n"
19
+ end
20
+
21
+ def save(obj_type, user_id, id, obj)
22
+ Rails.logger.debug "DataStore.save(#{obj_type}, #{user_id}, #{id}, #{obj})\n\n"
23
+ end
24
+
25
+ def create(obj_type, user_id, id, obj)
26
+ Rails.logger.debug "DataStore.add(#{obj_type}, #{user_id}, #{id}, #{obj})\n\n"
27
+ end
28
+
29
+ def delete(obj_type, user_id, id)
30
+ Rails.logger.debug "DataStore.delete(#{obj_type}, #{user_id}, #{id})\n\n"
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,41 @@
1
+ module OpenShift
2
+ class DnsService
3
+ @oo_dns_provider = OpenShift::DnsService
4
+
5
+ def self.provider=(provider_class)
6
+ @oo_dns_provider = provider_class
7
+ end
8
+
9
+ def self.instance
10
+ @oo_dns_provider.new
11
+ end
12
+
13
+ def initialize
14
+ end
15
+
16
+ def namespace_available?(namespace)
17
+ return true
18
+ end
19
+
20
+ def register_namespace(namespace)
21
+ end
22
+
23
+ def deregister_namespace(namespace)
24
+ end
25
+
26
+ def register_application(app_name, namespace, public_hostname)
27
+ end
28
+
29
+ def deregister_application(app_name, namespace)
30
+ end
31
+
32
+ def modify_application(app_name, namespace, public_hostname)
33
+ end
34
+
35
+ def publish
36
+ end
37
+
38
+ def close
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,671 @@
1
+ require 'rubygems'
2
+ require 'mongo'
3
+ require 'pp'
4
+
5
+ module OpenShift
6
+ class MongoDataStore < OpenShift::DataStore
7
+ MAX_CON_RETRIES = 60
8
+ CON_RETRY_WAIT_TM = 0.5 # in secs
9
+
10
+ attr_reader :replica_set, :host_port, :user, :password, :db, :collections
11
+
12
+ def initialize(access_info = nil)
13
+ if access_info != nil
14
+ # no-op
15
+ elsif defined? Rails
16
+ access_info = Rails.application.config.datastore
17
+ else
18
+ raise Exception.new("Mongo DataStore service is not initialized")
19
+ end
20
+ @replica_set = access_info[:replica_set]
21
+ @host_port = access_info[:host_port]
22
+ @user = access_info[:user]
23
+ @password = access_info[:password]
24
+ @db = access_info[:db]
25
+ @collections = access_info[:collections]
26
+ end
27
+
28
+ def self.instance
29
+ OpenShift::MongoDataStore.new
30
+ end
31
+
32
+ def find(obj_type, user_id, id)
33
+ Rails.logger.debug "MongoDataStore.find(#{obj_type}, #{user_id}, #{id})\n\n"
34
+ case obj_type
35
+ when "CloudUser"
36
+ get_user(user_id)
37
+ when "Application"
38
+ get_app(user_id, id)
39
+ when "Domain"
40
+ get_domain(user_id, id)
41
+ when "ApplicationTemplate"
42
+ find_application_template(id)
43
+ end
44
+ end
45
+
46
+ def find_all(obj_type, user_id=nil, opts=nil, &block)
47
+ Rails.logger.debug "MongoDataStore.find_all(#{obj_type}, #{user_id}, #{opts})\n\n"
48
+ case obj_type
49
+ when "CloudUser"
50
+ get_users(opts, &block)
51
+ when "Application"
52
+ get_apps(user_id, &block)
53
+ when "Domain"
54
+ get_domains(user_id, &block)
55
+ when "ApplicationTemplate"
56
+ if opts.nil? || opts.empty?
57
+ find_all_application_templates(&block)
58
+ else
59
+ find_application_template_by_tag(opts[:tag], &block)
60
+ end
61
+ end
62
+ end
63
+
64
+ def find_all_logins(opts)
65
+ Rails.logger.debug "MongoDataStore.find_all_logins()\n\n"
66
+ query = {}
67
+ if opts
68
+ if opts[:with_gears]
69
+ query["apps.group_instances.gears.0"] = {"$exists" => true}
70
+ end
71
+ if opts[:with_usage]
72
+ query["usage_records.0"] = {"$exists" => true}
73
+ end
74
+ if opts[:with_plan]
75
+ query["$or"] = [{"pending_plan_id" => {"$ne" => nil}}, {"plan_id" => {"$ne" => nil}}]
76
+ end
77
+ end
78
+ mcursor = user_collection.find(query, {:fields => []})
79
+ ret = []
80
+ mcursor.each do |hash|
81
+ ret.push(hash['_id'])
82
+ end
83
+ ret
84
+ end
85
+
86
+ def find_by_gear_uuid(gear_uuid)
87
+ Rails.logger.debug "MongoDataStore.find_by_gear_uuid(#{gear_uuid})\n\n"
88
+ hash = find_one( user_collection, { "apps.group_instances.gears.uuid" => gear_uuid } )
89
+ return nil unless hash
90
+ user_hash_to_ret(hash)
91
+ end
92
+
93
+ def find_by_uuid(obj_type_of_uuid, uuid)
94
+ Rails.logger.debug "MongoDataStore.find_by_uuid(#{obj_type_of_uuid}, #{uuid})\n\n"
95
+ case obj_type_of_uuid
96
+ when "CloudUser"
97
+ get_user_by_uuid(uuid)
98
+ when "Application"
99
+ get_user_by_app_uuid(uuid)
100
+ when "Domain"
101
+ get_user_by_domain_uuid(uuid)
102
+ when "ApplicationTemplate"
103
+ find_application_template(uuid)
104
+ end
105
+ end
106
+
107
+ def find_subaccounts_by_parent_login(parent_id)
108
+ Rails.logger.debug "MongoDataStore.find_subaccounts_by_parent_login(#{parent_id})\n\n"
109
+ cur = MongoDataStore.rescue_con_failure { user_collection.find({ "parent_user_login" => parent_id }) }
110
+ return [] unless cur
111
+ hash_list = []
112
+ cur.each do |hash|
113
+ hash.delete("_id")
114
+ hash_list << hash
115
+ end
116
+
117
+ hash_list
118
+ end
119
+
120
+ def save(obj_type, user_id, id, obj_attrs)
121
+ Rails.logger.debug "MongoDataStore.save(#{obj_type}, #{user_id}, #{id}, #hidden)\n\n"
122
+ case obj_type
123
+ when "CloudUser"
124
+ put_user(user_id, obj_attrs)
125
+ when "Application"
126
+ put_app(user_id, id, obj_attrs)
127
+ when "Domain"
128
+ put_domain(user_id, id, obj_attrs)
129
+ when "UsageRecord"
130
+ put_usage_record(user_id, id, obj_attrs)
131
+ end
132
+ end
133
+
134
+ def create(obj_type, user_id, id, obj_attrs)
135
+ Rails.logger.debug "MongoDataStore.create(#{obj_type}, #{user_id}, #{id}, #hidden)\n\n"
136
+ case obj_type
137
+ when "CloudUser"
138
+ add_user(user_id, obj_attrs)
139
+ when "Application"
140
+ add_app(user_id, id, obj_attrs)
141
+ when "Domain"
142
+ add_domain(user_id, id, obj_attrs)
143
+ when "ApplicationTemplate"
144
+ save_application_template(id, obj_attrs)
145
+ end
146
+ end
147
+
148
+ def delete(obj_type, user_id, id=nil)
149
+ Rails.logger.debug "MongoDataStore.delete(#{obj_type}, #{user_id}, #{id})\n\n"
150
+ case obj_type
151
+ when "CloudUser"
152
+ delete_user(user_id)
153
+ when "Application"
154
+ delete_app(user_id, id)
155
+ when "Domain"
156
+ delete_domain(user_id, id)
157
+ when "ApplicationTemplate"
158
+ delete_application_template(id)
159
+ when "UsageRecord"
160
+ delete_usage_record(user_id, id)
161
+ end
162
+ end
163
+
164
+ def delete_usage_record_by_gear_uuid(user_id, gear_uuid, usage_type)
165
+ Rails.logger.debug "MongoDataStore.delete_usage_record_by_gear_uuid(#{user_id}, #{gear_uuid}, #{usage_type})\n\n"
166
+ update( user_collection, { "_id" => user_id },
167
+ { "$pull" => { "usage_records" => {"gear_uuid" => gear_uuid, "usage_type" => usage_type}}} )
168
+ end
169
+
170
+ def delete_usage_records_by_uuids(user_id, uuids)
171
+ Rails.logger.debug "MongoDataStore.delete_usage_record_by_gear_uuid(#{user_id}, #{uuids})\n\n"
172
+ update( user_collection, { "_id" => user_id },
173
+ { "$pull" => { "usage_records" => {"uuid" => {"$in" => uuids}} }} )
174
+ end
175
+
176
+ def db(connection_opts=nil)
177
+ if @replica_set
178
+ options = {:read => :secondary, :connect_timeout => 60}
179
+ options.merge!(connection_opts) if connection_opts
180
+ con = Mongo::ReplSetConnection.new(*@host_port << options)
181
+ else
182
+ con = Mongo::Connection.new(@host_port[0], @host_port[1])
183
+ end
184
+ user_db = con.db(@db)
185
+ user_db.authenticate(@user, @password)
186
+ user_db
187
+ end
188
+
189
+ def user_collection(connection_opts=nil)
190
+ db(connection_opts).collection(@collections[:user])
191
+ end
192
+
193
+ def find_one(collection, *args)
194
+ MongoDataStore.rescue_con_failure do
195
+ collection.find_one(*args)
196
+ end
197
+ end
198
+
199
+ def find_and_modify(collection, *args)
200
+ MongoDataStore.rescue_con_failure do
201
+ collection.find_and_modify(*args)
202
+ end
203
+ end
204
+
205
+ def insert(collection, *args)
206
+ MongoDataStore.rescue_con_failure do
207
+ collection.insert(*args)
208
+ end
209
+ end
210
+
211
+ def update(collection, *args)
212
+ MongoDataStore.rescue_con_failure do
213
+ collection.update(*args)
214
+ end
215
+ end
216
+
217
+ def remove(collection, *args)
218
+ MongoDataStore.rescue_con_failure do
219
+ collection.remove(*args)
220
+ end
221
+ end
222
+
223
+ # Ensure retry upon connection failure
224
+ def self.rescue_con_failure(max_retries=MAX_CON_RETRIES, retry_wait_tm=CON_RETRY_WAIT_TM)
225
+ retries = 0
226
+ begin
227
+ yield
228
+ rescue Mongo::ConnectionFailure => ex
229
+ retries += 1
230
+ raise ex if retries > max_retries
231
+ sleep(retry_wait_tm)
232
+ retry
233
+ end
234
+ end
235
+
236
+ def find_district(uuid, connection_opts=nil)
237
+ Rails.logger.debug "MongoDataStore.find_district(#{uuid})\n\n"
238
+ hash = find_one( district_collection(connection_opts), "_id" => uuid )
239
+ hash_to_district_ret(hash)
240
+ end
241
+
242
+ def find_district_by_name(name, connection_opts=nil)
243
+ Rails.logger.debug "MongoDataStore.find_district_by_name(#{name})\n\n"
244
+ hash = find_one( district_collection(connection_opts), "name" => name )
245
+ hash_to_district_ret(hash)
246
+ end
247
+
248
+ def find_all_districts()
249
+ Rails.logger.debug "find_all_districts()\n\n"
250
+ MongoDataStore.rescue_con_failure do
251
+ mcursor = district_collection.find()
252
+ cursor_to_district_hash(mcursor)
253
+ end
254
+ end
255
+
256
+ def find_district_with_node(server_identity)
257
+ Rails.logger.debug "find_district_with_node(#{server_identity})\n\n"
258
+ hash = find_one( district_collection, {"server_identities.name" => server_identity } )
259
+ hash_to_district_ret(hash)
260
+ end
261
+
262
+ def save_district(uuid, district_attrs)
263
+ Rails.logger.debug "save_district(#{uuid}, #{district_attrs.pretty_inspect})\n\n"
264
+ district_attrs["_id"] = uuid
265
+ orig_server_identities = district_attrs["server_identities"]
266
+ district_attrs_to_internal(district_attrs)
267
+ update( district_collection, { "_id" => uuid }, district_attrs, { :upsert => true } )
268
+ district_attrs.delete("_id")
269
+ district_attrs["server_identities"] = orig_server_identities
270
+ end
271
+
272
+ def delete_district(uuid)
273
+ Rails.logger.debug "delete_district(#{uuid})\n\n"
274
+ remove( district_collection, { "_id" => uuid, "active_server_identities_size" => 0 } )
275
+ end
276
+
277
+ def reserve_district_given_uid(uuid, uid)
278
+ Rails.logger.debug "reserve_district_given_uid(#{uuid}, #{uid})\n\n"
279
+ hash = find_and_modify( district_collection, {
280
+ :query => {"_id" => uuid, "available_capacity" => {"$gt" => 0}},
281
+ :update => {"$pull" => { "available_uids" => uid }, "$inc" => { "available_capacity" => -1 }},
282
+ :new => false })
283
+ return hash ? (hash["available_uids"].include? uid) : false
284
+ end
285
+
286
+ def reserve_district_uid(uuid)
287
+ Rails.logger.debug "reserve_district_uid(#{uuid})\n\n"
288
+ hash = find_and_modify( district_collection, {
289
+ :query => {"_id" => uuid, "available_capacity" => {"$gt" => 0}},
290
+ :update => {"$pop" => { "available_uids" => -1}, "$inc" => { "available_capacity" => -1 }},
291
+ :new => false })
292
+ return hash ? hash["available_uids"][0] : nil
293
+ end
294
+
295
+ def unreserve_district_uid(uuid, uid)
296
+ Rails.logger.debug "unreserve_district_uid(#{uuid})\n\n"
297
+ update( district_collection, {"_id" => uuid, "available_uids" => {"$ne" => uid}}, {"$push" => { "available_uids" => uid}, "$inc" => { "available_capacity" => 1 }} )
298
+ end
299
+
300
+ def add_district_node(uuid, server_identity)
301
+ Rails.logger.debug "add_district_node(#{uuid},#{server_identity})\n\n"
302
+ update( district_collection, {"_id" => uuid, "server_identities.name" => { "$ne" => server_identity }}, {"$push" => { "server_identities" => {"name" => server_identity, "active" => true}}, "$inc" => { "active_server_identities_size" => 1 }} )
303
+ end
304
+
305
+ def remove_district_node(uuid, server_identity)
306
+ Rails.logger.debug "remove_district_node(#{uuid},#{server_identity})\n\n"
307
+ hash = find_and_modify( district_collection, {
308
+ :query => { "_id" => uuid, "server_identities" => {"$elemMatch" => {"name" => server_identity, "active" => false}}},
309
+ :update => { "$pull" => { "server_identities" => {"name" => server_identity }}} })
310
+ return hash != nil
311
+ end
312
+
313
+ def deactivate_district_node(uuid, server_identity)
314
+ Rails.logger.debug "deactivate_district_node(#{uuid},#{server_identity})\n\n"
315
+ update( district_collection, {"_id" => uuid, "server_identities" => {"$elemMatch" => {"name" => server_identity, "active" => true}}}, {"$set" => { "server_identities.$.active" => false}, "$inc" => { "active_server_identities_size" => -1 }} )
316
+ end
317
+
318
+ def activate_district_node(uuid, server_identity)
319
+ Rails.logger.debug "activate_district_node(#{uuid},#{server_identity})\n\n"
320
+ update( district_collection, {"_id" => uuid, "server_identities" => {"$elemMatch" => {"name" => server_identity, "active" => false}}}, {"$set" => { "server_identities.$.active" => true}, "$inc" => { "active_server_identities_size" => 1 }} )
321
+ end
322
+
323
+ def add_district_uids(uuid, uids)
324
+ Rails.logger.debug "add_district_capacity(#{uuid},#{uids})\n\n"
325
+ update( district_collection, {"_id" => uuid}, {"$pushAll" => { "available_uids" => uids }, "$inc" => { "available_capacity" => uids.length, "max_uid" => uids.length, "max_capacity" => uids.length }} )
326
+ end
327
+
328
+ def remove_district_uids(uuid, uids)
329
+ Rails.logger.debug "remove_district_capacity(#{uuid},#{uids})\n\n"
330
+ update( district_collection, {"_id" => uuid, "available_uids" => uids[0]}, {"$pullAll" => { "available_uids" => uids }, "$inc" => { "available_capacity" => -uids.length, "max_uid" => -uids.length, "max_capacity" => -uids.length }} )
331
+ end
332
+
333
+ def inc_district_externally_reserved_uids_size(uuid)
334
+ Rails.logger.debug "inc_district_externally_reserved_uids_size(#{uuid})\n\n"
335
+ update( district_collection, {"_id" => uuid}, {"$inc" => { "externally_reserved_uids_size" => 1 }} )
336
+ end
337
+
338
+ def find_available_district(node_profile=nil)
339
+ node_profile = node_profile ? node_profile : "small"
340
+ MongoDataStore.rescue_con_failure do
341
+ hash = district_collection.find(
342
+ { "available_capacity" => { "$gt" => 0 },
343
+ "active_server_identities_size" => { "$gt" => 0 },
344
+ "node_profile" => node_profile}).sort(["available_capacity", "descending"]).limit(1).next
345
+ hash_to_district_ret(hash)
346
+ end
347
+ end
348
+
349
+ private
350
+
351
+ def find_application_template_by_tag(tag)
352
+ arr = application_template_collection.find( {"tags" => tag} )
353
+ return nil if arr.nil?
354
+ templates = []
355
+ arr.each do |hash|
356
+ hash.delete("_id")
357
+ templates.push(hash)
358
+ end
359
+ templates
360
+ end
361
+
362
+ def find_application_template(id)
363
+ hash = application_template_collection.find_one( {"_id" => id} )
364
+ return nil if hash.nil?
365
+ hash.delete("_id")
366
+ hash
367
+ end
368
+
369
+ def find_all_application_templates()
370
+ arr = application_template_collection.find()
371
+ return nil if arr.nil?
372
+ templates = []
373
+ arr.each do |hash|
374
+ hash.delete("_id")
375
+ templates.push(hash)
376
+ end
377
+ templates
378
+ end
379
+
380
+ def save_application_template(uuid, attrs)
381
+ Rails.logger.debug "MongoDataStore.save_application_template(#{uuid}, #{attrs.pretty_inspect})\n\n"
382
+ attrs["_id"] = uuid
383
+ application_template_collection.update({ "_id" => uuid }, attrs, { :upsert => true })
384
+ attrs.delete("_id")
385
+ end
386
+
387
+ def delete_application_template(uuid)
388
+ Rails.logger.debug "MongoDataStore.delete_application_template(#{uuid})\n\n"
389
+ application_template_collection.remove({ "_id" => uuid })
390
+ end
391
+
392
+ def application_template_collection
393
+ db.collection(@collections[:application_template])
394
+ end
395
+
396
+ def get_user(user_id)
397
+ hash = find_one( user_collection, "_id" => user_id )
398
+ return nil unless hash && !hash.empty?
399
+
400
+ user_hash_to_ret(hash)
401
+ end
402
+
403
+ def get_user_by_uuid(uuid)
404
+ hash = find_one( user_collection, "uuid" => uuid )
405
+ return nil unless hash && !hash.empty?
406
+
407
+ user_hash_to_ret(hash)
408
+ end
409
+
410
+ def get_user_by_app_uuid(uuid)
411
+ hash = find_one( user_collection, "apps.uuid" => uuid )
412
+ return nil unless hash && !hash.empty?
413
+
414
+ user_hash_to_ret(hash)
415
+ end
416
+
417
+ def get_user_by_domain_uuid(uuid)
418
+ hash = find_one( user_collection, "domains.uuid" => uuid )
419
+ return nil unless hash && !hash.empty?
420
+
421
+ user_hash_to_ret(hash)
422
+ end
423
+
424
+ def get_users(opts=nil)
425
+ MongoDataStore.rescue_con_failure do
426
+ query = {}
427
+ if opts
428
+ if opts[:with_gears]
429
+ query["apps.group_instances.gears.0"] = {"$exists" => true}
430
+ end
431
+ if opts[:with_usage]
432
+ query["usage_records.0"] = {"$exists" => true}
433
+ end
434
+ if opts[:with_plan]
435
+ query["$or"] = [{"pending_plan_id" => {"$ne" => nil}}, {"plan_id" => {"$ne" => nil}}]
436
+ end
437
+ end
438
+ mcursor = user_collection.find(query)
439
+ ret = []
440
+ mcursor.each do |hash|
441
+ if block_given?
442
+ yield user_hash_to_ret(hash)
443
+ else
444
+ ret.push(user_hash_to_ret(hash))
445
+ end
446
+ end
447
+ ret
448
+ end
449
+ end
450
+
451
+ def user_hash_to_ret(hash)
452
+ hash.delete("_id")
453
+ hash
454
+ end
455
+
456
+ def get_app(user_id, id)
457
+ hash = find_one( user_collection, { "_id" => user_id, "apps.name" => /^#{id}$/i }, :fields => ["apps"])
458
+ return nil unless hash && !hash.empty?
459
+
460
+ app_hash = nil
461
+ hash["apps"].each do |app|
462
+ if app["name"].downcase == id.downcase
463
+ app_hash = app
464
+ break
465
+ end
466
+ end if hash["apps"]
467
+ app_hash
468
+ end
469
+
470
+ def get_apps(user_id)
471
+ hash = find_one( user_collection, { "_id" => user_id }, :fields => ["apps"] )
472
+ return [] unless hash && !hash.empty?
473
+ return [] unless hash["apps"] && !hash["apps"].empty?
474
+ hash["apps"]
475
+ end
476
+
477
+ def get_domain(user_id, id)
478
+ hash = find_one( user_collection, { "_id" => user_id, "domains.uuid" => id }, :fields => ["domains"] )
479
+ return nil unless hash && !hash.empty?
480
+
481
+ domain_hash = nil
482
+ hash["domains"].each do |domain|
483
+ if domain["uuid"] == id
484
+ domain_hash = domain
485
+ break
486
+ end
487
+ end if hash["domains"]
488
+ domain_hash
489
+ end
490
+
491
+ def get_domains(user_id)
492
+ hash = find_one( user_collection, { "_id" => user_id }, :fields => ["domains"] )
493
+ return [] unless hash && !hash.empty?
494
+ return [] unless hash["domains"] && !hash["domains"].empty?
495
+ hash["domains"]
496
+ end
497
+
498
+
499
+ def put_user(user_id, changed_user_attrs)
500
+ changed_user_attrs.delete("apps")
501
+ changed_user_attrs.delete("domains")
502
+ changed_user_attrs.delete("consumed_gears")
503
+ changed_user_attrs.delete("usage_records")
504
+
505
+ update( user_collection, { "_id" => user_id }, { "$set" => changed_user_attrs } )
506
+ end
507
+
508
+ def add_user(user_id, user_attrs)
509
+ user_attrs["_id"] = user_id
510
+ user_attrs.delete("apps")
511
+ user_attrs.delete("domains")
512
+ insert(user_collection, user_attrs)
513
+ user_attrs.delete("_id")
514
+ end
515
+
516
+ def put_app(user_id, id, app_attrs)
517
+ app_attrs_to_internal(app_attrs)
518
+ ngears = app_attrs["ngears"]
519
+ ngears = ngears.to_i
520
+ app_attrs.delete("ngears")
521
+ usage_records = app_attrs["usage_records"]
522
+ app_attrs.delete("usage_records")
523
+ destroyed_gears = app_attrs["destroyed_gears"]
524
+ app_attrs.delete("destroyed_gears")
525
+
526
+ updates = { "$set" => { "apps.$" => app_attrs } }
527
+ if usage_records && !usage_records.empty?
528
+ updates["$pushAll"] = { "usage_records" => usage_records }
529
+ end
530
+ if ngears != 0
531
+ updates["$inc"] = { "consumed_gears" => ngears }
532
+ query = { "_id" => user_id, "apps.name" => id }
533
+ if ngears > 0
534
+ condition = "(this.consumed_gears + #{ngears}) <= this.max_gears"
535
+ query["$where"] = condition
536
+ end
537
+
538
+ if destroyed_gears && !destroyed_gears.empty?
539
+ query["apps.group_instances.gears.uuid"] = { "$all" => destroyed_gears }
540
+ end
541
+
542
+ hash = find_and_modify( user_collection, { :query => query,
543
+ :update => updates })
544
+ raise OpenShift::UserException.new("Consistency check failed. Could not update application '#{id}' for '#{user_id}'", 1) if hash == nil
545
+ else
546
+ update( user_collection, { "_id" => user_id, "apps.name" => id}, updates )
547
+ end
548
+ end
549
+
550
+ def add_app(user_id, id, app_attrs)
551
+ app_attrs_to_internal(app_attrs)
552
+ ngears = app_attrs["ngears"]
553
+ ngears = ngears.to_i
554
+ app_attrs.delete("ngears")
555
+ usage_records = app_attrs["usage_records"]
556
+ app_attrs.delete("usage_records")
557
+ app_attrs.delete("destroyed_gears")
558
+
559
+ updates = { "$push" => { "apps" => app_attrs }, "$inc" => { "consumed_gears" => ngears }}
560
+ if usage_records && !usage_records.empty?
561
+ updates["$pushAll"] = { "usage_records" => usage_records }
562
+ end
563
+
564
+ hash = find_and_modify( user_collection, { :query => { "_id" => user_id, "apps.name" => { "$ne" => id }, "domains" => {"$exists" => true},
565
+ "$where" => "((this.consumed_gears + #{ngears}) <= this.max_gears) && (this.domains.length > 0)"},
566
+ :update => updates })
567
+ raise OpenShift::UserException.new("Failed: Either application limit has already reached or " +
568
+ "domain doesn't exist for '#{user_id}'", 104) if hash == nil
569
+ end
570
+
571
+ def put_domain(user_id, id, domain_attrs)
572
+ #TODO: FIXME
573
+ # domain_updates = {}
574
+ # domain_attrs.each do |k, v|
575
+ # domain_updates["domains.$.#{k}"] = v
576
+ # domain_updates["apps.$.domain.#{k}"] = v
577
+ # end
578
+ # update( user_collection, { "_id" => user_id, "domains.uuid" => id}, { "$set" => domain_updates } )
579
+ update( user_collection, { "_id" => user_id, "domains.uuid" => id}, { "$set" => { "domains.$" => domain_attrs }} )
580
+ end
581
+
582
+ #TODO: Revisit the query once we support multiple domains per user
583
+ def add_domain(user_id, id, domain_attrs)
584
+ hash = find_and_modify( user_collection, { :query => { "_id" => user_id, "domains.uuid" => { "$ne" => id },
585
+ "$or" => [{"domains" => {"$exists" => true, "$size" => 0}}, {"domains" => {"$exists" => false}}]},
586
+ :update => { "$push" => { "domains" => domain_attrs } } })
587
+ raise OpenShift::UserException.new("Domain already exists for #{user_id}", 158) if hash == nil
588
+ end
589
+
590
+ def delete_user(user_id)
591
+ remove( user_collection, { "_id" => user_id, "$or" => [{"domains" => {"$exists" => true, "$size" => 0}},
592
+ {"domains" => {"$exists" => false}}], "$where" => "this.consumed_gears == 0"} )
593
+ end
594
+
595
+ def delete_app(user_id, id)
596
+ update( user_collection, { "_id" => user_id, "apps.name" => id},
597
+ { "$pull" => { "apps" => {"name" => id }}})
598
+ end
599
+
600
+ def put_usage_record(user_id, id, usage_attrs)
601
+ update( user_collection, { "_id" => user_id, "usage_records.uuid" => id}, { "$set" => { "usage_records.$" => usage_attrs }} )
602
+ end
603
+
604
+ def delete_usage_record(user_id, id)
605
+ update( user_collection, { "_id" => user_id, },
606
+ { "$pull" => { "usage_records" => {"uuid" => id }}} )
607
+ end
608
+
609
+ def app_attrs_to_internal(app_attrs)
610
+ app_attrs
611
+ end
612
+
613
+ def delete_domain(user_id, id)
614
+ hash = find_and_modify( user_collection, { :query => { "_id" => user_id, "domains.uuid" => id,
615
+ "$or" => [{"apps" => {"$exists" => true, "$size" => 0}},
616
+ {"apps" => {"$exists" => false}}] },
617
+ :update => { "$pull" => { "domains" => {"uuid" => id } } }})
618
+ raise OpenShift::UserException.new("Could not delete domain." +
619
+ "Domain has valid applications.", 128) if hash == nil
620
+ end
621
+
622
+ #district
623
+
624
+ def district_collection(connection_opts=nil)
625
+ db(connection_opts).collection(@collections[:district])
626
+ end
627
+
628
+ def cursor_to_district_hash(cursor)
629
+ return [] unless cursor
630
+
631
+ districts = []
632
+ cursor.each do |hash|
633
+ districts.push(hash_to_district_ret(hash))
634
+ end
635
+ districts
636
+ end
637
+
638
+ def hash_to_district_ret(hash)
639
+ return nil unless hash
640
+ hash.delete("_id")
641
+ if hash["server_identities"]
642
+ server_identities = {}
643
+ hash["server_identities"].each do |server_identity|
644
+ name = server_identity["name"]
645
+ server_identity.delete("name")
646
+ server_identities[name] = server_identity
647
+ end
648
+ hash["server_identities"] = server_identities
649
+ else
650
+ hash["server_identities"] = {}
651
+ end
652
+ hash
653
+ end
654
+
655
+ def district_attrs_to_internal(district_attrs)
656
+ if district_attrs
657
+ if district_attrs["server_identities"]
658
+ server_identities = []
659
+ district_attrs["server_identities"].each do |name, server_identity|
660
+ server_identity["name"] = name
661
+ server_identities.push(server_identity)
662
+ end
663
+ district_attrs["server_identities"] = server_identities
664
+ else
665
+ district_attrs["server_identities"] = []
666
+ end
667
+ end
668
+ district_attrs
669
+ end
670
+ end
671
+ end