openshift-origin-console 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 (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