Steve Linabery
2009-Jan-09 01:50 UTC
[Ovirt-devel] [PATCH server] (Legit) Add audit trl for hosts join/leaving hwpools w/Rails observer class
Modify graph_controller.rb to utilize new audit feature when generating data for flexchart --- src/app/controllers/graph_controller.rb | 64 +++++++++++++++++++++++++-- src/app/models/hardware_pool.rb | 2 +- src/app/models/host.rb | 9 ++++ src/app/models/host_observer.rb | 47 ++++++++++++++++++++ src/app/models/membership_audit_event.rb | 26 +++++++++++ src/app/models/pool.rb | 1 + src/config/environment.rb | 2 +- src/db/migrate/033_add_pool_audit_trail.rb | 44 +++++++++++++++++++ 8 files changed, 188 insertions(+), 7 deletions(-) create mode 100644 src/app/models/host_observer.rb create mode 100644 src/app/models/membership_audit_event.rb create mode 100644 src/db/migrate/033_add_pool_audit_trail.rb diff --git a/src/app/controllers/graph_controller.rb b/src/app/controllers/graph_controller.rb index ee9425f..e8eea7e 100644 --- a/src/app/controllers/graph_controller.rb +++ b/src/app/controllers/graph_controller.rb @@ -6,9 +6,9 @@ class GraphController < ApplicationController def flexchart_data @id = params[:id] target = params[:target] - startTime = params[:startTime].to_i - endTime = params[:endTime].to_i - duration = endTime - startTime + startTime = Time.at(params[:startTime].to_i) + endTime = Time.at(params[:endTime].to_i) + duration = endTime.to_i - startTime.to_i #the maximum number of data points we want in any chart maxPoints = 100 @@ -29,10 +29,30 @@ class GraphController < ApplicationController counter = DEV_KEY_COUNTERS[target] pool = Pool.find(@id) - hosts = pool.hosts + hosts = Host.find(:all, + :include=> :membership_audit_events, + :conditions => ['membership_audit_events.container_target_id = ?',pool]) + requestList = [ ] hosts.each{ |host| - requestList.push StatsRequest.new(host.hostname, devclass, 0, counter, startTime, duration, resolution, DataFunction::Peak) + eventsInRange = host.membership_audit_events.from_pool(pool, + startTime, + endTime) + priorAuditEvent = host.membership_audit_events.most_recent_prior_event_from_pool(pool,startTime) + timeRanges = get_ranges_from_event_list(eventsInRange, + priorAuditEvent, + startTime, + endTime) + timeRanges.each{ |range| + requestList.push StatsRequest.new(host.hostname, + devclass, + 0, + counter, + range[0].to_i, + range[1].to_i - range[0].to_i, + resolution, + DataFunction::Peak) + } } statsList = getAggregateStatsData?(requestList) @@ -51,6 +71,40 @@ class GraphController < ApplicationController render :json => graph end + def get_ranges_from_event_list(list, priorEvent, startTime, endTime) + + results = Array.new + range = [startTime,endTime] + + joined = false + if priorEvent + if priorEvent.action == MembershipAuditEvent::JOIN + joined = true + end + end + + list.each_with_index { |event,index| + if event.action == MembershipAuditEvent::JOIN + joined = true + range[0] = event.created_at + else + range[0] = startTime unless joined + joined = false + range[1] = event.created_at + results.push Array.new(range) + range = [startTime,endTime] + end + } + + if joined + range[1] = endTime + results.push Array.new(range) + end + + results + end + + # generate layout for availability bar graphs def availability_graph diff --git a/src/app/models/hardware_pool.rb b/src/app/models/hardware_pool.rb index d39d8e7..b72d485 100644 --- a/src/app/models/hardware_pool.rb +++ b/src/app/models/hardware_pool.rb @@ -54,7 +54,7 @@ class HardwarePool < Pool hosts = Host.find(:all, :conditions => "id in (#{host_ids.join(', ')})") transaction do hosts.each do |host| - host.hardware_pool_id = target_pool_id + host.hardware_pool = HardwarePool.find(target_pool_id) host.save! end end diff --git a/src/app/models/host.rb b/src/app/models/host.rb index 640782d..813bc1d 100644 --- a/src/app/models/host.rb +++ b/src/app/models/host.rb @@ -23,6 +23,15 @@ class Host < ActiveRecord::Base belongs_to :hardware_pool belongs_to :bonding_type + has_many :membership_audit_events, :as => :member_target, :dependent => :destroy, :order => "created_at ASC" do + def from_pool(pool,startTime,endTime) + find(:all, :conditions=> ['container_target_id = ? and created_at between ? and ?',pool,startTime,endTime]) + end + def most_recent_prior_event_from_pool(pool,startTime) + find(:last, :conditions=> ['container_target_id = ? and created_at < ?',pool,startTime]) + end + end + has_many :cpus, :dependent => :destroy has_many :nics, :dependent => :destroy has_many :bondings, :dependent => :destroy diff --git a/src/app/models/host_observer.rb b/src/app/models/host_observer.rb new file mode 100644 index 0000000..df5efa1 --- /dev/null +++ b/src/app/models/host_observer.rb @@ -0,0 +1,47 @@ +# +# Copyright (C) 2008 Red Hat, Inc. +# Written by Steve Linabery <slinabery at redhat.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. A copy of the GNU General Public License is +# also available at http://www.gnu.org/copyleft/gpl.html. + +class HostObserver < ActiveRecord::Observer + + def after_create(a_host) + join = MembershipAuditEvent.new({ :member_target => a_host, + :container_target => a_host.hardware_pool, + :action => MembershipAuditEvent::JOIN }) + join.save! + end + + def before_update(a_host) + if a_host.changed? + change = a_host.changes['hardware_pool_id'] + if change + leave = MembershipAuditEvent.new({ :member_target => a_host, + :container_target => HardwarePool.find(change[0]), + :action => MembershipAuditEvent::LEAVE }) + leave.save! + + join = MembershipAuditEvent.new({ :member_target => a_host, + :container_target => HardwarePool.find(change[1]), + :action => MembershipAuditEvent::JOIN }) + join.save! + end + end + end +end + +HostObserver.instance diff --git a/src/app/models/membership_audit_event.rb b/src/app/models/membership_audit_event.rb new file mode 100644 index 0000000..b36cbee --- /dev/null +++ b/src/app/models/membership_audit_event.rb @@ -0,0 +1,26 @@ +# +# Copyright (C) 2008 Red Hat, Inc. +# Written by Steve Linabery <slinabery at redhat.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. A copy of the GNU General Public License is +# also available at http://www.gnu.org/copyleft/gpl.html. + +class MembershipAuditEvent < ActiveRecord::Base + belongs_to :container_target, :polymorphic => true + belongs_to :member_target, :polymorphic => true + + JOIN = "join" + LEAVE = "leave" +end diff --git a/src/app/models/pool.rb b/src/app/models/pool.rb index 7034e79..614325a 100644 --- a/src/app/models/pool.rb +++ b/src/app/models/pool.rb @@ -20,6 +20,7 @@ class Pool < ActiveRecord::Base acts_as_nested_set + has_many :membership_audit_events, :as => :container_target, :dependent => :destroy # moved associations here so that nested set :include directives work # TODO: find a way to put this back into vm_resource_pool.rb has_many :vms, :dependent => :nullify, :order => "id ASC", :foreign_key => :vm_resource_pool_id diff --git a/src/config/environment.rb b/src/config/environment.rb index 53edfad..66cae90 100644 --- a/src/config/environment.rb +++ b/src/config/environment.rb @@ -82,7 +82,7 @@ Rails::Initializer.run do |config| # Activate observers that should always be running # config.active_record.observers = :cacher, :garbage_collector - + config.active_record.observers = :host_observer end # Add new inflection rules using the following format diff --git a/src/db/migrate/033_add_pool_audit_trail.rb b/src/db/migrate/033_add_pool_audit_trail.rb new file mode 100644 index 0000000..d4b4338 --- /dev/null +++ b/src/db/migrate/033_add_pool_audit_trail.rb @@ -0,0 +1,44 @@ +# +# Copyright (C) 2008 Red Hat, Inc. +# Written by Steve Linabery <slinabery at redhat.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. A copy of the GNU General Public License is +# also available at http://www.gnu.org/copyleft/gpl.html. + +class AddPoolAuditTrail < ActiveRecord::Migration + def self.up + create_table :membership_audit_events do |t| + t.timestamp :created_at + t.string :action + t.integer :container_target_id + t.string :container_target_type + t.integer :member_target_id + t.string :member_target_type + t.integer :lock_version, :default => 0 + end + + Host.transaction do + Host.find(:all).each do |host| + + if (! host.membership_audit_events) + event = MembershipAuditEvent.new(:action => MembershipAuditEvent::JOIN, + :container_target => host.hardware_pool, + :member_target => host) + event.save! + end + end + end + end +end -- 1.6.0.6
Scott Seago
2009-Jan-09 22:33 UTC
[Ovirt-devel] [PATCH server] (Legit) Add audit trl for hosts join/leaving hwpools w/Rails observer class
Steve Linabery wrote:> Modify graph_controller.rb to utilize new audit feature when generating data for flexchart > --- > src/app/controllers/graph_controller.rb | 64 +++++++++++++++++++++++++-- > src/app/models/hardware_pool.rb | 2 +- > src/app/models/host.rb | 9 ++++ > src/app/models/host_observer.rb | 47 ++++++++++++++++++++ > src/app/models/membership_audit_event.rb | 26 +++++++++++ > src/app/models/pool.rb | 1 + > src/config/environment.rb | 2 +- > src/db/migrate/033_add_pool_audit_trail.rb | 44 +++++++++++++++++++ > 8 files changed, 188 insertions(+), 7 deletions(-) > create mode 100644 src/app/models/host_observer.rb > create mode 100644 src/app/models/membership_audit_event.rb > create mode 100644 src/db/migrate/033_add_pool_audit_trail.rb > > diff --git a/src/db/migrate/033_add_pool_audit_trail.rb b/src/db/migrate/033_add_pool_audit_trail.rb > new file mode 100644 > index 0000000..d4b4338 > --- /dev/null > +++ b/src/db/migrate/033_add_pool_audit_trail.rb > @@ -0,0 +1,44 @@ > +class AddPoolAuditTrail < ActiveRecord::Migration > + def self.up > + create_table :membership_audit_events do |t| > + t.timestamp :created_at > + t.string :action > + t.integer :container_target_id > + t.string :container_target_type > + t.integer :member_target_id > + t.string :member_target_type > + t.integer :lock_version, :default => 0 > + end > + > + Host.transaction do > + Host.find(:all).each do |host| > + > + if (! host.membership_audit_events) >This line needs to be changed to if (host.membership_audit_events.empty?)> + event = MembershipAuditEvent.new(:action => MembershipAuditEvent::JOIN, > + :container_target => host.hardware_pool, > + :member_target => host) > + event.save! > + end > + end > + end > + end > +end >You should also probably write the self.down action to remove the table if a downgrade is attempted. But other than these two migration issues, ACK -- seems to work fine for me. Scott