openshift-origin-controller 1.3.2

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 (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,27 @@
1
+ class ApplicationTemplate < OpenShift::UserModel
2
+ attr_accessor :uuid, :display_name, :descriptor_yaml, :git_url, :tags, :gear_cost, :metadata
3
+ primary_key :uuid
4
+
5
+ def initialize(display_name=nil,descriptor_yaml=nil,git_url=nil,tags=[], gear_cost=0, metadata = {})
6
+ self.display_name, self.descriptor_yaml, self.git_url, self.tags, self.gear_cost, self.metadata =
7
+ display_name, descriptor_yaml, git_url, tags, gear_cost, metadata
8
+ self.uuid = OpenShift::Model.gen_uuid
9
+ end
10
+
11
+ def self.find(id)
12
+ super(nil,id)
13
+ end
14
+
15
+ def self.find_all(tag=nil)
16
+ tag = {:tag => tag} unless tag.nil?
17
+ super(nil,tag)
18
+ end
19
+
20
+ def save
21
+ super(nil)
22
+ end
23
+
24
+ def delete
25
+ super(nil)
26
+ end
27
+ end
@@ -0,0 +1,51 @@
1
+ class CartridgeCache
2
+ def self.get_cached(key, opts={})
3
+ unless Rails.configuration.action_controller.perform_caching
4
+ if block_given?
5
+ return yield
6
+ end
7
+ end
8
+
9
+ val = Rails.cache.read(key)
10
+ unless val
11
+ if block_given?
12
+ val = yield
13
+ if val
14
+ Rails.cache.write(key, val, opts)
15
+ end
16
+ end
17
+ end
18
+
19
+ return val
20
+ end
21
+
22
+ def self.cartridges
23
+ get_cached("all_cartridges", :expires_in => 1.day) {OpenShift::ApplicationContainerProxy.find_one().get_available_cartridges}
24
+ end
25
+
26
+ FRAMEWORK_CART_NAMES = [#RHEL6 cartridges
27
+ "python-2.6", "jenkins-1.4", "ruby-1.8", "ruby-1.9",
28
+ "diy-0.1", "php-5.3", "jbossas-7", "jbosseap-6.0", "jbossews-1.0",
29
+ "perl-5.10", "nodejs-0.6", "zend-5.6",
30
+ ]
31
+ def self.cartridge_names(cart_type=nil)
32
+ cart_names = cartridges.map{|c| c.name}
33
+
34
+ if cart_type == 'standalone'
35
+ return cart_names & FRAMEWORK_CART_NAMES
36
+ elsif cart_type == 'embedded'
37
+ return (cart_names - FRAMEWORK_CART_NAMES)
38
+ else
39
+ return cart_names
40
+ end
41
+ end
42
+
43
+ def self.find_cartridge(capability)
44
+ carts = self.cartridges
45
+ carts.each do |cart|
46
+ return cart if cart.all_capabilities.include?(capability)
47
+ return cart if cart.name == capability
48
+ end
49
+ return nil
50
+ end
51
+ end
@@ -0,0 +1,334 @@
1
+ class CloudUser < OpenShift::UserModel
2
+ attr_accessor :login, :uuid, :system_ssh_keys, :env_vars, :ssh_keys, :domains, :max_gears, :consumed_gears, :applications,
3
+ :auth_method, :save_jobs, :usage_records, :gear_usage_records, :capabilities, :parent_user_login,
4
+ :plan_id, :usage_account_id, :pending_plan_id, :pending_plan_uptime
5
+ primary_key :login
6
+ exclude_attributes :applications, :auth_method, :save_jobs, :usage_records
7
+ require_update_attributes :system_ssh_keys, :env_vars, :ssh_keys, :domains
8
+ private :login=, :uuid=, :save_jobs=
9
+
10
+ validates_each :login do |record, attribute, val|
11
+ record.errors.add(attribute, {:message => "Invalid characters found in login '#{val}' ", :exit_code => 107}) if val =~ /["\$\^<>\|%\/;:,\\\*=~]/
12
+ end
13
+
14
+ validates_each :ssh_keys do |record, attribute, val|
15
+ val.each do |key_name, key_info|
16
+ if !(key_name =~ /\A[A-Za-z0-9]+\z/)
17
+ record.errors.add attribute, {:message => "Invalid key name: #{key_name}", :exit_code => 117}
18
+ end
19
+ if !Key::VALID_SSH_KEY_TYPES.include?(key_info['type'])
20
+ record.errors.add attribute, {:message => "Invalid key type: #{key_info['type']}", :exit_code => 116}
21
+ end
22
+ if !(key_info['key'] =~ /\A[A-Za-z0-9\+\/=]+\z/)
23
+ record.errors.add attribute, {:message => "Invalid ssh key: #{key_info['key']}", :exit_code => 108}
24
+ end
25
+ end if val
26
+ end
27
+
28
+ def initialize(login=nil, ssh=nil, ssh_type=nil, key_name=nil, capabilities=nil,
29
+ parent_login=nil)
30
+ super()
31
+ if not ssh.nil?
32
+ ssh_type = Key::DEFAULT_SSH_KEY_TYPE if ssh_type.to_s.strip.length == 0
33
+ self.ssh_keys = {} unless self.ssh_keys
34
+ key_name = Key::DEFAULT_SSH_KEY_NAME if key_name.to_s.strip.length == 0
35
+ self.ssh_keys[key_name] = { "key" => ssh, "type" => ssh_type }
36
+ else
37
+ self.ssh_keys = {} unless self.ssh_keys
38
+ end
39
+ self.login = login
40
+ self.domains = []
41
+ self.max_gears = Rails.configuration.openshift[:default_max_gears]
42
+ self.capabilities = capabilities || {}
43
+ unless self.capabilities.has_key?('gear_sizes')
44
+ # set the user's gear capabilities to default if not specified
45
+ self.capabilities['gear_sizes'] =
46
+ Rails.application.config.openshift[:default_gear_capabilities] ||
47
+ [ Rails.application.config.openshift[:default_gear_size] ]
48
+ end
49
+ self.parent_user_login = parent_login
50
+
51
+ self.consumed_gears = 0
52
+ end
53
+
54
+ def save
55
+ resultIO = ResultIO.new
56
+ unless persisted?
57
+ #new user record
58
+ resultIO.append(create())
59
+ end
60
+
61
+ if applications && !applications.empty? && save_jobs
62
+ gears = []
63
+ tag = ""
64
+
65
+ applications.each do |app|
66
+ app.gears.each do |gear|
67
+ if !app.destroyed_gears || !app.destroyed_gears.include?(gear.uuid)
68
+ gears << gear
69
+ end
70
+ end
71
+ end
72
+
73
+ handle = RemoteJob.create_parallel_job
74
+
75
+ RemoteJob.run_parallel_on_gears(gears, handle) { |exec_handle, gear|
76
+ if save_jobs['removes']
77
+ save_jobs['removes'].each do |action, values|
78
+ case action
79
+ when 'ssh_keys'
80
+ values.each do |value|
81
+ ssh_key = value[0]
82
+ ssh_key_comment = value[1]
83
+ job = gear.ssh_key_job_remove(ssh_key, ssh_key_comment)
84
+ RemoteJob.add_parallel_job(exec_handle, tag, gear, job)
85
+ end
86
+ when 'env_vars'
87
+ values.each do |value|
88
+ env_var_key = value[0]
89
+ job = gear.env_var_job_remove(env_var_key)
90
+ RemoteJob.add_parallel_job(exec_handle, tag, gear, job)
91
+ end
92
+ when 'broker_auth_keys'
93
+ values.each do |value|
94
+ app_uuid = value[0]
95
+ if app_uuid == gear.app.uuid
96
+ job = gear.broker_auth_key_job_remove
97
+ RemoteJob.add_parallel_job(exec_handle, tag, gear, job)
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+ if save_jobs['adds']
104
+ save_jobs['adds'].each do |action, values|
105
+ case action
106
+ when 'ssh_keys'
107
+ values.each do |value|
108
+ ssh_key = value[0]
109
+ ssh_key_type = value[1]
110
+ ssh_key_comment = value[2]
111
+ job = gear.ssh_key_job_add(ssh_key, ssh_key_type, ssh_key_comment)
112
+ RemoteJob.add_parallel_job(exec_handle, tag, gear, job)
113
+ end
114
+ when 'env_vars'
115
+ values.each do |value|
116
+ env_var_key = value[0]
117
+ env_var_value = value[1]
118
+ job = gear.env_var_job_add(env_var_key, env_var_value)
119
+ RemoteJob.add_parallel_job(exec_handle, tag, gear, job)
120
+ end
121
+ when 'broker_auth_keys'
122
+ values.each do |value|
123
+ app_uuid = value[0]
124
+ if app_uuid == gear.app.uuid
125
+ iv = value[1]
126
+ token = value[2]
127
+ job = gear.broker_auth_key_job_add(iv, token)
128
+ RemoteJob.add_parallel_job(exec_handle, tag, gear, job)
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ }
135
+ RemoteJob.get_parallel_run_results(handle) { |tag, gear, output, status|
136
+ if status != 0
137
+ raise OpenShift::NodeException.new("Error updating settings on gear: #{gear} with status: #{status} and output: #{output}", 143)
138
+ end
139
+ }
140
+ save_jobs['removes'].clear if save_jobs['removes']
141
+ save_jobs['adds'].clear if save_jobs['adds']
142
+ end
143
+
144
+ super(@login)
145
+
146
+ resultIO
147
+ end
148
+
149
+ def applications
150
+ @applications
151
+ end
152
+
153
+ def domains
154
+ @domains
155
+ end
156
+
157
+ def self.find_by_uuid(obj_type_of_uuid, uuid)
158
+ hash = OpenShift::DataStore.instance.find_by_uuid(obj_type_of_uuid, uuid)
159
+ return nil unless hash
160
+ hash_to_obj(hash)
161
+ end
162
+
163
+ def self.find_subaccounts_by_parent_login(parent_login)
164
+ hash_list = OpenShift::DataStore.instance.find_subaccounts_by_parent_login(parent_login)
165
+ return nil if hash_list.nil? or hash_list.empty?
166
+ hash_list.map {|hash| hash_to_obj(hash) }
167
+ end
168
+
169
+ def self.hash_to_obj(hash)
170
+ apps = []
171
+ if hash["apps"]
172
+ hash["apps"].each do |app_hash|
173
+ app = Application.hash_to_obj(app_hash)
174
+ apps.push(app)
175
+ end
176
+ hash.delete("apps")
177
+ end
178
+ domains = []
179
+ if hash["domains"]
180
+ hash["domains"].each do |domain_hash|
181
+ domain = Domain.hash_to_obj(domain_hash)
182
+ domains.push(domain)
183
+ end
184
+ hash.delete("apps")
185
+ end
186
+ usage_records = []
187
+ if hash["usage_records"]
188
+ hash["usage_records"].each do |usage_hash|
189
+ usage_record = UsageRecord.hash_to_obj(usage_hash)
190
+ usage_records.push(usage_record)
191
+ end
192
+ hash.delete("usage_records")
193
+ end
194
+ user = super(hash)
195
+ user.applications = apps
196
+ apps.each do |app|
197
+ app.user = user
198
+ app.reset_state
199
+ end
200
+
201
+ user.domains = domains
202
+ domains.each do |domain|
203
+ domain.user = user
204
+ end
205
+
206
+ user.usage_records = usage_records
207
+ usage_records.each do |usage_record|
208
+ usage_record.user = user
209
+ end
210
+
211
+ user
212
+ end
213
+
214
+ def force_delete
215
+ self.applications.each do |app|
216
+ app.cleanup_and_delete()
217
+ end if self.applications && !self.applications.empty?
218
+ self.domains.each do |domain|
219
+ domain.delete
220
+ end if self.domains && !self.domains.empty?
221
+ user = CloudUser.find(self.login)
222
+ user.delete if user
223
+ end
224
+
225
+ def delete
226
+ if (self.domains && !self.domains.empty?) or (self.applications && !self.applications.empty?)
227
+ raise OpenShift::UserException.new("Error: User '#{@login}' has valid domain or applications.", 139)
228
+ end
229
+ super(@login)
230
+ end
231
+
232
+ def self.find(login)
233
+ super(login,login)
234
+ end
235
+
236
+ def self.find_all_logins(opts=nil)
237
+ OpenShift::DataStore.instance.find_all_logins(opts)
238
+ end
239
+
240
+ def add_system_ssh_key(app_name, key)
241
+ self.system_ssh_keys = {} unless self.system_ssh_keys
242
+ self.system_ssh_keys[app_name] = key
243
+ add_save_job('adds', 'ssh_keys', [key, nil, app_name])
244
+ end
245
+
246
+ def remove_system_ssh_key(app_name)
247
+ self.system_ssh_keys = {} unless self.system_ssh_keys
248
+ key = self.system_ssh_keys[app_name]
249
+ return unless key
250
+ self.system_ssh_keys.delete app_name
251
+ add_save_job('removes', 'ssh_keys', [key, app_name])
252
+ end
253
+
254
+ def add_ssh_key(key_name, key, key_type=nil)
255
+ self.ssh_keys = {} unless self.ssh_keys
256
+ key_type = Key::DEFAULT_SSH_KEY_TYPE if key_type.to_s.strip.length == 0
257
+ self.ssh_keys[key_name] = { "key" => key, "type" => key_type }
258
+ add_save_job('adds', 'ssh_keys', [key, key_type, key_name])
259
+ end
260
+
261
+ def remove_ssh_key(key_name)
262
+ self.ssh_keys = {} unless self.ssh_keys
263
+
264
+ # validations
265
+ raise OpenShift::UserKeyException.new("ERROR: Key name '#{key_name}' doesn't exist for user #{self.login}", 118) if not self.ssh_keys.has_key?(key_name)
266
+
267
+ add_save_job('removes', 'ssh_keys', [self.ssh_keys[key_name]["key"], key_name])
268
+ self.ssh_keys.delete key_name
269
+ end
270
+
271
+ def update_ssh_key(key, key_type=nil, key_name=nil)
272
+ key_name = Key::DEFAULT_SSH_KEY_NAME if key_name.to_s.strip.length == 0
273
+ remove_ssh_key(key_name)
274
+ add_ssh_key(key_name, key, key_type)
275
+ end
276
+
277
+ def get_ssh_key
278
+ raise OpenShift::UserKeyException.new("ERROR: No ssh keys found for user #{self.login}",
279
+ 123) if self.ssh_keys.nil? or not self.ssh_keys.kind_of?(Hash)
280
+ key_name = (self.ssh_keys.key?(Key::DEFAULT_SSH_KEY_NAME)) ? Key::DEFAULT_SSH_KEY_NAME : self.ssh_keys.keys[0]
281
+ self.ssh_keys[key_name]
282
+ end
283
+
284
+ def add_env_var(key, value)
285
+ self.env_vars = {} unless self.env_vars
286
+ self.env_vars[key] = value
287
+ add_save_job('adds', 'env_vars', [key, value])
288
+ end
289
+
290
+ def remove_env_var(key)
291
+ self.env_vars = {} unless self.env_vars
292
+ self.env_vars.delete key
293
+ add_save_job('removes', 'env_vars', [key])
294
+ end
295
+
296
+ def add_save_job(section, object, value)
297
+ self.save_jobs = {} unless self.save_jobs
298
+ self.save_jobs[section] = {} unless self.save_jobs[section]
299
+ self.save_jobs[section][object] = [] unless self.save_jobs[section][object]
300
+ self.save_jobs[section][object] << value
301
+ end
302
+
303
+ private
304
+
305
+ def create
306
+ resultIO = ResultIO.new
307
+ notify_observers(:before_cloud_user_create)
308
+ begin
309
+ user = CloudUser.find(@login)
310
+ if user
311
+ #TODO Rework when we allow multiple domains per user
312
+ raise OpenShift::UserException.new("User with login '#{@login}' already exists", 102, resultIO)
313
+ end
314
+
315
+ begin
316
+ Rails.logger.debug "DEBUG: Attempting to add user '#{@login}'"
317
+ resultIO.debugIO << "Creating user entry login:#{@login}"
318
+ @uuid = OpenShift::Model.gen_uuid
319
+ notify_observers(:cloud_user_create_success)
320
+ rescue Exception => e
321
+ Rails.logger.debug e
322
+ begin
323
+ notify_observers(:cloud_user_create_error)
324
+ ensure
325
+ raise
326
+ end
327
+ end
328
+ ensure
329
+ notify_observers(:after_cloud_user_create)
330
+ end
331
+ resultIO
332
+ end
333
+
334
+ end
@@ -0,0 +1,228 @@
1
+ class ComponentInstance < OpenShift::Model
2
+ attr_accessor :state, :parent_cart_name, :parent_cart_profile, :parent_component_name, :parent_cart_group,
3
+ :name, :dependencies, :group_instance_name, :exec_order, :cart_data, :cart_properties, :addtl_fs_gb
4
+
5
+ def initialize (cartname=nil, profname=nil, groupname=nil, compname=nil, pathname=nil, gi=nil)
6
+ self.name = pathname
7
+ self.parent_cart_name = cartname
8
+ self.parent_cart_profile = profname
9
+ self.parent_cart_group = groupname
10
+ self.group_instance_name = gi.name unless gi.nil?
11
+ self.parent_component_name = compname
12
+ self.dependencies = []
13
+ self.exec_order = []
14
+ self.cart_data = []
15
+ self.cart_properties = {}
16
+ self.addtl_fs_gb = 0
17
+ end
18
+
19
+ def process_cart_data(data)
20
+ data.chomp! if data
21
+ self.cart_data.push data
22
+ end
23
+
24
+ def process_cart_properties(properties)
25
+ properties.each do |key, value|
26
+ self.cart_properties[key] = value
27
+ end
28
+ end
29
+
30
+ def get_component_definition(app)
31
+ if self.parent_cart_name == app.name
32
+ cart = app
33
+ else
34
+ cart = CartridgeCache::find_cartridge(self.parent_cart_name)
35
+ end
36
+ raise Exception.new("Cartridge #{self.parent_cart_name} not found") if cart.nil?
37
+ profile = cart.profiles(self.parent_cart_profile)
38
+ group = profile.groups(self.parent_cart_group)
39
+ comp_name = group.component_refs(self.parent_component_name).component
40
+ comp = profile.components(comp_name)
41
+ return comp,profile,cart
42
+ end
43
+
44
+ def elaborate(app)
45
+ comp,profile,cart = get_component_definition(app)
46
+
47
+ self.dependencies = []
48
+
49
+ # cart map has all the sub-cartridges that will get instantiated through this component instance
50
+ cart_map, cart_map_keys = get_cartridges_for_dependencies(comp, cart)
51
+
52
+ group_list = cart_map_keys.map { |key|
53
+ cartprofile = cart_map[key]
54
+ elaborate_cartridge(cartprofile[0], cartprofile[1], app)
55
+ }.flatten
56
+
57
+ self.dependencies.each do |dep|
58
+ cinst = app.comp_instance_map[dep]
59
+ new_conns = ComponentInstance.establish_connections(cinst, self, app)
60
+ new_conns.each { |conn|
61
+ if conn.from_connector.type.match(/^FILESYSTEM/) or conn.from_connector.type.match(/^AFUNIX/)
62
+ self.exec_order << dep if not self.exec_order.include? dep
63
+ end
64
+ }
65
+ end
66
+
67
+ ComponentInstance.establish_connections(self, self, app)
68
+
69
+ resolve_exec_order(app)
70
+
71
+ return group_list
72
+ end
73
+
74
+ def resolve_exec_order(app)
75
+ deps = self.dependencies.dup
76
+ self.dependencies.each { |dep|
77
+ depinst = app.comp_instance_map[dep]
78
+ comp,p,c = depinst.get_component_definition(app)
79
+ if comp.depends_service and !comp.depends_service.empty?
80
+ comp.depends_service.each { |dependent_cart|
81
+ deps.each { |parent_dep|
82
+ if parent_dep.include? dependent_cart
83
+ # add parent_dep to exec_order
84
+ self.exec_order << parent_dep if not self.exec_order.include? parent_dep
85
+ end
86
+ }
87
+ }
88
+ end
89
+ self.exec_order << dep if not self.exec_order.include? dep
90
+ }
91
+ end
92
+
93
+ def self.establish_connections(inst1, inst2, app)
94
+ comp1,prof1,cart1 = inst1.get_component_definition(app)
95
+ comp2,prof2,cart2 = inst2.get_component_definition(app)
96
+
97
+ new_connections = []
98
+
99
+ comp1.publishes.each do |pub|
100
+ comp2.subscribes.each do |sub|
101
+ next if not pub.type==sub.type
102
+ ce = ConnectionEndpoint.new(inst1, inst2, pub, sub)
103
+ app.conn_endpoints_list << ce
104
+ new_connections << ce
105
+ end
106
+ end
107
+ return if inst1==inst2
108
+ comp1.subscribes.each do |sub|
109
+ comp2.publishes.each do |pub|
110
+ next if not pub.type==sub.type
111
+ ce = ConnectionEndpoint.new(inst2, inst1, pub, sub)
112
+ app.conn_endpoints_list << ce
113
+ new_connections << ce
114
+ end
115
+ end
116
+ new_connections
117
+ end
118
+
119
+ def elaborate_cartridge(cart, profile, app)
120
+ group_list = profile.groups.map do |g|
121
+ gpath = self.name + cart.get_name_prefix + g.get_name_prefix
122
+ gi = app.working_group_inst_hash[gpath]
123
+ if gi.nil?
124
+ gi = app.group_instance_map[gpath]
125
+ if gi.nil?
126
+ gi = GroupInstance.new(app, cart.name, profile.name, g.name, gpath)
127
+ else
128
+ gi.merge(cart.name, profile.name, g.name, gpath)
129
+ end
130
+ else
131
+ gi.merge(cart.name, profile.name, g.name, gpath)
132
+ end
133
+ app.group_instance_map[gpath] = gi
134
+ app.working_group_inst_hash[gpath] = gi
135
+ sub_components = gi.elaborate(profile, g, self.name, app)
136
+ self.dependencies += sub_components
137
+ gi
138
+ end
139
+
140
+ # make connection_endpoints out of provided connections
141
+ profile.connections.each do |conn|
142
+ inst1 = ComponentInstance::find_component_in_cart(profile, app, conn.components[0], self.name)
143
+ inst2 = ComponentInstance::find_component_in_cart(profile, app, conn.components[1], self.name)
144
+ ComponentInstance::establish_connections(inst1, inst2, app)
145
+ end
146
+
147
+ profile.group_overrides.each do |n, v|
148
+ from_cinst = ComponentInstance::find_component_in_cart(profile, app, n, self.name)
149
+ to_cinst = ComponentInstance::find_component_in_cart(profile, app, v, self.name)
150
+ next if from_cinst.nil? or to_cinst.nil?
151
+ app.group_override_map[from_cinst.group_instance_name] = to_cinst.group_instance_name
152
+ app.group_override_map[to_cinst.group_instance_name] = from_cinst.group_instance_name
153
+ end
154
+
155
+ return group_list
156
+ end
157
+
158
+ def self.find_component_in_cart(profile, app, comp_name, parent_path)
159
+ # FIXME : comp_name could be a component_name only, feature_name, cartridge_name that
160
+ # one of the components depend upon, or a hierarchical name
161
+
162
+ comp_name_list = comp_name.split("/")
163
+ comp_name = comp_name_list.first
164
+ rest = comp_name_list[1..-1]
165
+
166
+ group_comp_refs = profile.groups.map { |g| g.component_refs }
167
+ comp_refs = group_comp_refs.flatten
168
+ comp_inst = nil
169
+ comp_refs.each { |comp_ref|
170
+ name_prefix = comp_ref.get_name_prefix(profile)
171
+ comp_inst = app.comp_instance_map[parent_path + name_prefix]
172
+ next if comp_inst.nil?
173
+ if name_prefix!=""
174
+ next if comp_ref.name!=comp_name
175
+ return comp_inst if rest.length==0
176
+ comp_name = rest.first
177
+ rest = rest[1..-1]
178
+ end
179
+ comp_inst.dependencies.each { |dep|
180
+ dep_inst = app.comp_instance_map[dep]
181
+ next if dep_inst.parent_cart_name != comp_name
182
+ return dep_inst if rest.length==0
183
+ c, dep_profile, ca = dep_inst.get_component_definition(app)
184
+ found_inst = self.find_component_in_cart(dep_profile, app, rest.join('/'), dep_inst.name)
185
+ return found_inst if not found_inst.nil?
186
+ }
187
+ }
188
+
189
+ return comp_inst
190
+ end
191
+
192
+ def set_additional_quota(app, fs_gb, inodes=nil)
193
+ changed_gbs = fs_gb - @addtl_fs_gb
194
+ gi = app.group_instance_map[self.group_instance_name]
195
+ gi.update_quota(changed_gbs, inodes)
196
+ @addtl_fs_gb = fs_gb
197
+ end
198
+
199
+ def self.collect_exec_order(app, cinst, return_list)
200
+ cinst.exec_order.each do |dep|
201
+ depinst = app.comp_instance_map[dep]
202
+ collect_exec_order(app, depinst, return_list)
203
+ return_list << dep if not return_list.include? dep
204
+ end
205
+ end
206
+
207
+ def get_cartridges_for_dependencies(comp, cart)
208
+ # resolve features into cartridges - two features may resolve
209
+ # into one cartridge only, e.g. depends = [db,db-failover]
210
+ # will resolve into one mysql cartridge being instantiated with (master/slave) profile
211
+ cart_map = {}
212
+ cart_map_keys = []
213
+ depends = comp.depends + cart.requires_feature
214
+
215
+ depends.each do |feature|
216
+ cart = CartridgeCache::find_cartridge(feature)
217
+ raise OpenShift::UserException.new("Invalid cartridge specified: #{feature}",1) if cart.nil?
218
+ capability = feature
219
+ capability = nil if feature==cart.name
220
+ profile = cart.find_profile(capability)
221
+ key = cart.name + profile.name
222
+ cart_map_keys << key if not cart_map_keys.include? key
223
+ cart_map[key] = [cart, profile]
224
+ end
225
+ return cart_map, cart_map_keys
226
+ end
227
+
228
+ end