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
data/COPYRIGHT ADDED
@@ -0,0 +1 @@
1
+ Copyright 2012 Red Hat, Inc. and/or its affiliates.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in openshift-origin-controller.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,12 @@
1
+ Licensed under the Apache License, Version 2.0 (the "License");
2
+ you may not use this file except in compliance with the License.
3
+ You may obtain a copy of the License at
4
+
5
+ http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software
8
+ distributed under the License is distributed on an "AS IS" BASIS,
9
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ See the License for the specific language governing permissions and
11
+ limitations under the License.
12
+
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ Notice of Export Control Law
2
+
3
+ This software distribution includes cryptographic software that is subject to the U.S. Export Administration Regulations (the "*EAR*") and other U.S. and foreign laws and may not be exported, re-exported or transferred (a) to any country listed in Country Group E:1 in Supplement No. 1 to part 740 of the EAR (currently, Cuba, Iran, North Korea, Sudan & Syria); (b) to any prohibited destination or to any end user who has been prohibited from participating in U.S. export transactions by any federal agency of the U.S. government; or (c) for use in connection with the design, development or production of nuclear, chemical or biological weapons, or rocket systems, space launch vehicles, or sounding rockets, or unmanned air vehicle systems.You may not download this software or technical information if you are located in one of these countries or otherwise subject to these restrictions. You may not provide this software or technical information to individuals or entities located in one of these countries or otherwise subject to these restrictions. You are also responsible for compliance with foreign law requirements applicable to the import, export and use of this software and technical information.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ #require "bundler/gem_tasks"
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new(:test) do |t|
6
+ t.libs << 'test'
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ t.verbose = true
9
+ end
@@ -0,0 +1,115 @@
1
+ class AppEventsController < BaseController
2
+ respond_to :xml, :json
3
+ before_filter :authenticate, :check_version
4
+
5
+ # POST /domains/[domain_id]/applications/[application_id]/events
6
+ def create
7
+ domain_id = params[:domain_id]
8
+ id = params[:application_id]
9
+ event = params[:event]
10
+ server_alias = params[:alias]
11
+
12
+ domain = Domain.get(@cloud_user, domain_id)
13
+ return render_error(:not_found, "Domain #{domain_id} not found", 127,
14
+ "APPLICATION_EVENT") if !domain || !domain.hasAccess?(@cloud_user)
15
+
16
+ @domain_name = domain.namespace
17
+ application = get_application(id)
18
+ return render_error(:not_found, "Application '#{id}' not found", 101,
19
+ "APPLICATION_EVENT") unless application
20
+
21
+ @application_name = application.name
22
+ @application_uuid = application.uuid
23
+ return render_error(:unprocessable_entity, "Alias must be specified for adding or removing application alias.", 126,
24
+ "APPLICATION_EVENT", "event") if ['add-alias', 'remove-alias'].include?(event) && !server_alias
25
+ return render_error(:unprocessable_entity, "Reached gear limit of #{@cloud_user.max_gears}", 104,
26
+ "APPLICATION_EVENT") if (event == 'scale-up') && (@cloud_user.consumed_gears >= @cloud_user.max_gears)
27
+
28
+ msg = "Added #{event} to application #{id}"
29
+ begin
30
+ case event
31
+ when "start"
32
+ application.start
33
+ msg = "Application #{id} has started"
34
+ when "stop"
35
+ application.stop
36
+ msg = "Application #{id} has stopped"
37
+ when "force-stop"
38
+ application.force_stop
39
+ msg = "Application #{id} has forcefully stopped"
40
+ when "restart"
41
+ application.restart
42
+ msg = "Application #{id} has restarted"
43
+ when "expose-port"
44
+ application.expose_port
45
+ msg = "Application #{id} has exposed port"
46
+ when "conceal-port"
47
+ application.conceal_port
48
+ msg = "Application #{id} has concealed port"
49
+ when "show-port"
50
+ r = application.show_port
51
+ msg = "Application #{id} called show port"
52
+ msg += ": #{r.resultIO.string.chomp}" if !r.resultIO.string.empty?
53
+ when "add-alias"
54
+ applications = Application.find_all(@cloud_user)
55
+ applications.each do |app|
56
+ app.aliases.each do |a|
57
+ if a.casecmp(server_alias) == 0
58
+ return render_error(:unprocessable_entity, "Alias already in use.", 140,
59
+ "APPLICATION_EVENT", "event")
60
+ end
61
+ end unless app.aliases.nil?
62
+ end
63
+ r = application.add_alias(server_alias)
64
+ msg = "Application #{id} has added alias"
65
+ msg += ": #{r.resultIO.string.chomp}" if !r.resultIO.string.empty?
66
+ when "remove-alias"
67
+ r = application.remove_alias(server_alias)
68
+ msg = "Application #{id} has removed alias"
69
+ msg += ": #{r.resultIO.string.chomp}" if !r.resultIO.string.empty?
70
+ when "scale-up"
71
+ application.scaleup
72
+ msg = "Application #{id} has scaled up"
73
+ when "scale-down"
74
+ application.scaledown
75
+ msg = "Application #{id} has scaled down"
76
+ when 'tidy'
77
+ r = application.tidy
78
+ msg = "Application #{id} called tidy"
79
+ msg += ": #{r.resultIO.string.chomp}" if !r.resultIO.string.empty?
80
+ when 'reload'
81
+ r = application.reload
82
+ msg = "Application #{id} called reload"
83
+ msg += ": #{r.resultIO.string.chomp}" if !r.resultIO.string.empty?
84
+ when "thread-dump"
85
+ r = application.threaddump
86
+ msg = !r.errorIO.string.empty? ? r.errorIO.string.chomp : r.resultIO.string.chomp
87
+ #TODO: We need to reconsider how we are reporting messages to the client
88
+ success_msg = "Application event '#{event}' successful" unless msg.include?("not supported")
89
+ message = Message.new(:result, msg, 0)
90
+ application = get_application(id)
91
+ if $requested_api_version >= 1.2
92
+ app = RestApplication12.new(application, get_url, nolinks)
93
+ else
94
+ app = RestApplication10.new(application, get_url, nolinks)
95
+ end
96
+ render_success(:ok, "application", app, "#{event.sub('-', '_').upcase}_APPLICATION",
97
+ success_msg, true, nil, [message])
98
+ return
99
+ else
100
+ return render_error(:unprocessable_entity, "Invalid application event '#{event}' specified",
101
+ 126, "APPLICATION_EVENT", "event")
102
+ end
103
+ rescue Exception => e
104
+ return render_exception(e, "#{event.sub('-', '_').upcase}_APPLICATION")
105
+ end
106
+ application = get_application(id)
107
+ if $requested_api_version >= 1.2
108
+ app = RestApplication12.new(application, get_url, nolinks)
109
+ else
110
+ app = RestApplication10.new(application, get_url, nolinks)
111
+ end
112
+ render_success(:ok, "application", app, "#{event.sub('-', '_').upcase}_APPLICATION",
113
+ "Application event '#{event}' successful", true)
114
+ end
115
+ end
@@ -0,0 +1,19 @@
1
+ class ApplicationTemplatesController < BaseController
2
+ respond_to :xml, :json
3
+ before_filter :check_version
4
+
5
+ def index
6
+ templates = ApplicationTemplate.find_all.map{|t| RestApplicationTemplate.new(t, get_url, nolinks)}
7
+ render_success(:ok, "application_templates", templates, "LIST_TEMPLATES", "Showing all templates")
8
+ end
9
+
10
+ def show
11
+ id_or_tag = params[:id]
12
+ template = ApplicationTemplate.find(id_or_tag)
13
+ return render_success(:ok, "application_template", RestApplicationTemplate.new(template, get_url, nolinks),
14
+ "SHOW_TEMPLATE", "Showing template for '#{id_or_tag}'") if template
15
+
16
+ templates = ApplicationTemplate.find_all(id_or_tag).map{|t| RestApplicationTemplate.new(t, get_url, nolinks)}
17
+ render_success(:ok, "application_templates", templates, "LIST_TEMPLATES", "Showing template for '#{id_or_tag}'")
18
+ end
19
+ end
@@ -0,0 +1,214 @@
1
+ class ApplicationsController < BaseController
2
+ respond_to :xml, :json
3
+ before_filter :authenticate, :check_version
4
+ include LegacyBrokerHelper
5
+ include CartridgeHelper
6
+ # GET /domains/[domain id]/applications
7
+ def index
8
+ domain_id = params[:domain_id]
9
+
10
+ domain = Domain.get(@cloud_user, domain_id)
11
+ return render_error(:not_found, "Domain '#{domain_id}' not found", 127,
12
+ "LIST_APPLICATIONS") if !domain || !domain.hasAccess?(@cloud_user)
13
+
14
+ @domain_name = domain.namespace
15
+ applications = Application.find_all(@cloud_user)
16
+ apps = Array.new
17
+ include_cartridges = (params[:include] == "cartridges")
18
+
19
+ applications.each do |application|
20
+ if application.domain.uuid = domain.uuid
21
+ if $requested_api_version == 1.0
22
+ app = RestApplication10.new(application, get_url, nolinks)
23
+ elsif $requested_api_version < 1.3
24
+ app = RestApplication12.new(application, get_url, nolinks)
25
+ else
26
+ app = RestApplication.new(application, get_url, nolinks)
27
+ end
28
+ if include_cartridges
29
+ app.cartridges = get_cartridges(application)
30
+ end
31
+ apps.push(app)
32
+ end
33
+ end if applications
34
+ render_success(:ok, "applications", apps, "LIST_APPLICATIONS", "Found #{apps.length} applications for domain '#{domain_id}'")
35
+ end
36
+
37
+ # GET /domains/[domain_id]/applications/<id>
38
+ def show
39
+ domain_id = params[:domain_id]
40
+ id = params[:id]
41
+
42
+ domain = Domain.get(@cloud_user, domain_id)
43
+ return render_error(:not_found, "Domain '#{domain_id}' not found", 127,
44
+ "SHOW_APPLICATION") if !domain || !domain.hasAccess?(@cloud_user)
45
+
46
+ @domain_name = domain.namespace
47
+ application = get_application(id)
48
+ return render_error(:not_found, "Application '#{id}' not found", 101,
49
+ "SHOW_APPLICATION") if !application or application.domain.uuid != domain.uuid
50
+
51
+ @application_name = application.name
52
+ @application_uuid = application.uuid
53
+ if $requested_api_version == 1.0
54
+ app = RestApplication10.new(application, get_url, nolinks)
55
+ elsif $requested_api_version < 1.3
56
+ app = RestApplication12.new(application, get_url, nolinks)
57
+ else
58
+ app = RestApplication.new(application, get_url, nolinks)
59
+ end
60
+ include_cartridges = (params[:include] == "cartridges")
61
+ if include_cartridges
62
+ app.cartridges = get_cartridges(application)
63
+ end
64
+ render_success(:ok, "application", app, "SHOW_APPLICATION", "Application '#{id}' found")
65
+ end
66
+
67
+ # POST /domains/[domain_id]/applications
68
+ def create
69
+ domain_id = params[:domain_id]
70
+ app_name = params[:name]
71
+ cartridges = Array(params[:cartridges] || params[:cartridge])
72
+ scale = get_bool(params[:scale])
73
+ init_git_url = params[:initial_git_url]
74
+ template_id = params[:template]
75
+ node_profile = params[:gear_profile]
76
+ node_profile.downcase! if node_profile
77
+
78
+ domain = Domain.get(@cloud_user, domain_id)
79
+ return render_error(:not_found, "Domain '#{domain_id}' not found", 127,
80
+ "ADD_APPLICATION") if !domain || !domain.hasAccess?(@cloud_user)
81
+
82
+ @domain_name = domain.namespace
83
+ return render_error(:unprocessable_entity, "Application name is required and cannot be blank",
84
+ 105, "ADD_APPLICATION", "name") if !app_name or app_name.empty?
85
+
86
+ application = get_application(app_name)
87
+ return render_error(:unprocessable_entity, "The supplied application name '#{app_name}' already exists",
88
+ 100, "ADD_APPLICATION", "name") if application
89
+
90
+ Rails.logger.debug "Checking to see if user limit for number of apps has been reached"
91
+ return render_error(:unprocessable_entity, "#{@login} has already reached the gear limit of #{@cloud_user.max_gears}",
92
+ 104, "ADD_APPLICATION") if (@cloud_user.consumed_gears >= @cloud_user.max_gears)
93
+
94
+ application = nil
95
+ if template_id
96
+ template = ApplicationTemplate.find(template_id)
97
+ return render_error(:unprocessable_entity, "Invalid template #{template_id}", 125,
98
+ "ADD_APPLICATION", "template") unless template
99
+ application = Application.new(@cloud_user, app_name, nil, node_profile, nil, template, scale, domain)
100
+ else
101
+ framework_cartridges = []
102
+ other_cartridges = []
103
+ Rails.logger.debug "Selected cartridges: #{cartridges.inspect}"
104
+ carts = get_cached("cart_list_standalone", :expires_in => 21600.seconds) {Application.get_available_cartridges("standalone")}
105
+ if !cartridges
106
+
107
+ return render_error(:unprocessable_entity, "You must specify a cartridge. Valid values are (#{carts.join(', ')})",
108
+ 109, "ADD_APPLICATION", "cartridge")
109
+ else
110
+ cartridges.each do |cart|
111
+ framework_cartridges.push(cart) unless not carts.include?(cart)
112
+ other_cartridges.push(cart) unless carts.include?(cart)
113
+ end
114
+ if framework_cartridges.empty?
115
+ return render_error(:unprocessable_entity, "Each application must contain one web cartridge. None of the specified cartridges #{cartridges.to_sentence} is a web cartridge. Please include one of the following cartridges: #{carts.to_sentence}.",
116
+ 109, "ADD_APPLICATION", "cartridge")
117
+ elsif framework_cartridges.length > 1
118
+ return render_error(:unprocessable_entity, "Each application must contain only one web cartridge. Please include a single web cartridge from this list: #{carts.to_sentence}.",
119
+ 109, "ADD_APPLICATION", "cartridge")
120
+ end
121
+ end
122
+ begin
123
+ application = Application.new(@cloud_user, app_name, nil, node_profile, framework_cartridges[0], nil, scale, domain, init_git_url)
124
+ rescue Exception => e
125
+ return render_error(:internal_server_error, "Error returned from server #{e.message}", 1, "ADD_APPLICATION")
126
+ end
127
+ end
128
+
129
+ app_configure_reply = nil
130
+
131
+ Rails.logger.debug "Validating application"
132
+ if not application.valid?
133
+ messages = get_error_messages(application)
134
+ return render_error(:unprocessable_entity, nil, nil, "ADD_APPLICATION", nil, nil, messages)
135
+ end
136
+
137
+ @application_name = application.name
138
+ begin
139
+ application.user_agent = request.headers['User-Agent']
140
+ Rails.logger.debug "Creating application #{application.name}"
141
+ application.create
142
+ Rails.logger.debug "Configuring dependencies #{application.name}"
143
+ app_configure_reply = application.configure_dependencies
144
+ Rails.logger.debug "Executing connections for #{application.name}"
145
+ application.execute_connections
146
+ cart_reply = []
147
+ other_cartridges.each do |cart|
148
+ cart_reply << application.add_dependency(cart)
149
+ end if other_cartridges and !other_cartridges.empty?
150
+ begin
151
+ Rails.logger.debug "Creating dns"
152
+ application.create_dns
153
+ rescue Exception => e
154
+ log_action(@request_id, @cloud_user.uuid, @cloud_user.login, "ADD_APPLICATION", false, "Failed to create dns for application #{application.name}: #{e.message}", get_extra_log_args)
155
+ application.destroy_dns
156
+ raise
157
+ end
158
+ rescue Exception => e
159
+ application.destroy(true)
160
+ if application.persisted?
161
+ application.delete
162
+ end
163
+ return render_exception(e, "ADD_APPLICATION")
164
+ end
165
+
166
+ if $requested_api_version == 1.0
167
+ app = RestApplication10.new(application, get_url, nolinks)
168
+ elsif $requested_api_version < 1.3
169
+ app = RestApplication12.new(application, get_url, nolinks)
170
+ else
171
+ app = RestApplication.new(application, get_url, nolinks)
172
+ end
173
+ messages = []
174
+ log_msg = "Application #{application.name} was created."
175
+ messages.push(Message.new(:info, log_msg))
176
+
177
+ current_ip = application.get_public_ip_address
178
+ messages.push(Message.new(:info, "#{current_ip}", 0, "current_ip")) unless !current_ip or current_ip.empty?
179
+ messages.push(Message.new(:info, app_configure_reply.resultIO.string, 0, :result)) if app_configure_reply
180
+ cart_reply.each do |reply|
181
+ messages.push(Message.new(:info, reply.resultIO.string, 0, :result))
182
+ end unless cart_reply.empty?
183
+ include_cartridges = (params[:include] == "cartridges")
184
+ if include_cartridges
185
+ app.cartridges = get_cartridges(application)
186
+ end
187
+ render_success(:created, "application", app, "ADD_APPLICATION", log_msg, nil, nil, messages)
188
+ end
189
+
190
+ # DELELTE domains/[domain_id]/applications/[id]
191
+ def destroy
192
+ domain_id = params[:domain_id]
193
+ id = params[:id]
194
+
195
+ domain = Domain.get(@cloud_user, domain_id)
196
+ return render_format_error(:not_found, "Domain #{domain_id} not found", 127,
197
+ "DELETE_APPLICATION") if !domain || !domain.hasAccess?(@cloud_user)
198
+
199
+ @domain_name = domain.namespace
200
+ application = get_application(id)
201
+ return render_format_error(:not_found, "Application #{id} not found.", 101,
202
+ "DELETE_APPLICATION") if !application or application.domain.uuid != domain.uuid
203
+
204
+ @application_name = application.name
205
+ @application_uuid = application.uuid
206
+ begin
207
+ Rails.logger.debug "Deleting application #{id}"
208
+ application.cleanup_and_delete()
209
+ rescue Exception => e
210
+ return render_format_exception(e, "DELETE_APPLICATION")
211
+ end
212
+ render_format_success(:no_content, nil, nil, "DELETE_APPLICATION", "Application #{id} is deleted.", true)
213
+ end
214
+ end
@@ -0,0 +1,367 @@
1
+ require 'action_dispatch/http/mime_types'
2
+ module Mime
3
+ class Type
4
+ class << self
5
+ def lookup(string)
6
+ LOOKUP[string.split(';').first]
7
+ end
8
+ end
9
+ end
10
+ end
11
+ class BaseController < ActionController::Base
12
+ respond_to :json, :xml
13
+ before_filter :check_version, :only => :show
14
+ before_filter :check_nolinks
15
+ API_VERSION = 1.3
16
+ SUPPORTED_API_VERSIONS = [1.0,1.1,1.2, 1.3]
17
+
18
+ include UserActionLogger
19
+
20
+ # Initialize domain/app variables to be used for logging in user_action.log
21
+ # The values will be set in the controllers handling the requests
22
+ @domain_name = nil
23
+ @application_name = nil
24
+ @application_uuid = nil
25
+
26
+ def show
27
+ blacklisted_words = OpenShift::ApplicationContainerProxy.get_blacklisted
28
+ unless nolinks
29
+ links = {
30
+ "API" => Link.new("API entry point", "GET", URI::join(get_url, "api")),
31
+ "GET_ENVIRONMENT" => Link.new("Get environment information", "GET", URI::join(get_url, "environment")),
32
+ "GET_USER" => Link.new("Get user information", "GET", URI::join(get_url, "user")),
33
+ "LIST_DOMAINS" => Link.new("List domains", "GET", URI::join(get_url, "domains")),
34
+ "ADD_DOMAIN" => Link.new("Create new domain", "POST", URI::join(get_url, "domains"), [
35
+ Param.new("id", "string", "Name of the domain",nil,blacklisted_words)
36
+ ]),
37
+ "LIST_CARTRIDGES" => Link.new("List cartridges", "GET", URI::join(get_url, "cartridges")),
38
+ "LIST_TEMPLATES" => Link.new("List application templates", "GET", URI::join(get_url, "application_templates")),
39
+ "LIST_ESTIMATES" => Link.new("List available estimates", "GET" , URI::join(get_url, "estimates"))
40
+ }
41
+ links.merge!(if base_url = Rails.application.config.openshift[:community_quickstarts_url]
42
+ base_url = URI.join(get_url, base_url).to_s
43
+ {
44
+ "LIST_QUICKSTARTS" => Link.new("List quickstarts", "GET", URI::join(base_url, "v1/quickstarts/promoted.json")),
45
+ "SHOW_QUICKSTART" => Link.new("Retrieve quickstart with :id", "GET", URI::join(base_url, "v1/quickstarts/:id"), [
46
+ Param.new(":id", "string", "Unique identifier of the quickstart", nil, [])
47
+ ]),
48
+ "SEARCH_QUICKSTARTS" => Link.new("Search quickstarts", "GET", URI::join(base_url, "v1/quickstarts.json"), [
49
+ Param.new("search", "string", "The search term to use for the quickstart", nil, [])
50
+ ]),
51
+ }
52
+ else
53
+ {
54
+ "LIST_QUICKSTARTS" => Link.new("List quickstarts", "GET", URI::join(get_url, "quickstarts")),
55
+ "SHOW_QUICKSTART" => Link.new("Retrieve quickstart with :id", "GET", URI::join(get_url, "quickstarts/:id"), [
56
+ Param.new(":id", "string", "Unique identifier of the quickstart", nil, [])
57
+ ]),
58
+ }
59
+ end)
60
+ end
61
+
62
+ @reply = RestReply.new(:ok, "links", links)
63
+ respond_with @reply, :status => @reply.status
64
+ end
65
+
66
+ protected
67
+
68
+ def authenticate
69
+ login = nil
70
+ password = nil
71
+ @request_id = gen_req_uuid
72
+
73
+ if request.headers['User-Agent'] == "OpenShift"
74
+ if params['broker_auth_key'] && params['broker_auth_iv']
75
+ login = params['broker_auth_key']
76
+ password = params['broker_auth_iv']
77
+ else
78
+ if request.headers['broker_auth_key'] && request.headers['broker_auth_iv']
79
+ login = request.headers['broker_auth_key']
80
+ password = request.headers['broker_auth_iv']
81
+ end
82
+ end
83
+ end
84
+ if login.nil? or password.nil?
85
+ authenticate_with_http_basic { |u, p|
86
+ login = u
87
+ password = p
88
+ }
89
+ end
90
+ begin
91
+ auth = OpenShift::AuthService.instance.authenticate(request, login, password)
92
+ @login = auth[:username]
93
+ @auth_method = auth[:auth_method]
94
+
95
+ if not request.headers["X-Impersonate-User"].nil?
96
+ @parent_user = CloudUser.find @login
97
+ subuser_name = request.headers["X-Impersonate-User"]
98
+
99
+ if @parent_user.nil?
100
+ Rails.logger.debug "#{@login} tried to impersonate user but #{@login} user does not exist"
101
+ raise OpenShift::AccessDeniedException.new "Insufficient privileges to access user #{subuser_name}"
102
+ end
103
+
104
+ if @parent_user.capabilities.nil? || !@parent_user.capabilities["subaccounts"] == true
105
+ Rails.logger.debug "#{@parent_user.login} tried to impersonate user but does not have require capability."
106
+ raise OpenShift::AccessDeniedException.new "Insufficient privileges to access user #{subuser_name}"
107
+ end
108
+
109
+ sub_user = CloudUser.find subuser_name
110
+ if sub_user && sub_user.parent_user_login != @parent_user.login
111
+ Rails.logger.debug "#{@parent_user.login} tried to impersinate user #{subuser_name} but does not own the subaccount."
112
+ raise OpenShift::AccessDeniedException.new "Insufficient privileges to access user #{subuser_name}"
113
+ end
114
+
115
+ if sub_user.nil?
116
+ Rails.logger.debug "Adding user #{subuser_name} as sub user of #{@parent_user.login} ...inside base_controller"
117
+ @cloud_user = CloudUser.new(subuser_name,nil,nil,nil,{},@parent_user.login)
118
+ @cloud_user.parent_user_login = @parent_user.login
119
+ init_user
120
+ else
121
+ @cloud_user = sub_user
122
+ end
123
+ else
124
+ @cloud_user = CloudUser.find @login
125
+ if @cloud_user.nil?
126
+ Rails.logger.debug "Adding user #{@login}...inside base_controller"
127
+ @cloud_user = CloudUser.new(@login)
128
+ init_user
129
+ end
130
+ end
131
+
132
+ @cloud_user.auth_method = @auth_method unless @cloud_user.nil?
133
+ rescue OpenShift::UserException => e
134
+ render_format_exception(e)
135
+ rescue OpenShift::AccessDeniedException
136
+ log_action(@request_id, 'nil', login, "AUTHENTICATE", true, "Access denied")
137
+ request_http_basic_authentication
138
+ end
139
+ end
140
+
141
+ def init_user()
142
+ begin
143
+ @cloud_user.save
144
+ rescue Exception => e
145
+ cu = CloudUser.find @login
146
+ raise unless cu && (@cloud_user.parent_user_login == cu.parent_user_login)
147
+ @cloud_user = cu
148
+ end
149
+ end
150
+
151
+ def get_application(id)
152
+ app = Application.find(@cloud_user, id)
153
+ app.user_agent = request.headers['User-Agent'] if app
154
+ app
155
+ end
156
+
157
+ def rest_replies_url(*args)
158
+ return "/broker/rest/api"
159
+ end
160
+
161
+ def get_url
162
+ #Rails.logger.debug "Request URL: #{request.url}"
163
+ url = URI::join(request.url, "/broker/rest/")
164
+ #Rails.logger.debug "Request URL: #{url.to_s}"
165
+ return url.to_s
166
+ end
167
+
168
+ def nolinks
169
+ ignore_links = params[:nolinks]
170
+ if ignore_links
171
+ ignore_links.downcase!
172
+ return true if ["true", "1"].include?(ignore_links)
173
+ return false if ["false", "0"].include?(ignore_links)
174
+ raise OpenShift::UserException.new("Invalid value for 'nolinks'. Valid options: [true, false, 1, 0]", 167)
175
+ end
176
+ return false
177
+ end
178
+
179
+ def check_version
180
+ accept_header = request.headers['Accept']
181
+ mime_types = accept_header.split(%r{,\s*})
182
+ version_header = API_VERSION
183
+ mime_types.each do |mime_type|
184
+ values = mime_type.split(%r{;\s*})
185
+ values.each do |value|
186
+ value = value.downcase
187
+ if value.include?("version")
188
+ version_header = value.split("=")[1].delete(' ').to_f
189
+ end
190
+ end
191
+ end
192
+
193
+ #$requested_api_version = request.headers['X_API_VERSION']
194
+ if not version_header
195
+ $requested_api_version = API_VERSION
196
+ else
197
+ $requested_api_version = version_header
198
+ end
199
+
200
+ if not SUPPORTED_API_VERSIONS.include? $requested_api_version
201
+ invalid_version = $requested_api_version
202
+ $requested_api_version = API_VERSION
203
+ return render_format_error(:not_acceptable, "Requested API version #{invalid_version} is not supported. Supported versions are #{SUPPORTED_API_VERSIONS.map{|v| v.to_s}.join(",")}")
204
+ end
205
+ end
206
+
207
+ def check_nolinks
208
+ begin
209
+ nolinks
210
+ rescue Exception => e
211
+ return render_format_exception(e)
212
+ end
213
+ end
214
+
215
+ def get_bool(param_value)
216
+ if param_value.is_a? TrueClass or param_value.is_a? FalseClass
217
+ return param_value
218
+ elsif param_value.is_a? String and param_value.upcase == "TRUE"
219
+ return true
220
+ else
221
+ return false
222
+ end
223
+ end
224
+
225
+ def gen_req_uuid
226
+ # The request id can be generated differently to make it a bit more meaningful
227
+ File.open("/proc/sys/kernel/random/uuid", "r") do |file|
228
+ file.gets.strip.gsub("-","")
229
+ end
230
+ end
231
+
232
+ def get_cloud_user_info(cloud_user)
233
+ if cloud_user
234
+ return { :uuid => cloud_user.uuid, :login => cloud_user.login }
235
+ else
236
+ return { :uuid => 0, :login => 'anonymous' }
237
+ end
238
+ end
239
+
240
+ def get_extra_log_args
241
+ args = {}
242
+ args["APP"] = @application_name if @application_name
243
+ args["DOMAIN"] = @domain_name if @domain_name
244
+ args["APP_UUID"] = @application_uuid if @application_uuid
245
+
246
+ return args
247
+ end
248
+
249
+ def get_error_messages(object, orig_field=nil, display_field=nil)
250
+ messages = []
251
+ object.errors.keys.each do |key|
252
+ field = key.to_s
253
+ field = display_field if orig_field && (key.to_s == orig_field)
254
+ err_msgs = object.errors.get(key)
255
+ err_msgs.each do |err_msg|
256
+ messages.push(Message.new(:error, err_msg[:message], err_msg[:exit_code], field))
257
+ end if err_msgs
258
+ end if object && object.errors && object.errors.keys
259
+ return messages
260
+ end
261
+
262
+ #Due to the bug in rails, 'format' is explicitly used for PUT, DELETE rest calls
263
+ def render_response(reply, format=false)
264
+ if format
265
+ respond_with(reply) do |fmt|
266
+ fmt.xml { render :xml => reply, :status => reply.status }
267
+ fmt.json { render :json => reply, :status => reply.status }
268
+ end
269
+ else
270
+ respond_with reply, :status => reply.status
271
+ end
272
+ end
273
+
274
+ def render_error_internal(status, msg, err_code=nil, log_tag=nil,
275
+ field=nil, msg_type=nil, messages=nil, format=false, internal_error=false)
276
+ reply = RestReply.new(status)
277
+ user_info = get_cloud_user_info(@cloud_user)
278
+
279
+ logger_msg = nil
280
+ if msg
281
+ msg_type = :error unless msg_type
282
+ reply.messages.push(Message.new(msg_type, msg, err_code, field))
283
+ logger_msg = msg
284
+ end
285
+ if messages && !messages.empty?
286
+ reply.messages.concat(messages)
287
+ unless logger_msg
288
+ msg = []
289
+ messages.each { |m| msg.push(m.text) }
290
+ logger_msg = msg.join(', ')
291
+ end
292
+ end
293
+ log_action(@request_id, user_info[:uuid], user_info[:login], log_tag, !internal_error, logger_msg, get_extra_log_args) if log_tag
294
+ render_response(reply, format)
295
+ end
296
+
297
+ def render_exception_internal(ex, log_tag, format)
298
+ Rails.logger.error ex
299
+ Rails.logger.error ex.backtrace
300
+
301
+ error_code = ex.respond_to?('code') ? ex.code : 1
302
+ message = ex.message
303
+ if ex.kind_of? OpenShift::UserException
304
+ status = :unprocessable_entity
305
+ elsif ex.kind_of? OpenShift::DNSException
306
+ status = :service_unavailable
307
+ elsif ex.kind_of? OpenShift::NodeException
308
+ status = :internal_server_error
309
+ if ex.resultIO && ex.resultIO.errorIO
310
+ error_code = ex.resultIO.exitcode
311
+ message = ex.resultIO.errorIO.string.strip
312
+ end
313
+ else
314
+ status = :internal_server_error
315
+ end
316
+
317
+ internal_error = status != :unprocessable_entity
318
+ render_error_internal(status, message, error_code, log_tag, nil, nil, nil, format, internal_error)
319
+ end
320
+
321
+ def render_success_internal(status, type, data, log_tag, log_msg=nil, publish_msg=false,
322
+ msg_type=nil, messages=nil, format=false)
323
+ reply = RestReply.new(status, type, data)
324
+ user_info = get_cloud_user_info(@cloud_user)
325
+
326
+ logger_msg = nil
327
+ if log_msg
328
+ msg_type = :info unless msg_type
329
+ reply.messages.push(Message.new(msg_type, log_msg)) if publish_msg
330
+ logger_msg = log_msg
331
+ end
332
+ if messages && !messages.empty?
333
+ reply.messages.concat(messages)
334
+ unless logger_msg
335
+ msg = []
336
+ messages.each { |m| msg.push(m.text) }
337
+ logger_msg = msg.join(', ')
338
+ end
339
+ end
340
+ log_action(@request_id, user_info[:uuid], user_info[:login], log_tag, true, logger_msg, get_extra_log_args) if log_tag
341
+ render_response(reply, format)
342
+ end
343
+
344
+ def render_format_error(status, msg, err_code=nil, log_tag=nil, field=nil, msg_type=nil, messages=nil)
345
+ render_error_internal(status, msg, err_code, log_tag, field, msg_type, messages, true)
346
+ end
347
+
348
+ def render_format_exception(ex, log_tag=nil)
349
+ render_exception_internal(ex, log_tag, true)
350
+ end
351
+
352
+ def render_format_success(status, type, data, log_tag, log_msg=nil, publish_msg=false, msg_type=nil, messages=nil)
353
+ render_success_internal(status, type, data, log_tag, log_msg, publish_msg, msg_type, messages, true)
354
+ end
355
+
356
+ def render_error(status, msg, err_code=nil, log_tag=nil, field=nil, msg_type=nil, messages=nil)
357
+ render_error_internal(status, msg, err_code, log_tag, field, msg_type, messages, false)
358
+ end
359
+
360
+ def render_exception(ex, log_tag=nil)
361
+ render_exception_internal(ex, log_tag, false)
362
+ end
363
+
364
+ def render_success(status, type, data, log_tag, log_msg=nil, publish_msg=false, msg_type=nil, messages=nil)
365
+ render_success_internal(status, type, data, log_tag, log_msg, publish_msg, msg_type, messages, false)
366
+ end
367
+ end