openshift-origin-console 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (291) hide show
  1. data/COPYRIGHT +1 -0
  2. data/Gemfile +21 -0
  3. data/LICENSE +203 -0
  4. data/README.md +123 -0
  5. data/Rakefile +44 -0
  6. data/app/assets/images/cartridge-edge.gif +0 -0
  7. data/app/assets/images/console/arrow-down.png +0 -0
  8. data/app/assets/images/console/console-sprite.png +0 -0
  9. data/app/assets/images/favicon-32.png +0 -0
  10. data/app/assets/images/loader-dark.gif +0 -0
  11. data/app/assets/images/loader.gif +0 -0
  12. data/app/assets/images/sprite-vert.png +0 -0
  13. data/app/assets/javascripts/console.js +10 -0
  14. data/app/assets/javascripts/console/form.js.coffee +51 -0
  15. data/app/assets/stylesheets/_alerts.scss +84 -0
  16. data/app/assets/stylesheets/_breadcrumbs.scss +31 -0
  17. data/app/assets/stylesheets/_buttons.scss +229 -0
  18. data/app/assets/stylesheets/_code.scss +86 -0
  19. data/app/assets/stylesheets/_custom.scss +207 -0
  20. data/app/assets/stylesheets/_footer.scss +54 -0
  21. data/app/assets/stylesheets/_forms.scss +710 -0
  22. data/app/assets/stylesheets/_grid.scss +28 -0
  23. data/app/assets/stylesheets/_input-prepend-append.scss +138 -0
  24. data/app/assets/stylesheets/_labels.scss +40 -0
  25. data/app/assets/stylesheets/_mixins.scss +76 -0
  26. data/app/assets/stylesheets/_override-variables.scss +1 -0
  27. data/app/assets/stylesheets/_responsive.scss +438 -0
  28. data/app/assets/stylesheets/_ribbon.scss +57 -0
  29. data/app/assets/stylesheets/_type.scss +306 -0
  30. data/app/assets/stylesheets/_utilities.scss +10 -0
  31. data/app/assets/stylesheets/_variables.scss +131 -0
  32. data/app/assets/stylesheets/common.css.scss +82 -0
  33. data/app/assets/stylesheets/console/_application.scss +194 -0
  34. data/app/assets/stylesheets/console/_base.scss +26 -0
  35. data/app/assets/stylesheets/console/_breadcrumbs.scss +32 -0
  36. data/app/assets/stylesheets/console/_buttons.scss +214 -0
  37. data/app/assets/stylesheets/console/_core.scss +1002 -0
  38. data/app/assets/stylesheets/console/_dropdowns.scss +63 -0
  39. data/app/assets/stylesheets/console/_help.scss +54 -0
  40. data/app/assets/stylesheets/console/_mixins.scss +11 -0
  41. data/app/assets/stylesheets/console/_navbar.scss +415 -0
  42. data/app/assets/stylesheets/console/_ribbon.scss +82 -0
  43. data/app/assets/stylesheets/console/_tile.scss +122 -0
  44. data/app/assets/stylesheets/origin.css.scss +37 -0
  45. data/app/controllers/account/dashboard.rb +13 -0
  46. data/app/controllers/account_controller.rb +3 -0
  47. data/app/controllers/application_types_controller.rb +80 -0
  48. data/app/controllers/applications_controller.rb +183 -0
  49. data/app/controllers/building_controller.rb +81 -0
  50. data/app/controllers/capability_aware.rb +18 -0
  51. data/app/controllers/cartridge_types_controller.rb +53 -0
  52. data/app/controllers/cartridges_controller.rb +43 -0
  53. data/app/controllers/console/auth/basic.rb +65 -0
  54. data/app/controllers/console/auth/none.rb +5 -0
  55. data/app/controllers/console/auth/remote_user.rb +69 -0
  56. data/app/controllers/console/rescue.rb +48 -0
  57. data/app/controllers/console_controller.rb +19 -0
  58. data/app/controllers/console_index_controller.rb +14 -0
  59. data/app/controllers/domain_aware.rb +26 -0
  60. data/app/controllers/domain_session_sweeper.rb +29 -0
  61. data/app/controllers/domains_controller.rb +30 -0
  62. data/app/controllers/keys_controller.rb +43 -0
  63. data/app/controllers/scaling_controller.rb +46 -0
  64. data/app/controllers/sshkey_aware.rb +23 -0
  65. data/app/controllers/sshkey_session_sweeper.rb +29 -0
  66. data/app/controllers/user_session_sweeper.rb +29 -0
  67. data/app/helpers/console/community_helper.rb +78 -0
  68. data/app/helpers/console/console_helper.rb +26 -0
  69. data/app/helpers/console/help_helper.rb +270 -0
  70. data/app/helpers/console/html5_boilerplate_helper.rb +63 -0
  71. data/app/helpers/console/layout_helper.rb +277 -0
  72. data/app/helpers/console/model_helper.rb +106 -0
  73. data/app/helpers/console/secured_helper.rb +5 -0
  74. data/app/models/alias.rb +10 -0
  75. data/app/models/application.rb +148 -0
  76. data/app/models/application_associations.rb +36 -0
  77. data/app/models/application_template.rb +90 -0
  78. data/app/models/application_type.rb +258 -0
  79. data/app/models/async_aware.rb +60 -0
  80. data/app/models/capabilities.rb +62 -0
  81. data/app/models/cartridge.rb +122 -0
  82. data/app/models/cartridge_type.rb +140 -0
  83. data/app/models/domain.rb +44 -0
  84. data/app/models/domain_associations.rb +33 -0
  85. data/app/models/embedded.rb +11 -0
  86. data/app/models/gear.rb +13 -0
  87. data/app/models/gear_group.rb +104 -0
  88. data/app/models/key.rb +87 -0
  89. data/app/models/quickstart.rb +135 -0
  90. data/app/models/rest_api.rb +130 -0
  91. data/app/models/rest_api/base.rb +781 -0
  92. data/app/models/rest_api/cacheable.rb +91 -0
  93. data/app/models/rest_api/environment.rb +13 -0
  94. data/app/models/rest_api/info.rb +34 -0
  95. data/app/models/rest_api/log_subscriber.rb +29 -0
  96. data/app/models/rest_api/railties/controller_runtime.rb +37 -0
  97. data/app/models/user.rb +27 -0
  98. data/app/models/user_associations.rb +6 -0
  99. data/app/views/account/_domain.html.haml +14 -0
  100. data/app/views/account/_keys.html.haml +20 -0
  101. data/app/views/account/_user.html.haml +5 -0
  102. data/app/views/account/show.html.haml +15 -0
  103. data/app/views/application_templates/_application_template.html.haml +5 -0
  104. data/app/views/application_types/_application_type.html.haml +19 -0
  105. data/app/views/application_types/_custom.html.haml +19 -0
  106. data/app/views/application_types/_persisted.html.haml +26 -0
  107. data/app/views/application_types/_tile.html.haml +9 -0
  108. data/app/views/application_types/index.html.haml +87 -0
  109. data/app/views/application_types/search.html.haml +67 -0
  110. data/app/views/application_types/show.html.haml +219 -0
  111. data/app/views/applications/_application.html.haml +34 -0
  112. data/app/views/applications/_applications_filter.html.haml +8 -0
  113. data/app/views/applications/_footer.html.haml +0 -0
  114. data/app/views/applications/_name.html.haml +28 -0
  115. data/app/views/applications/delete.html.haml +19 -0
  116. data/app/views/applications/get_started.html.haml +145 -0
  117. data/app/views/applications/index.html.haml +55 -0
  118. data/app/views/applications/show.html.haml +193 -0
  119. data/app/views/building/delete.html.haml +22 -0
  120. data/app/views/building/new.html.haml +57 -0
  121. data/app/views/building/show.html.haml +12 -0
  122. data/app/views/cartridge_types/_cartridge_type.html.haml +61 -0
  123. data/app/views/cartridge_types/index.html.haml +37 -0
  124. data/app/views/cartridge_types/show.html.haml +21 -0
  125. data/app/views/cartridges/next_steps.html.haml +58 -0
  126. data/app/views/cartridges/show.html.haml +1 -0
  127. data/app/views/console/error.html.haml +58 -0
  128. data/app/views/console/help.html.haml +90 -0
  129. data/app/views/console/not_found.html.haml +69 -0
  130. data/app/views/console/unauthorized.html.haml +7 -0
  131. data/app/views/domains/_domain.html.haml +14 -0
  132. data/app/views/domains/_form.html.haml +13 -0
  133. data/app/views/domains/edit.html.haml +5 -0
  134. data/app/views/domains/new.html.haml +6 -0
  135. data/app/views/keys/_form.html.haml +14 -0
  136. data/app/views/keys/_simple_form.html.haml +14 -0
  137. data/app/views/keys/new.html.haml +2 -0
  138. data/app/views/layouts/_footer.html.haml +38 -0
  139. data/app/views/layouts/_head.html.haml +35 -0
  140. data/app/views/layouts/console.html.haml +60 -0
  141. data/app/views/layouts/console/_header.html.haml +44 -0
  142. data/app/views/layouts/console/_identity.html.haml +7 -0
  143. data/app/views/layouts/console/_javascripts.html.haml +5 -0
  144. data/app/views/layouts/console/_stylesheets.html.haml +6 -0
  145. data/app/views/scaling/delete.html.haml +17 -0
  146. data/app/views/scaling/new.html.haml +24 -0
  147. data/app/views/scaling/show.html.haml +81 -0
  148. data/app/views/shared/_tracking.html.haml +0 -0
  149. data/conf/console.conf.example +108 -0
  150. data/conf/openshift_console.conf +10 -0
  151. data/config/cartridge_types.yml +54 -0
  152. data/config/initializers/barista_config.rb +86 -0
  153. data/config/initializers/cartridge_types.rb +5 -0
  154. data/config/initializers/console_security.rb +1 -0
  155. data/config/initializers/date_helper.rb +5 -0
  156. data/config/initializers/extended_logger.rb +51 -0
  157. data/config/initializers/formtastic.rb +100 -0
  158. data/config/initializers/inflections.rb +38 -0
  159. data/config/initializers/rdiscount.rb +8 -0
  160. data/config/initializers/rest_api.rb +22 -0
  161. data/config/initializers/sass.rb +30 -0
  162. data/config/initializers/session_trace.rb +32 -0
  163. data/config/initializers/x_frame_options.rb +53 -0
  164. data/config/locales/en.yml +12 -0
  165. data/lib/active_resource/associations.rb +107 -0
  166. data/lib/active_resource/associations/builder/association.rb +35 -0
  167. data/lib/active_resource/associations/builder/belongs_to.rb +5 -0
  168. data/lib/active_resource/associations/builder/has_many.rb +5 -0
  169. data/lib/active_resource/associations/builder/has_one.rb +5 -0
  170. data/lib/active_resource/persistent_connection.rb +341 -0
  171. data/lib/active_resource/persistent_http_mock.rb +68 -0
  172. data/lib/active_resource/reflection.rb +78 -0
  173. data/lib/console.rb +8 -0
  174. data/lib/console/config_file.rb +13 -0
  175. data/lib/console/configuration.rb +163 -0
  176. data/lib/console/engine.rb +28 -0
  177. data/lib/console/formtastic/bootstrap_form_builder.rb +369 -0
  178. data/lib/console/rails/app_redirector.rb +40 -0
  179. data/lib/console/rails/filter_hash.rb +15 -0
  180. data/lib/console/rails/routes.rb +51 -0
  181. data/lib/console/version.rb +5 -0
  182. data/lib/tasks/assets.rake +79 -0
  183. data/lib/tasks/stats.rake +18 -0
  184. data/lib/tasks/test_suites.rake +73 -0
  185. data/test/coverage_helper.rb +27 -0
  186. data/test/fixtures/cartridges.json +1 -0
  187. data/test/fixtures/quickstarts.csv +3 -0
  188. data/test/functional/account_controller_test.rb +14 -0
  189. data/test/functional/application_types_controller_test.rb +251 -0
  190. data/test/functional/applications_controller_sanity_test.rb +26 -0
  191. data/test/functional/applications_controller_test.rb +365 -0
  192. data/test/functional/building_controller_test.rb +203 -0
  193. data/test/functional/cartridge_types_controller_isolation_test.rb +68 -0
  194. data/test/functional/cartridge_types_controller_test.rb +48 -0
  195. data/test/functional/cartridges_controller_test.rb +83 -0
  196. data/test/functional/console_auth_basic_controller_test.rb +82 -0
  197. data/test/functional/console_auth_remote_user_controller_test.rb +90 -0
  198. data/test/functional/console_index_controller_test.rb +22 -0
  199. data/test/functional/domains_controller_test.rb +194 -0
  200. data/test/functional/keys_controller_test.rb +163 -0
  201. data/test/functional/quickstarts.json +18 -0
  202. data/test/functional/scaling_controller_test.rb +153 -0
  203. data/test/integration/assets_test.rb +34 -0
  204. data/test/integration/help_link_test.rb +43 -0
  205. data/test/integration/quickstarts_test.rb +24 -0
  206. data/test/integration/rescue_from_test.rb +25 -0
  207. data/test/integration/rest_api/application_test.rb +115 -0
  208. data/test/integration/rest_api/cartridge_test.rb +44 -0
  209. data/test/integration/rest_api/cartridge_type_test.rb +143 -0
  210. data/test/integration/rest_api/domain_test.rb +91 -0
  211. data/test/integration/rest_api/info_test.rb +9 -0
  212. data/test/integration/rest_api/key_test.rb +85 -0
  213. data/test/integration/static_pages_test.rb +44 -0
  214. data/test/rails_app/Rakefile +7 -0
  215. data/test/rails_app/app/controllers/application_controller.rb +5 -0
  216. data/test/rails_app/config.ru +4 -0
  217. data/test/rails_app/config/application.rb +48 -0
  218. data/test/rails_app/config/boot.rb +10 -0
  219. data/test/rails_app/config/database.yml +25 -0
  220. data/test/rails_app/config/environment.rb +5 -0
  221. data/test/rails_app/config/environments/development.rb +38 -0
  222. data/test/rails_app/config/environments/production.rb +70 -0
  223. data/test/rails_app/config/environments/test.rb +43 -0
  224. data/test/rails_app/config/initializers/auth.rb +0 -0
  225. data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  226. data/test/rails_app/config/initializers/inflections.rb +10 -0
  227. data/test/rails_app/config/initializers/mime_types.rb +5 -0
  228. data/test/rails_app/config/initializers/secret_token.rb +7 -0
  229. data/test/rails_app/config/initializers/session_store.rb +8 -0
  230. data/test/rails_app/config/locales/en.yml +5 -0
  231. data/test/rails_app/config/routes.rb +4 -0
  232. data/test/rails_app/script/rails +6 -0
  233. data/test/support/auth.rb +111 -0
  234. data/test/support/base.rb +142 -0
  235. data/test/support/errors.rb +28 -0
  236. data/test/support/rest_api.rb +189 -0
  237. data/test/test_helper.rb +14 -0
  238. data/test/unit/active_model_compliance_test.rb +23 -0
  239. data/test/unit/async_aware_test.rb +55 -0
  240. data/test/unit/configuration_test.rb +158 -0
  241. data/test/unit/filter_hash_test.rb +64 -0
  242. data/test/unit/helpers/model_helper_test.rb +61 -0
  243. data/test/unit/overrides_test.rb +9 -0
  244. data/test/unit/rest_api_test.rb +1590 -0
  245. data/vendor/assets/javascripts/MIT-LICENSE.txt +20 -0
  246. data/vendor/assets/javascripts/bootstrap-collapse.js +157 -0
  247. data/vendor/assets/javascripts/bootstrap-dropdown.js +100 -0
  248. data/vendor/assets/javascripts/bootstrap-tab.js +135 -0
  249. data/vendor/assets/javascripts/bootstrap-transition.js +61 -0
  250. data/vendor/assets/javascripts/jquery.spin.js +47 -0
  251. data/vendor/assets/javascripts/jquery.ui.widget.js +16 -0
  252. data/vendor/assets/javascripts/jquery_cookie.js +41 -0
  253. data/vendor/assets/javascripts/jquery_validate_min.js +51 -0
  254. data/vendor/assets/javascripts/modernizr.min.js +2 -0
  255. data/vendor/assets/javascripts/plugins.js +16 -0
  256. data/vendor/assets/stylesheets/bootstrap/_accordion.scss +28 -0
  257. data/vendor/assets/stylesheets/bootstrap/_alerts.scss +70 -0
  258. data/vendor/assets/stylesheets/bootstrap/_breadcrumbs.scss +22 -0
  259. data/vendor/assets/stylesheets/bootstrap/_button-groups.scss +147 -0
  260. data/vendor/assets/stylesheets/bootstrap/_buttons.scss +183 -0
  261. data/vendor/assets/stylesheets/bootstrap/_carousel.scss +121 -0
  262. data/vendor/assets/stylesheets/bootstrap/_close.scss +18 -0
  263. data/vendor/assets/stylesheets/bootstrap/_code.scss +57 -0
  264. data/vendor/assets/stylesheets/bootstrap/_component-animations.scss +18 -0
  265. data/vendor/assets/stylesheets/bootstrap/_dropdowns.scss +130 -0
  266. data/vendor/assets/stylesheets/bootstrap/_forms.scss +522 -0
  267. data/vendor/assets/stylesheets/bootstrap/_grid.scss +8 -0
  268. data/vendor/assets/stylesheets/bootstrap/_hero-unit.scss +20 -0
  269. data/vendor/assets/stylesheets/bootstrap/_labels.scss +32 -0
  270. data/vendor/assets/stylesheets/bootstrap/_layouts.scss +17 -0
  271. data/vendor/assets/stylesheets/bootstrap/_mixins.scss +602 -0
  272. data/vendor/assets/stylesheets/bootstrap/_modals.scss +84 -0
  273. data/vendor/assets/stylesheets/bootstrap/_navbar.scss +299 -0
  274. data/vendor/assets/stylesheets/bootstrap/_navs.scss +353 -0
  275. data/vendor/assets/stylesheets/bootstrap/_pager.scss +30 -0
  276. data/vendor/assets/stylesheets/bootstrap/_pagination.scss +55 -0
  277. data/vendor/assets/stylesheets/bootstrap/_popovers.scss +49 -0
  278. data/vendor/assets/stylesheets/bootstrap/_progress-bars.scss +95 -0
  279. data/vendor/assets/stylesheets/bootstrap/_reset.scss +126 -0
  280. data/vendor/assets/stylesheets/bootstrap/_scaffolding.scss +33 -0
  281. data/vendor/assets/stylesheets/bootstrap/_sprites.scss +158 -0
  282. data/vendor/assets/stylesheets/bootstrap/_tables.scss +150 -0
  283. data/vendor/assets/stylesheets/bootstrap/_thumbnails.scss +35 -0
  284. data/vendor/assets/stylesheets/bootstrap/_tooltip.scss +35 -0
  285. data/vendor/assets/stylesheets/bootstrap/_type.scss +218 -0
  286. data/vendor/assets/stylesheets/bootstrap/_utilities.scss +23 -0
  287. data/vendor/assets/stylesheets/bootstrap/_variables.scss +107 -0
  288. data/vendor/assets/stylesheets/bootstrap/_wells.scss +17 -0
  289. data/vendor/assets/stylesheets/bootstrap/bootstrap.scss +66 -0
  290. data/vendor/assets/stylesheets/bootstrap/responsive.scss +334 -0
  291. metadata +506 -0
