diff --git a/app/controllers/admin/hosts_controller.rb b/app/controllers/admin/hosts_controller.rb index cb281ce..db5b2cc 100644 --- a/app/controllers/admin/hosts_controller.rb +++ b/app/controllers/admin/hosts_controller.rb @@ -1,32 +1,40 @@ class Admin::HostsController < Admin::BaseController before_action :fetch_host, only: [:verify, :set_quota] # GET /admin/hosts/unverified def unverified @hosts = Host.unverified end # POST /admin/hosts/1/verify def verify @host.verify(current_user.id) redirect_to unverified_admin_hosts_path end # PUT /admin/hosts/1/set_quota def set_quota - @host.quota = params[:host][:quota] + @host.quota = case params[:unit] + when 'MB' + params[:quota].to_i * ConfigurationSetting::MEGA_BYTES + when 'GB' + params[:quota].to_i * ConfigurationSetting::GIGA_BYTES + when 'TB' + params[:quota].to_i * ConfigurationSetting::TERA_BYTES + end + if @host.save flash[:success] = 'Changes saved' else flash[:error] = 'Changes not saved' end redirect_to admin_client_path(@host.client) end private def fetch_host @host = Host.find(params[:id]) end end diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb index 994fabd..fda69cd 100644 --- a/app/controllers/admin/settings_controller.rb +++ b/app/controllers/admin/settings_controller.rb @@ -1,62 +1,79 @@ class Admin::SettingsController < Admin::BaseController before_action :fetch_configuration_settings, only: [:edit, :update, :reset] # GET /admin/settings def index @settings = ConfigurationSetting.last || ConfigurationSetting.new end # GET /admin/settings/new def new @setting = ConfigurationSetting.new end # GET /admin/settings/1/edit def edit end # POST /admin/settings def create @setting = ConfigurationSetting.new(fetch_params) if @setting.save flash[:success] = 'Configuration Submitted' redirect_to admin_settings_path else flash[:error] = 'Configuration was not submitted' render :new end end # PATCH /admin/settings/1/update def update if fetch_params.present? && @setting.update_attributes(fetch_params) flash[:success] = 'Configuration Submitted' redirect_to admin_settings_path else flash[:error] = 'Configuration was not submitted' render :edit end end # DELETE /admin/settings/1/reset def reset @setting.destroy redirect_to admin_settings_path end private def fetch_configuration_settings @setting = ConfigurationSetting.find(params[:id]) end def fetch_params + return @clean_params if @clean_params.present? + + @clean_params = required_params + + @clean_params[:client][:quota] = case @clean_params[:client].delete(:quota_unit) + when 'MB' + @clean_params[:client][:quota].to_i * ConfigurationSetting::MEGA_BYTES + when 'GB' + @clean_params[:client][:quota].to_i * ConfigurationSetting::GIGA_BYTES + when 'TB' + @clean_params[:client][:quota].to_i * ConfigurationSetting::TERA_BYTES + end + + @clean_params + end + + def required_params params.require(:configuration_setting). permit( job: [:storage, :pool, :messages, :priority, :'Write Bootstrap'], client: [:catalog, :file_retention, :file_retention_period_type, :job_retention, - :job_retention_period_type, :autoprune, :quota], + :job_retention_period_type, :autoprune, :quota, :quota_unit], pool: [:full, :differential, :incremental] ) end end diff --git a/app/models/configuration_setting.rb b/app/models/configuration_setting.rb index c3215b7..47400c2 100644 --- a/app/models/configuration_setting.rb +++ b/app/models/configuration_setting.rb @@ -1,119 +1,128 @@ # ConfigurationSetting class describes a model that keeps the current Bacula # configuration. # # It has some hard coded settings as defaults. # Archiving's admins can enter new settings concerning: # # * jobs # * clients # # and override the default ones. # # ConfigurationSetting is supposed to have only one record in persisted in the database # which will hold the altered configuration as a patch to the defaults. # Admins can reset this change at any time. class ConfigurationSetting < ActiveRecord::Base establish_connection ARCHIVING_CONF + extend ActionView::Helpers::NumberHelper + + MEGA_BYTES = 1024 * 1024 + GIGA_BYTES = MEGA_BYTES * 1024 + TERA_BYTES = GIGA_BYTES * 1024 serialize :job, JSON serialize :client, JSON serialize :pool, JSON JOB = { storage: :File, pool: Archiving.settings[:default_pool], messages: :Standard, priority: 10, :'Write Bootstrap' => '"/var/lib/bacula/%c.bsr"' } CLIENT = { catalog: 'MyCatalog', file_retention: 60, file_retention_period_type: 'days', job_retention: 180, job_retention_period_type: 'days', autoprune: 'yes', quota: Archiving.settings[:client_quota] } POOL = { full: Archiving.settings[:default_pool], differential: Archiving.settings[:default_pool], incremental: Archiving.settings[:default_pool] } RETENTION_PERIODS = %w{seconds minutes hours days weeks months quarters years} AUTOPRUNE_OPTIONS = ['yes', 'no'] # Fetches the current configuration for jobs. # # The current configuration is the last submitted record, patched to the default # settings. # If there is no record, the default settings are returned # # @return [Hash] with settings def self.current_job_settings (last || new).job.symbolize_keys.reverse_merge(JOB.dup) end # Fetches the current configuration for clients. # # The current configuration is the last submitted record, patched to the default # settings. # If there is no record, the default settings are returned # # @return [Hash] with settings def self.current_client_settings (last || new).client.symbolize_keys.reverse_merge(CLIENT.dup) end # Fetches the current configuration for pools. # # The current configuration is the last submitted record, patched to the default # settings. # If there is no record, the default settings are returned # # @return [Hash] with settings def self.current_pool_settings (last || new).pool.symbolize_keys.reverse_merge(POOL.dup) end # Fetches the provided client size quota # # @return [Integer] bytes space quota per client def self.client_quota current_client_settings[:quota] end # Fetches the record's configuration for jobs. # # The configuration is the record's configuration patched to the default # settings. # # @return [Hash] with settings def current_job_settings job.symbolize_keys.reverse_merge(JOB.dup) end # Fetches the record's configuration for clients. # # The configuration is the record's configuration patched to the default # settings. # # @return [Hash] with settings def current_client_settings client.symbolize_keys.reverse_merge(CLIENT.dup) end + def self.current_client_settings_human + current_client_settings.merge(quota: number_to_human_size(current_client_settings[:quota])) + end + # Fetches the record's configuration for pools. # # The configuration is the record's configuration patched to the default # settings. # # @return [Hash] with settings def current_pool_settings pool.symbolize_keys.reverse_merge(POOL.dup) end end diff --git a/app/views/admin/clients/show.html.erb b/app/views/admin/clients/show.html.erb index d18cba1..b53d0a0 100644 --- a/app/views/admin/clients/show.html.erb +++ b/app/views/admin/clients/show.html.erb @@ -1,65 +1,65 @@ <%= render partial: 'header' %>
<%= link_to '#', data: { toggle: 'modal', target: ".js-quota:first"}, class: "btn btn-default", role: "button" do %> Set Quota <% end %> <% if @client.host.can_block? %> <%= link_to 'Lock client', block_admin_client_path(@client), method: :post, data: { confirm: 'This will disable and lock the client. Are you sure?' }, class: "btn btn-warning", role: "button" %> <% end %> <% if @client.host.blocked? %> <%= link_to 'Unlock client', unblock_admin_client_path(@client), method: :post, data: { confirm: 'This will unlock the client. Are you sure?' }, class: "btn btn-warning", role: "button" %> <% end %> <%= link_to 'Remove client', revoke_admin_client_path(@client), method: :delete, data: { confirm: 'This will REMOVE the client from Bacula. Are you sure?' }, class: "btn btn-danger", role: "button" %>

