18794: Add version and config metrics to workbench1.
[arvados.git] / apps / workbench / config / arvados_config.rb
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: AGPL-3.0
4
5 #
6 # Load Arvados configuration from /etc/arvados/config.yml, using defaults
7 # from config.default.yml
8 #
9 # Existing application.yml is migrated into the new config structure.
10 # Keys in the legacy application.yml take precedence.
11 #
12 # Use "bundle exec config:dump" to get the complete active configuration
13 #
14 # Use "bundle exec config:migrate" to migrate application.yml to
15 # config.yml.  After adding the output of config:migrate to
16 # /etc/arvados/config.yml, you will be able to delete application.yml.
17
18 require 'config_loader'
19 require 'config_validators'
20 require 'open3'
21
22 # Load the defaults, used by config:migrate and fallback loading
23 # legacy application.yml
24 load_time = Time.now.utc
25 defaultYAML, stderr, status = Open3.capture3("arvados-server", "config-dump", "-config=-", "-skip-legacy", stdin_data: "Clusters: {xxxxx: {}}")
26 if !status.success?
27   puts stderr
28   raise "error loading config: #{status}"
29 end
30 confs = YAML.load(defaultYAML, deserialize_symbols: false)
31 clusterID, clusterConfig = confs["Clusters"].first
32 $arvados_config_defaults = clusterConfig
33 $arvados_config_defaults["ClusterID"] = clusterID
34 $arvados_config_defaults["SourceTimestamp"] = Time.rfc3339(confs["SourceTimestamp"])
35 $arvados_config_defaults["SourceSHA256"] = confs["SourceSHA256"]
36
37 if ENV["ARVADOS_CONFIG"] == "none"
38   # Don't load config. This magic value is set by packaging scripts so
39   # they can run "rake assets:precompile" without a real config.
40   $arvados_config_global = $arvados_config_defaults.deep_dup
41 else
42   # Load the global config file
43   Open3.popen2("arvados-server", "config-dump", "-skip-legacy") do |stdin, stdout, status_thread|
44     confs = YAML.load(stdout, deserialize_symbols: false)
45     if confs && !confs.empty?
46       # config-dump merges defaults with user configuration, so every
47       # key should be set.
48       clusterID, clusterConfig = confs["Clusters"].first
49       $arvados_config_global = clusterConfig
50       $arvados_config_global["ClusterID"] = clusterID
51       $arvados_config_global["SourceTimestamp"] = Time.rfc3339(confs["SourceTimestamp"])
52       $arvados_config_global["SourceSHA256"] = confs["SourceSHA256"]
53     else
54       # config-dump failed, assume we will be loading from legacy
55       # application.yml, initialize with defaults.
56       $arvados_config_global = $arvados_config_defaults.deep_dup
57     end
58   end
59 end
60
61 # Now make a copy
62 $arvados_config = $arvados_config_global.deep_dup
63 $arvados_config["LoadTimestamp"] = load_time
64
65 # Declare all our configuration items.
66 arvcfg = ConfigLoader.new
67
68 arvcfg.declare_config "ManagementToken", String, :ManagementToken
69 arvcfg.declare_config "TLS.Insecure", Boolean, :arvados_insecure_https
70 arvcfg.declare_config "Collections.TrustAllContent", Boolean, :trust_all_content
71
72 arvcfg.declare_config "Services.Controller.ExternalURL", URI, :arvados_v1_base, ->(cfg, k, v) {
73   u = URI(v)
74   u.path = ""
75   ConfigLoader.set_cfg cfg, "Services.Controller.ExternalURL", u
76 }
77
78 arvcfg.declare_config "Services.WebShell.ExternalURL", URI, :shell_in_a_box_url, ->(cfg, k, v) {
79   v ||= ""
80   u = URI(v.sub("%{hostname}", "*"))
81   u.path = ""
82   ConfigLoader.set_cfg cfg, "Services.WebShell.ExternalURL", u
83 }
84
85 arvcfg.declare_config "Services.WebDAV.ExternalURL", URI, :keep_web_url, ->(cfg, k, v) {
86   v ||= ""
87   u = URI(v.sub("%{uuid_or_pdh}", "*"))
88   u.path = ""
89   ConfigLoader.set_cfg cfg, "Services.WebDAV.ExternalURL", u
90 }
91
92 arvcfg.declare_config "Services.WebDAVDownload.ExternalURL", URI, :keep_web_download_url, ->(cfg, k, v) {
93   v ||= ""
94   u = URI(v.sub("%{uuid_or_pdh}", "*"))
95   u.path = ""
96   ConfigLoader.set_cfg cfg, "Services.WebDAVDownload.ExternalURL", u
97 }
98
99 arvcfg.declare_config "Services.Composer.ExternalURL", URI, :composer_url
100 arvcfg.declare_config "Services.Workbench2.ExternalURL", URI, :workbench2_url
101
102 arvcfg.declare_config "Users.AnonymousUserToken", String, :anonymous_user_token
103
104 arvcfg.declare_config "Workbench.SecretKeyBase", String, :secret_key_base
105
106 arvcfg.declare_config "Workbench.ApplicationMimetypesWithViewIcon", Hash, :application_mimetypes_with_view_icon, ->(cfg, k, v) {
107   mimetypes = {}
108   v.each do |m|
109     mimetypes[m] = {}
110   end
111   ConfigLoader.set_cfg cfg, "Workbench.ApplicationMimetypesWithViewIcon", mimetypes
112 }
113
114 arvcfg.declare_config "Workbench.RunningJobLogRecordsToFetch", Integer, :running_job_log_records_to_fetch
115 arvcfg.declare_config "Workbench.LogViewerMaxBytes", Integer, :log_viewer_max_bytes
116 arvcfg.declare_config "Workbench.ProfilingEnabled", Boolean, :profiling_enabled
117 arvcfg.declare_config "Workbench.APIResponseCompression", Boolean, :api_response_compression
118 arvcfg.declare_config "Workbench.UserProfileFormFields", Hash, :user_profile_form_fields, ->(cfg, k, v) {
119   if !v
120     v = []
121   end
122   entries = {}
123   v.each_with_index do |s,i|
124     entries[s["key"]] = {
125       "Type" => s["type"],
126       "FormFieldTitle" => s["form_field_title"],
127       "FormFieldDescription" => s["form_field_description"],
128       "Required" => s["required"],
129       "Position": i
130     }
131     if s["options"]
132       entries[s["key"]]["Options"] = {}
133       s["options"].each do |o|
134         entries[s["key"]]["Options"][o] = {}
135       end
136     end
137   end
138   ConfigLoader.set_cfg cfg, "Workbench.UserProfileFormFields", entries
139 }
140 arvcfg.declare_config "Workbench.UserProfileFormMessage", String, :user_profile_form_message
141 arvcfg.declare_config "Workbench.Theme", String, :arvados_theme
142 arvcfg.declare_config "Workbench.ShowUserNotifications", Boolean, :show_user_notifications
143 arvcfg.declare_config "Workbench.ShowUserAgreementInline", Boolean, :show_user_agreement_inline
144 arvcfg.declare_config "Workbench.RepositoryCache", String, :repository_cache
145 arvcfg.declare_config "Workbench.Repositories", Boolean, :repositories
146 arvcfg.declare_config "Workbench.APIClientConnectTimeout", ActiveSupport::Duration, :api_client_connect_timeout
147 arvcfg.declare_config "Workbench.APIClientReceiveTimeout", ActiveSupport::Duration, :api_client_receive_timeout
148 arvcfg.declare_config "Workbench.APIResponseCompression", Boolean, :api_response_compression
149 arvcfg.declare_config "Workbench.SiteName", String, :site_name
150 arvcfg.declare_config "Workbench.MultiSiteSearch", String, :multi_site_search, ->(cfg, k, v) {
151   if !v
152     v = ""
153   end
154   ConfigLoader.set_cfg cfg, "Workbench.MultiSiteSearch", v.to_s
155 }
156 arvcfg.declare_config "Workbench.EnablePublicProjectsPage", Boolean, :enable_public_projects_page
157 arvcfg.declare_config "Workbench.EnableGettingStartedPopup", Boolean, :enable_getting_started_popup
158 arvcfg.declare_config "Workbench.ArvadosPublicDataDocURL", String, :arvados_public_data_doc_url
159 arvcfg.declare_config "Workbench.ArvadosDocsite", String, :arvados_docsite
160 arvcfg.declare_config "Workbench.ShowRecentCollectionsOnDashboard", Boolean, :show_recent_collections_on_dashboard
161 arvcfg.declare_config "Workbench.ActivationContactLink", String, :activation_contact_link
162 arvcfg.declare_config "Workbench.DefaultOpenIdPrefix", String, :default_openid_prefix
163
164 arvcfg.declare_config "Mail.SendUserSetupNotificationEmail", Boolean, :send_user_setup_notification_email
165 arvcfg.declare_config "Mail.IssueReporterEmailFrom", String, :issue_reporter_email_from
166 arvcfg.declare_config "Mail.IssueReporterEmailTo", String, :issue_reporter_email_to
167 arvcfg.declare_config "Mail.SupportEmailAddress", String, :support_email_address
168 arvcfg.declare_config "Mail.EmailFrom", String, :email_from
169
170 application_config = {}
171 %w(application.default application).each do |cfgfile|
172   path = "#{::Rails.root.to_s}/config/#{cfgfile}.yml"
173   confs = ConfigLoader.load(path, erb: true)
174   # Ignore empty YAML file:
175   next if confs == false
176   application_config.deep_merge!(confs['common'] || {})
177   application_config.deep_merge!(confs[::Rails.env.to_s] || {})
178 end
179
180 $remaining_config = arvcfg.migrate_config(application_config, $arvados_config)
181
182 # Checks for wrongly typed configuration items, coerces properties
183 # into correct types (such as Duration), and optionally raise error
184 # for essential configuration that can't be empty.
185 arvcfg.coercion_and_check $arvados_config_defaults, check_nonempty: false
186 arvcfg.coercion_and_check $arvados_config_global, check_nonempty: false
187 arvcfg.coercion_and_check $arvados_config, check_nonempty: true
188
189 # * $arvados_config_defaults is the defaults
190 # * $arvados_config_global is $arvados_config_defaults merged with the contents of /etc/arvados/config.yml
191 # These are used by the rake config: tasks
192 #
193 # * $arvados_config is $arvados_config_global merged with the migrated contents of application.yml
194 # This is what actually gets copied into the Rails configuration object.
195
196 ArvadosWorkbench::Application.configure do
197   # Copy into the Rails config object.  This also turns Hash into
198   # OrderedOptions so that application code can use
199   # Rails.configuration.API.Blah instead of
200   # Rails.configuration.API["Blah"]
201   ConfigLoader.copy_into_config $arvados_config, config
202   ConfigLoader.copy_into_config $remaining_config, config
203   secrets.secret_key_base = $arvados_config["Workbench"]["SecretKeyBase"]
204   if ENV["ARVADOS_CONFIG"] != "none"
205     ConfigValidators.validate_wb2_url_config()
206     ConfigValidators.validate_download_config()
207   end
208   if Rails.configuration.Users.AnonymousUserToken and
209      !Rails.configuration.Users.AnonymousUserToken.starts_with?("v2/")
210     Rails.configuration.Users.AnonymousUserToken = "v2/#{clusterID}-gj3su-anonymouspublic/#{Rails.configuration.Users.AnonymousUserToken}"
211   end
212 end