@@ -0,0 +1,78 @@
1
+ #
2
+ # Reproduced from https://github.com/rails/rails/pull/230/files for ActiveResource association support.
3
+ #
4
+ require 'active_support/core_ext/class/attribute'
5
+ require 'active_support/core_ext/module/deprecation'
6
+
7
+ module ActiveResource
8
+ # = Active Resource reflection
9
+ #
10
+ # Associations in ActiveResource would be used to resolve nested attributes
11
+ # in a response with correct classes.
12
+ # Now they could be specify over Associations with the options :class_name
13
+ module Reflection # :nodoc:
14
+ extend ActiveSupport::Concern
15
+
16
+ included do
17
+ class_attribute :reflections
18
+ self.reflections = {}
19
+ end
20
+
21
+ module ClassMethods
22
+ def create_reflection(macro, name, options)
23
+ reflection = AssociationReflection.new(macro, name, options)
24
+
25
+ # Simple reflection based abstraction
26
+ if (target = "#{reflection.class_name}Associations".safe_constantize)
27
+ method_name = "when_#{macro}".to_sym
28
+ target.send(method_name, self, options) if target.respond_to? method_name
29
+ end
30
+
31
+ self.reflections = self.reflections.merge(name => reflection)
32
+ reflection
33
+ end
34
+ end
35
+
36
+
37
+ class AssociationReflection
38
+
39
+ def initialize(macro, name, options)
40
+ @macro, @name, @options = macro, name, options
41
+ end
42
+
43
+ # Returns the name of the macro.
44
+ #
45
+ # <tt>has_many :clients</tt> returns <tt>:clients</tt>
46
+ attr_reader :name
47
+
48
+ # Returns the macro type.
49
+ #
50
+ # <tt>has_many :clients</tt> returns <tt>:has_many</tt>
51
+ attr_reader :macro
52
+
53
+ # Returns the hash of options used for the macro.
54
+ #
55
+ # <tt>has_many :clients</tt> returns +{}+
56
+ attr_reader :options
57
+
58
+ # Returns the class for the macro.
59
+ #
60
+ # <tt>has_many :clients</tt> returns the Client class
61
+ def klass
62
+ @klass ||= class_name.constantize
63
+ end
64
+
65
+ # Returns the class name for the macro.
66
+ #
67
+ # <tt>has_many :clients</tt> returns <tt>'Client'</tt>
68
+ def class_name
69
+ @class_name ||= derive_class_name
70
+ end
71
+
72
+ private
73
+ def derive_class_name
74
+ return (options[:class_name] ? options[:class_name].to_s : name.to_s).classify
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,8 @@
1
+ module Console
2
+ class AccessDenied < StandardError ; end
3
+ class ApiNotAvailable < StandardError ; end
4
+ end
5
+
6
+ require 'console/version'
7
+ require 'console/engine'
8
+
@@ -0,0 +1,13 @@
1
+ module Console
2
+ class ConfigFile < HashWithIndifferentAccess
3
+ def initialize(file)
4
+ IO.read(File.expand_path(file)).lines.
5
+ map{ |s| s.gsub(/((^|[^\\])(\\\\)*)#.*/,'\1') }. # eliminate unescaped comments
6
+ each do |s|
7
+ if pair = /^\s*(.*?[^\\]+?(?:\\\\)*)=(.*)$/.match(s)
8
+ self[pair[1].strip.gsub(/\\(.)/,'\1')] = pair[2].strip.gsub(/\\(.)/,'\1')
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,163 @@
1
+ require 'active_support/configurable'
2
+ require 'active_support/core_ext/hash'
3
+ require 'console/config_file'
4
+
5
+ module Console
6
+
7
+ # Configures global settings for Console
8
+ # Console.configure do |config|
9
+ # config.disable_assets = 10
10
+ # end
11
+ def self.configure(file=nil,&block)
12
+ config.send(:load, file) if file
13
+ yield config if block_given?
14
+ end
15
+
16
+ # Global settings for Console
17
+ def self.config
18
+ @config ||= Configuration.new
19
+ end
20
+
21
+ class InvalidConfiguration < StandardError ; end
22
+
23
+ class Configuration #:nodoc:
24
+ include ActiveSupport::Configurable
25
+
26
+ config_accessor :disable_static_assets
27
+ config_accessor :parent_controller
28
+
29
+ config_accessor :security_controller
30
+ config_accessor :remote_user_header
31
+ config_accessor :remote_user_name_header
32
+ config_accessor :remote_user_copy_headers
33
+
34
+ config_accessor :disable_account
35
+ config_accessor :cartridge_type_metadata
36
+ config_accessor :include_helpers
37
+
38
+ Builtin = {
39
+ :openshift => {
40
+ :url => 'https://openshift.redhat.com/broker/rest',
41
+ :suffix => 'rhcloud.com'
42
+ },
43
+ :local => {
44
+ :url => 'https://localhost/broker/rest',
45
+ :suffix => 'dev.rhcloud.com'
46
+ }
47
+ }
48
+ Builtin.freeze
49
+
50
+ def api=(config)
51
+ config = case
52
+ when Builtin[config]
53
+ source = config
54
+ Builtin[config]
55
+ when config == :external
56
+ source = '~/.openshift/console.conf'
57
+ api_config_from(Console::ConfigFile.new(source))
58
+ when config.respond_to?(:[])
59
+ source = 'object in config'
60
+ Builtin[:openshift].with_indifferent_access.merge(config)
61
+ else
62
+ raise InvalidConfiguration, "Invalid argument to Console.config.api #{config.inspect}"
63
+ end
64
+
65
+ unless config[:url]
66
+ raise InvalidConfiguration, <<-EXCEPTION.strip_heredoc
67
+ The console requires that Console.config.api be set to a symbol or endpoint configuration object. Active configuration is #{Rails.env}
68
+
69
+ '#{config.inspect}' via #{source} is not valid.
70
+
71
+ Valid symbols: #{Builtin.each_key.collect {|k| ":#{k}"}.concat([:external]).join(', ')}
72
+ Valid api object:
73
+ {
74
+ :url => '' # A URL pointing to the root of the REST API, e.g.
75
+ # https://openshift.redhat.com/broker/rest
76
+ }
77
+ EXCEPTION
78
+ end
79
+
80
+ freeze_api(config, source)
81
+ end
82
+ def api
83
+ @api
84
+ end
85
+
86
+ def cartridge_type_metadata
87
+ @cartridge_type_metadata || File.expand_path(File.join('config', 'cartridge_types.yml'), Console::Engine.root)
88
+ end
89
+
90
+ def user_agent
91
+ @user_agent ||= "openshift_console/#{Console::VERSION::STRING} (ruby #{RUBY_VERSION}; #{RUBY_PLATFORM})"
92
+ end
93
+ def user_agent=(agent)
94
+ @user_agent = agent
95
+ end
96
+
97
+ protected
98
+
99
+ def load(file)
100
+ config = Console::ConfigFile.new(file)
101
+ raise InvalidConfiguration, "BROKER_URL not specified in #{file}" unless config[:BROKER_URL]
102
+
103
+ freeze_api(api_config_from(config), file)
104
+
105
+ case config[:CONSOLE_SECURITY]
106
+ when 'basic'
107
+ self.security_controller = 'Console::Auth::Basic'
108
+ when 'remote_user'
109
+ self.security_controller = 'Console::Auth::RemoteUser'
110
+ [:remote_user_copy_headers, :remote_user_header, :remote_user_name_header].each do |s|
111
+ value = config[s.upcase]
112
+ self.send(:"#{s}=", s.to_s.ends_with?('s') ? value.split(',') : value) if value
113
+ end
114
+ when String
115
+ self.security_controller = config[:CONSOLE_SECURITY]
116
+ end
117
+ end
118
+
119
+ def to_ruby_value(s)
120
+ case
121
+ when s == nil
122
+ nil
123
+ when s[0] == '{'
124
+ eval(s)
125
+ when s[0] == ':'
126
+ s[1..-1].to_sym
127
+ when s =~ /^\d+$/
128
+ s.to_i
129
+ else
130
+ s
131
+ end
132
+ end
133
+
134
+ def api_config_from(config)
135
+ config.inject(HashWithIndifferentAccess.new) do |h, (k, v)|
136
+ if match = /^BROKER_API_(.*)/.match(k)
137
+ h[match[1].downcase] = to_ruby_value(v)
138
+ end
139
+ h
140
+ end.merge({
141
+ :url => config[:BROKER_URL],
142
+ :proxy => config[:BROKER_PROXY_URL],
143
+ :suffix => config[:DOMAIN_SUFFIX],
144
+ })
145
+ end
146
+
147
+ def freeze_api(config, source)
148
+ @api = {
149
+ :user_agent => user_agent,
150
+ }.with_indifferent_access.merge(config)
151
+ @api[:source] = source
152
+ @api.freeze
153
+ end
154
+ end
155
+
156
+ configure do |config|
157
+ config.disable_static_assets = false
158
+ config.disable_account = false
159
+ config.parent_controller = 'ApplicationController'
160
+ config.security_controller = 'Console::Auth::Basic'
161
+ config.include_helpers = true
162
+ end
163
+ end
@@ -0,0 +1,28 @@
1
+ require 'rails/engine'
2
+ require 'sprockets/railtie'
3
+
4
+ # Engines must explicitly require dependencies
5
+ require 'haml'
6
+ require 'formtastic'
7
+ require 'pp'
8
+
9
+ require 'console'
10
+ require 'console/configuration'
11
+
12
+ module Console
13
+ class Engine < Rails::Engine
14
+ config.before_initialize do
15
+ Haml.init_rails(binding)
16
+ Haml::Template.options[:format] = :html5
17
+ end
18
+ initializer "static assets" do |app|
19
+ unless Console.config.disable_static_assets or Rails.env.production?
20
+ app.middleware.insert_before(::ActionDispatch::Static, ::ActionDispatch::Static, "#{root}/public")
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ require 'console/rails/routes'
27
+ require 'console/rails/app_redirector'
28
+ require 'console/rails/filter_hash'
@@ -0,0 +1,369 @@
1
+ require 'formtastic'
2
+
3
+ module Console
4
+ module Formtastic
5
+ class BootstrapFormBuilder < ::Formtastic::SemanticFormBuilder
6
+
7
+ def initialize(object_name, object, template, options, proc)
8
+ options[:html] ||= {}
9
+ class_names = options[:html][:class] ? options[:html][:class].split(" ") : []
10
+
11
+ class_names << 'form-inline' if options[:simple]
12
+ options[:html][:class] = class_names.join(" ")
13
+
14
+ super
15
+ end
16
+
17
+ # set the default css class
18
+ def buttons(*args)
19
+ options = args.extract_options!
20
+ options[:class] ||= @options[:simple] ? 'btn-toolbar' : 'form-actions'
21
+ super *(args << options)
22
+ end
23
+
24
+ def loading(*args)
25
+ image = template.instance_variable_get(:@loader_image) || template.image_path('loader.gif')
26
+ template.content_tag(:img, nil, :alt => 'Working...', 'data-loading' => 'true', :class => 'icon-loading', :style => 'display: none', :src => image)
27
+ end
28
+
29
+ # override tag creation
30
+ def field_set_and_list_wrapping(*args, &block) #:nodoc:
31
+ contents = args.last.is_a?(::Hash) ? '' : args.pop.flatten
32
+ html_options = args.extract_options!
33
+
34
+ legend = html_options.dup.delete(:name).to_s
35
+ legend %= parent_child_index(html_options[:parent]) if html_options[:parent]
36
+ legend = template.content_tag(:legend, template.content_tag(:span, ::Formtastic::Util.html_safe(legend))) unless legend.blank?
37
+
38
+ if block_given?
39
+ contents = if template.respond_to?(:is_haml?) && template.is_haml?
40
+ template.capture_haml(&block)
41
+ else
42
+ template.capture(&block)
43
+ end
44
+ end
45
+
46
+ # Ruby 1.9: String#to_s behavior changed, need to make an explicit join.
47
+ contents = contents.join if contents.respond_to?(:join)
48
+ fieldset = template.content_tag(:fieldset,
49
+ ::Formtastic::Util.html_safe(legend) << ::Formtastic::Util.html_safe(contents), #changed
50
+ html_options.except(:builder, :parent)
51
+ )
52
+ template.concat(fieldset) if block_given? && !::Formtastic::Util.rails3?
53
+ fieldset
54
+ end
55
+
56
+ def semantic_errors(*args)
57
+ html_options = args.extract_options!
58
+ html_options[:class] ||= 'alert alert-error unstyled errors'
59
+
60
+ full_errors = args.inject([]) do |array, method|
61
+ attribute = localized_string(method, method.to_sym, :label) || humanized_attribute_name(method)
62
+ @object.errors[method.to_sym].each do |error|
63
+ if error.present?
64
+ error = [attribute, error].join(" ") unless error[0,1] == error[0,1].upcase
65
+ array << error
66
+ end
67
+ end
68
+ array
69
+ #errors = Array(@object.errors[method.to_sym]).to_sentence
70
+ #errors.present? ? array << [attribute, errors].join(" ") : array ||= []
71
+ end
72
+ full_errors << @object.errors[:base] unless html_options.delete(:not) == :base
73
+ full_errors.flatten!
74
+ full_errors.compact!
75
+ return nil if full_errors.blank?
76
+ #html_options[:class] ||= "errors"
77
+ template.content_tag(:ul, html_options) do
78
+ ::Formtastic::Util.html_safe(full_errors.map { |error| template.content_tag(:li, error) }.join)
79
+ end
80
+ end
81
+
82
+ def inline_hints_for(method, options) #:nodoc:
83
+ options[:hint] = localized_string(method, options[:hint], :hint)
84
+ return if options[:hint].blank? or options[:hint].kind_of? Hash
85
+ if input_inline?
86
+ @input_inline_hints << options[:hint]
87
+ return nil
88
+ end
89
+ hint_class = options[:hint_class] || default_hint_class
90
+ template.content_tag(:p, ::Formtastic::Util.html_safe(options[:hint]), :class => hint_class)
91
+ end
92
+
93
+ def inline_errors_for(method, options = {}) #:nodoc:
94
+ return nil unless render_inline_errors?
95
+ errors = error_keys(method, options).map do |x|
96
+ attribute = localized_string(x, x.to_sym, :label) || humanized_attribute_name(x)
97
+ @object.errors[x].map do |error|
98
+ (error[0,1] == error[0,1].upcase) ? error : [attribute, error].join(" ")
99
+ end
100
+ end.flatten.compact.uniq
101
+ return nil unless errors.any?
102
+ if input_inline?
103
+ @input_inline_errors << errors
104
+ return nil
105
+ end
106
+ send(:"error_#{inline_errors}", [*errors], options)
107
+ end
108
+
109
+ def error_list(errors, options = {}) #:nodoc:
110
+ error_class = options[:error_class] || default_inline_error_class
111
+ template.content_tag(:p, errors.join(' ').untaint, :class => error_class)
112
+ end
113
+
114
+ def inputs(*args, &block)
115
+ title = field_set_title_from_args(*args)
116
+ html_options = args.extract_options!
117
+ html_options[:class] ||= "inputs"
118
+ html_options[:name] = title
119
+
120
+ if html_options[:for] # Nested form
121
+ inputs_for_nested_attributes(*(args << html_options), &block)
122
+ elsif html_options[:inline]
123
+ @input_inline = true
124
+ @input_inline_errors = []
125
+ @input_inline_hints = []
126
+ fieldset = inline_fields_and_wrapping(*(args << html_options), &block)
127
+ @input_inline = false
128
+ @label = nil
129
+ fieldset
130
+ elsif block_given?
131
+ field_set_and_list_wrapping(*(args << html_options), &block)
132
+ else
133
+ if @object && args.empty?
134
+ args = association_columns(:belongs_to)
135
+ args += content_columns
136
+ args -= RESERVED_COLUMNS
137
+ args.compact!
138
+ end
139
+ legend = args.shift if args.first.is_a?(::String)
140
+ contents = args.collect { |method| input(method.to_sym) }
141
+ args.unshift(legend) if legend.present?
142
+
143
+ field_set_and_list_wrapping(*((args << html_options) << contents))
144
+ end
145
+ end
146
+
147
+ def inline_fields_and_wrapping(*args, &block)
148
+ contents = args.last.is_a?(::Hash) ? '' : args.pop.flatten
149
+ html_options = args.extract_options!
150
+
151
+ html_options.delete(:inline)
152
+ html_class = ['control-group']
153
+ html_class << 'control-group-important' if html_options.delete(:important)
154
+
155
+ label = template.content_tag(:label, ::Formtastic::Util.html_safe(html_options.dup.delete(:name).to_s) << required_or_optional_string(html_options.delete(:required)), { :class => 'control-label' }) if html_options[:name]
156
+
157
+ # Generate form elements
158
+ if block_given?
159
+ contents = if template.respond_to?(:is_haml?) && template.is_haml?
160
+ template.capture_haml(&block)
161
+ else
162
+ template.capture(&block)
163
+ end
164
+ end
165
+
166
+ # Ruby 1.9: String#to_s behavior changed, need to make an explicit join.
167
+ #contents = contents.join if contents.respond_to?(:join)
168
+ unless html_options[:without_errors]
169
+ contents << send(:"error_#{inline_errors}", [*@input_inline_errors], {})
170
+ html_class << 'error' unless @input_inline_errors.empty?
171
+ end
172
+
173
+ @input_inline_hints.each do |hint|
174
+ contents << template.content_tag(:p, hint, :class => default_hint_class)
175
+ end
176
+
177
+ template.content_tag(:div, ::Formtastic::Util.html_safe(label || '') << template.content_tag(:div, ::Formtastic::Util.html_safe(contents), {:class => 'controls'}), { :class => html_class.join(' ') })
178
+ end
179
+
180
+ def input_inline?
181
+ @input_inline
182
+ end
183
+
184
+ # change from li to div.control-group, move hints/errors into the input block
185
+ def input(method, options = {})
186
+ options = options.dup # Allow options to be shared without being tainted by Formtastic
187
+
188
+ options[:required] = method_required?(method) unless options.key?(:required)
189
+ options[:as] ||= default_input_type(method, options)
190
+
191
+ html_class = [
192
+ options[:as],
193
+ options[:required] ? :required : :optional,
194
+ 'control-group',
195
+ ] #changed
196
+ html_class << 'control-group-important' if options[:important]
197
+
198
+ wrapper_html = options.delete(:wrapper_html) || {}
199
+ if has_errors?(method, options)
200
+ html_class << 'error'
201
+
202
+ wrapper_html[:"data-server-error"] = "server-error"
203
+ end
204
+ wrapper_html[:id] ||= generate_html_id(method)
205
+ wrapper_html[:class] = (html_class << wrapper_html[:class]).flatten.compact.join(' ')
206
+
207
+ if options[:input_html] && options[:input_html][:id]
208
+ options[:label_html] ||= {}
209
+ options[:label_html][:for] ||= options[:input_html][:id]
210
+ end
211
+
212
+ # moved hint/error output inside basic_input_helper
213
+ safe_html_output = ::Formtastic::Util.html_safe(inline_input_for(method, options))
214
+ return safe_html_output if input_inline?
215
+ template.content_tag(:div, safe_html_output, wrapper_html) #changed to move to basic_input_helper
216
+ end
217
+
218
+ def parts(method, options, &block)
219
+ input_parts = (custom_inline_order[options[:as]] || inline_order).dup
220
+ input_parts = input_parts - [:errors, :hints] if options[:as] == :hidden
221
+ input_parts.map do |type|
222
+ (:input == type) ? yield : send(:"inline_#{type}_for", method, options)
223
+ end.compact.join("\n")
224
+ end
225
+
226
+ # wrap contents in div.controls
227
+ def basic_input_helper(form_helper_method, type, method, options) #:nodoc:
228
+ html_options = options.delete(:input_html) || {}
229
+ html_options = default_string_options(method, type).merge(html_options) if [:numeric, :string, :password, :text, :phone, :search, :url, :email].include?(type)
230
+ field_id = generate_html_id(method, "")
231
+ html_options[:id] ||= field_id
232
+ label_options = options_for_label(options)
233
+ label_options[:class] ||= 'control-label'
234
+ label_options[:for] ||= html_options[:id]
235
+
236
+ control_content = parts(method, options) do
237
+ send(respond_to?(form_helper_method) ? form_helper_method : :text_field, method, html_options)
238
+ end
239
+
240
+ safe_control_content = ::Formtastic::Util.html_safe(control_content)
241
+ input_inline? ? safe_control_content : label(method, label_options) << template.content_tag(:div, safe_control_content, {:class => 'controls'}) #added class
242
+ # end changes
243
+ end
244
+
245
+ # wrap select in a control
246
+ def select_input(method, options)
247
+ html_options = options.delete(:input_html) || {}
248
+ html_options[:multiple] = html_options[:multiple] || options.delete(:multiple)
249
+ html_options.delete(:multiple) if html_options[:multiple].nil?
250
+
251
+ reflection = reflection_for(method)
252
+ if reflection && [ :has_many, :has_and_belongs_to_many ].include?(reflection.macro)
253
+ html_options[:multiple] = true if html_options[:multiple].nil?
254
+ html_options[:size] ||= 5
255
+ options[:include_blank] ||= false
256
+ end
257
+ options = set_include_blank(options)
258
+ input_name = generate_association_input_name(method)
259
+ html_options[:id] ||= generate_html_id(input_name, "")
260
+
261
+ select_html = if options[:group_by]
262
+ # The grouped_options_select is a bit counter intuitive and not optimised (mostly due to ActiveRecord).
263
+ # The formtastic user however shouldn't notice this too much.
264
+ raw_collection = find_raw_collection_for_column(method, options.reverse_merge(:find_options => { :include => options[:group_by] }))
265
+ label, value = detect_label_and_value_method!(raw_collection, options)
266
+ group_collection = raw_collection.map { |option| option.send(options[:group_by]) }.uniq
267
+ group_label_method = options[:group_label_method] || detect_label_method(group_collection)
268
+ group_collection = group_collection.sort_by { |group_item| group_item.send(group_label_method) }
269
+ group_association = options[:group_association] || detect_group_association(method, options[:group_by])
270
+
271
+ # Here comes the monster with 8 arguments
272
+ grouped_collection_select(input_name, group_collection,
273
+ group_association, group_label_method,
274
+ value, label,
275
+ strip_formtastic_options(options), html_options)
276
+ else
277
+ collection = find_collection_for_column(method, options)
278
+
279
+ select(input_name, collection, strip_formtastic_options(options), html_options)
280
+ end
281
+
282
+ label_options = options_for_label(options).merge(:input_name => input_name)
283
+ label_options[:for] ||= html_options[:id]
284
+
285
+ select_html = parts(method, options) do
286
+ select_html
287
+ end
288
+
289
+ safe_select_html = ::Formtastic::Util.html_safe(select_html)
290
+
291
+ return safe_select_html if input_inline?
292
+ label(method, label_options) << template.content_tag(:div, safe_select_html, {:class => 'controls'})
293
+ end
294
+
295
+ def boolean_input(method, options)
296
+ html_options = options.delete(:input_html) || {}
297
+ checked_value = options.delete(:checked_value) || '1'
298
+ unchecked_value = options.delete(:unchecked_value) || '0'
299
+ checked = @object && ActionView::Helpers::InstanceTag.check_box_checked?(@object.send(:"#{method}"), checked_value)
300
+
301
+ html_options[:id] = html_options[:id] || generate_html_id(method, "")
302
+ input_html = template.check_box_tag(
303
+ "#{@object_name}[#{method}]",
304
+ checked_value,
305
+ checked,
306
+ html_options
307
+ )
308
+
309
+ label_options = options_for_label(options)
310
+ label_options[:for] ||= html_options[:id]
311
+ (label_options[:class] ||= []) << 'checkbox'
312
+
313
+ input_html << localized_string(method, label_options[:label], :label) || humanized_attribute_name(method)
314
+ label_options.delete :label
315
+
316
+ safe_input_html = ::Formtastic::Util.html_safe(input_html)
317
+
318
+ return safe_input_html if input_inline?
319
+
320
+ template.content_tag(:div, label(method, safe_input_html, label_options), {:class => 'controls'}) << template.hidden_field_tag((html_options[:name] || "#{@object_name}[#{method}]"), unchecked_value, :id => nil, :disabled => html_options[:disabled])
321
+ end
322
+
323
+ # remove the button wrapper
324
+ def commit_button(*args)
325
+ options = args.extract_options!
326
+ text = options.delete(:label) || args.shift
327
+
328
+ if @object && (@object.respond_to?(:persisted?) || @object.respond_to?(:new_record?))
329
+ if @object.respond_to?(:persisted?) # ActiveModel
330
+ key = @object.persisted? ? :update : :create
331
+ else # Rails 2
332
+ key = @object.new_record? ? :create : :update
333
+ end
334
+
335
+ # Deal with some complications with ActiveRecord::Base.human_name and two name models (eg UserPost)
336
+ # ActiveRecord::Base.human_name falls back to ActiveRecord::Base.name.humanize ("Userpost")
337
+ # if there's no i18n, which is pretty crappy. In this circumstance we want to detect this
338
+ # fall back (human_name == name.humanize) and do our own thing name.underscore.humanize ("User Post")
339
+ if @object.class.model_name.respond_to?(:human)
340
+ object_name = @object.class.model_name.human
341
+ else
342
+ object_human_name = @object.class.human_name # default is UserPost => "Userpost", but i18n may do better ("User post")
343
+ crappy_human_name = @object.class.name.humanize # UserPost => "Userpost"
344
+ decent_human_name = @object.class.name.underscore.humanize # UserPost => "User post"
345
+ object_name = (object_human_name == crappy_human_name) ? decent_human_name : object_human_name
346
+ end
347
+ else
348
+ key = :submit
349
+ object_name = @object_name.to_s.send(label_str_method)
350
+ end
351
+
352
+ text = (localized_string(key, text, :action, :model => object_name) ||
353
+ ::Formtastic::I18n.t(key, :model => object_name)) unless text.is_a?(::String)
354
+
355
+ button_html = options.delete(:button_html) || {}
356
+ button_html.merge!(:class => [button_html[:class] || 'btn btn-primary', key].compact.join(' '))
357
+
358
+ #remove need for wrapper
359
+ #wrapper_html_class = ['btn-primary'] #changed # TODO: Add class reflecting on form action.
360
+ #wrapper_html = options.delete(:wrapper_html) || {}
361
+ #wrapper_html[:class] = (wrapper_html_class << wrapper_html[:class]).flatten.compact.join(' ')
362
+
363
+ accesskey = (options.delete(:accesskey) || default_commit_button_accesskey) unless button_html.has_key?(:accesskey)
364
+ button_html = button_html.merge(:accesskey => accesskey) if accesskey
365
+ submit(text, button_html) # no wrapper
366
+ end
367
+ end
368
+ end
369
+ end