Client Details

Bacula Jobs

<%= render partial: 'client_details' %>
<% if @client.host %> <%= render partial: 'jobs' %> <% end %>
diff --git a/app/views/admin/settings/_form.html.erb b/app/views/admin/settings/_form.html.erb index 41bd71c..11bb6c3 100644 --- a/app/views/admin/settings/_form.html.erb +++ b/app/views/admin/settings/_form.html.erb @@ -1,81 +1,82 @@ <%= bootstrap_form_for(@setting, url: path, layout: :horizontal, label_col: 'col-xs-5', control_col: 'col-xs-5') do |f| %>

Client


<%= f.fields_for :client do |c| %> <%= c.text_field :catalog, :value => @setting.current_client_settings[:catalog] %> <%= c.number_field :file_retention, :value => @setting.current_client_settings[:file_retention] %> <%= c.select :file_retention_period_type, options_for_select(ConfigurationSetting::RETENTION_PERIODS, @setting.current_client_settings[:file_retention_period_type]) %> <%= c.number_field :job_retention, :value => @setting.current_client_settings[:job_retention] %> <%= c.select :job_retention_period_type, options_for_select(ConfigurationSetting::RETENTION_PERIODS, @setting.current_client_settings[:job_retention_period_type]) %> <%= c.select :autoprune, ConfigurationSetting::AUTOPRUNE_OPTIONS, :value => @setting.current_client_settings[:autoprune] %> <%= c.number_field :quota, - :value => @setting.current_client_settings[:quota] %> + value: @setting.current_client_settings[:quota].to_i / ConfigurationSetting::MEGA_BYTES %> + <%= c.select(:quota_unit, ['MB', 'GB', 'TB'], value: 'MB') %> <% end %>

Job


<%= f.fields_for :job do |jb| %> <%= jb.select :storage, options_for_select(Storage.available_options, @setting.current_job_settings[:storage]) %> <%= jb.select :pool, options_for_select(Pool.available_options, @setting.current_job_settings[:pool]) %> <%= jb.text_field :messages, :value => @setting.current_job_settings[:messages] %> <%= jb.text_field :'Write Bootstrap', :value => @setting.current_job_settings[:'Write Bootstrap'] %> <%= jb.number_field :priority, :value => @setting.current_job_settings[:priority] %> <% end %>

Pool


<%= f.fields_for :pool do |p| %> <%= p.select :full, options_for_select(Pool.available_options, @setting.current_pool_settings[:full]) %> <%= p.select :differential, options_for_select(Pool.available_options, @setting.current_pool_settings[:differential]) %> <%= p.select :incremental, options_for_select(Pool.available_options, @setting.current_pool_settings[:incremental]) %> <% end %>
<%= link_to 'Cancel', admin_settings_path %>
<%= f.submit class: 'btn btn-success' %>

<% end %> diff --git a/app/views/admin/settings/index.html.erb b/app/views/admin/settings/index.html.erb index 3c934f3..f7956a5 100644 --- a/app/views/admin/settings/index.html.erb +++ b/app/views/admin/settings/index.html.erb @@ -1,48 +1,48 @@

Settings

<% if !@settings.persisted? %> <% end %>

Client Settings

Job Settings

Pool Settings

- <%= table_for(ConfigurationSetting.current_job_settings) %> + <%= table_for(ConfigurationSetting.current_client_settings_human) %>
- <%= table_for(ConfigurationSetting.current_client_settings) %> + <%= table_for(ConfigurationSetting.current_job_settings) %>
<%= table_for(ConfigurationSetting.current_pool_settings) %>
<%= link_to 'Change Config', @settings.persisted? ? edit_admin_setting_path(@settings) : new_admin_setting_path, class: 'btn btn-primary', role: 'button' %>
<% if @settings.persisted? %>
<%= link_to 'Restore to defaults', reset_admin_setting_path(@settings), method: :delete, data: { confirm: 'This will reset the configuration to the defaults' }, class: 'btn btn-danger', role: 'button' %>
<% end %>