[PATCH conductor] Redmine 3153 - Remove unnecessary partials
by Jirka Tomasek
This patch implements Redmine task #3153, cleans or fixes partials for catalogs,
config_servers, deployables, deployments, harware_profiles, instances and layouts.
It also fixes filters in provider_account, catalog details pages and fixes
permissions partial. Partials cleanup for the rest of the views will follow next
sprint.
11 years, 11 months
[PATCH conductor] Fixed setting of deployment state for existing deployments
by Jan Provazník
From: Jan Provaznik <jprovazn(a)redhat.com>
---
src/app/models/deployment.rb | 2 +-
...081132_update_state_for_existing_deployments.rb | 27 ++++++++++++++++++++
2 files changed, 28 insertions(+), 1 deletions(-)
create mode 100644 src/db/migrate/20120507081132_update_state_for_existing_deployments.rb
diff --git a/src/app/models/deployment.rb b/src/app/models/deployment.rb
index d7956ab..d15cc15 100644
--- a/src/app/models/deployment.rb
+++ b/src/app/models/deployment.rb
@@ -427,7 +427,7 @@ class Deployment < ActiveRecord::Base
json = super(options).merge({
:deployable_xml_name => deployable_xml.name,
:status => state,
- :translated_status => I18n.t("deployments.status.#{state}"),
+ :translated_state => I18n.t("deployments.status.#{state}"),
:status_description => I18n.t("deployments.status_description.#{state}"),
:instances_count => instances.count,
:failed_instances_count => failed_instances.count,
diff --git a/src/db/migrate/20120507081132_update_state_for_existing_deployments.rb b/src/db/migrate/20120507081132_update_state_for_existing_deployments.rb
new file mode 100644
index 0000000..be472a4
--- /dev/null
+++ b/src/db/migrate/20120507081132_update_state_for_existing_deployments.rb
@@ -0,0 +1,27 @@
+class UpdateStateForExistingDeployments < ActiveRecord::Migration
+ def self.up
+ Deployment.where(:state => nil).each do |d|
+ d.update_attribute(:state, get_deployment_state(d))
+ end
+ end
+
+ def self.down
+ end
+
+ def self.get_deployment_state(deployment)
+ if deployment.instances.all? {|i| i.inactive?}
+ Deployment::STATE_STOPPED
+ elsif deployment.all_instances_running?
+ Deployment::STATE_RUNNING
+ elsif deployment.instances.all? { |i| [Instance::STATE_NEW,
+ Instance::STATE_PENDING, Instance::STATE_RUNNING].include?(i.state) }
+ Deployment::STATE_PENDING
+ elsif deployment.instances.all? { |i| [Instance::STATE_RUNNING,
+ Instance::STATE_SHUTTING_DOWN,
+ Instance::STATE_STOPPED].include?(i.state) }
+ Deployment::STATE_SHUTTING_DOWN
+ else
+ Deployemnt::STATE_INCOMPLETE
+ end
+ end
+end
--
1.7.7.6
11 years, 11 months
[PATCH conductor] Redmine #3210: Conductor should validate the provider, not just deltacloud-core instance.
by Jason Guiditta
https://www.aeolusproject.org/redmine/issues/3210
This patch adds a new method to the provider validation to verify
that the named provider is valid for a given deltacloud instance. In
addition, it moves this check out of the controller and down to the
model where it belongs on create action. It also adds errors to the
activerecord/en.yml, running tests on that value rather than a string.
---
src/app/controllers/providers_controller.rb | 17 ++++--------
src/app/models/provider.rb | 11 +++++++-
src/config/locales/activerecord/en.yml | 4 +++
src/features/provider.feature | 22 +++------------
src/features/step_definitions/provider_steps.rb | 31 ++++++++++++++++++++--
src/features/support/custom.rb | 4 +++
src/spec/factories/provider.rb | 1 -
src/spec/models/provider_spec.rb | 18 ++++++++-----
src/spec/spec_helper.rb | 4 +++
9 files changed, 72 insertions(+), 40 deletions(-)
diff --git a/src/app/controllers/providers_controller.rb b/src/app/controllers/providers_controller.rb
index 1335292..41cf5d5 100644
--- a/src/app/controllers/providers_controller.rb
+++ b/src/app/controllers/providers_controller.rb
@@ -104,18 +104,13 @@ class ProvidersController < ApplicationController
params[:provider][:provider_type_id] = provider_type.id
end
@provider = Provider.new(params[:provider])
- if !(a)provider.connect
- flash[:warning] = t"providers.flash.warning.connect_failed"
- render :action => "new"
+ if @provider.save
+ @provider.assign_owner_roles(current_user)
+ flash[:notice] = t"providers.flash.notice.added"
+ redirect_to edit_provider_path(@provider)
else
- if @provider.save
- @provider.assign_owner_roles(current_user)
- flash[:notice] = t"providers.flash.notice.added"
- redirect_to edit_provider_path(@provider)
- else
- flash[:warning] = t"providers.flash.error.not_added"
- render :action => "new"
- end
+ flash[:warning] = t"providers.flash.error.not_added"
+ render :action => "new"
end
end
diff --git a/src/app/models/provider.rb b/src/app/models/provider.rb
index 2033a04..fc3040e 100644
--- a/src/app/models/provider.rb
+++ b/src/app/models/provider.rb
@@ -251,7 +251,8 @@ class Provider < ActiveRecord::Base
def validate_provider
if !nil_or_empty(url)
- errors.add("url", "must be a valid provider url") unless valid_framework?
+ errors.add("url", I18n.t("activerecord.errors.provider.url")) unless valid_framework?
+ errors.add("deltacloud_provider", I18n.t("activerecord.errors.provider.deltacloud_provider")) unless valid_provider?
end
end
@@ -261,4 +262,12 @@ class Provider < ActiveRecord::Base
connect.nil? ? false : true
end
+ def valid_provider?
+ if !nil_or_empty(deltacloud_provider)
+ client = connect
+ return false if client.nil?
+ return false unless client.valid_provider? deltacloud_provider
+ end
+ true
+ end
end
diff --git a/src/config/locales/activerecord/en.yml b/src/config/locales/activerecord/en.yml
index 3ac086f..86b250f 100644
--- a/src/config/locales/activerecord/en.yml
+++ b/src/config/locales/activerecord/en.yml
@@ -343,3 +343,7 @@ en:
state: "State"
created_at: "Created At"
updated_at: "Updated At"
+ errors:
+ provider:
+ url: "Must be a valid provider uri"
+ deltacloud_provider: "Must be a valid provider identifier"
diff --git a/src/features/provider.feature b/src/features/provider.feature
index b1df22e..2ba7081 100644
--- a/src/features/provider.feature
+++ b/src/features/provider.feature
@@ -46,27 +46,15 @@ Feature: Manage Providers
And I should see "Provider URL"
Scenario: Create a new Provider
- Given I am on the providers page
- And there is not a provider named "testprovider"
- When I follow "create_new_provider"
- Then I should be on the new provider page
- When I fill in "provider[name]" with "testprovider"
- And I fill in "provider[url]" with "http://localhost:3002/api"
- And I select "Amazon EC2" from "provider_provider_type_id"
- And I press "save"
+ Given I am on the new provider page
+ And I attempt to add a valid provider
Then I should be on the testprovider's edit provider page
- And I should see "Provider added"
+ And I should see a confirmation message
And I should have a provider named "testprovider"
Scenario: Create a new Provider failure when using wrong url
- Given I am on the providers page
- And there is not a provider named "testprovider"
- When I follow "create_new_provider"
- Then I should be on the new provider page
- When I fill in "provider[name]" with "testprovider"
- And I fill in "provider[url]" with "http://localhost:3010/api"
- And I select "Amazon EC2" from "provider_provider_type_id"
- And I press "save"
+ Given I am on the new provider page
+ And I attempt to add a provider with an invalid url
Then I should be on the providers page
And I should see a warning message
diff --git a/src/features/step_definitions/provider_steps.rb b/src/features/step_definitions/provider_steps.rb
index fc25f87..605f49c 100644
--- a/src/features/step_definitions/provider_steps.rb
+++ b/src/features/step_definitions/provider_steps.rb
@@ -13,13 +13,30 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+def new_provider(port,bool)
+ destroy_provider("testprovider")
+ stub_framework(bool)
+ fill_in "provider[name]", :with => "testprovider"
+ fill_in "provider[url]", :with => "http://localhost:#{port}/api"
+ select("Amazon EC2", :from => "provider_provider_type_id")
+ click_button "save"
+end
+
+def destroy_provider(name)
+ provider = Provider.find_by_name(name)
+ if provider then provider.destroy end
+end
+
+def stub_framework(bool)
+ Provider.any_instance.stub(:valid_framework?).and_return(bool)
+end
+
Given /^there should not exist a provider named "([^\"]*)"$/ do |name|
Provider.find_by_name(name).should be_nil
end
Given /^there is not a provider named "([^"]*)"$/ do |name|
- provider = Provider.find_by_name(name)
- if provider then provider.destroy end
+ destroy_provider(name)
end
Given /^there is a provider named "([^\"]*)"$/ do |name|
@@ -27,7 +44,15 @@ Given /^there is a provider named "([^\"]*)"$/ do |name|
end
Given /^provider "([^"]*)" is not accessible$/ do |arg1|
- Provider.any_instance.stub(:valid_framework?).and_return(false)
+ stub_framework(false)
+end
+
+Given /^I attempt to add a valid provider$/ do
+ new_provider(3002,true)
+end
+
+Given /^I attempt to add a provider with an invalid url$/ do
+ new_provider(3010,false)
end
Then /^I should have a provider named "([^\"]*)"$/ do |name|
diff --git a/src/features/support/custom.rb b/src/features/support/custom.rb
index a02427c..e529073 100644
--- a/src/features/support/custom.rb
+++ b/src/features/support/custom.rb
@@ -23,6 +23,10 @@ Provider.class_eval do
true
end
+ def valid_provider?
+ true
+ end
+
def populate_realms
true
end
diff --git a/src/spec/factories/provider.rb b/src/spec/factories/provider.rb
index de6092d..a85b73b 100644
--- a/src/spec/factories/provider.rb
+++ b/src/spec/factories/provider.rb
@@ -33,7 +33,6 @@ FactoryGirl.define do
name 'mock2'
provider_type { ProviderType.find_by_deltacloud_driver("mock") }
url 'http://localhost:3002/api'
- deltacloud_provider 'mock'
after_create { |p| p.realms << FactoryGirl.create(:realm3, :provider => p) }
end
diff --git a/src/spec/models/provider_spec.rb b/src/spec/models/provider_spec.rb
index 11cf71e..4d07f9d 100644
--- a/src/spec/models/provider_spec.rb
+++ b/src/spec/models/provider_spec.rb
@@ -56,17 +56,21 @@ describe Provider do
end
end
- it "should be able to connect to the specified framework" do
- @provider.should be_valid
- @provider.connect.should_not be_nil
-
+ it "should set error if unable to connect to specified deltacloud instance" do
+ @provider.stub(:valid_provider?).and_return(true)
@provider.url = "http://invalid.provider/url"
@provider.stub(:connect).and_return(nil)
- deltacloud = @provider.connect
@provider.should have(1).error_on(:url)
- @provider.errors[:url].first.should eql("must be a valid provider url")
+ @provider.errors[:url].first.should eql(I18n.t("activerecord.errors.provider.url"))
+ @provider.should_not be_valid
+ end
+
+ it "should set error if unable to connect to specified deltacloud_provider" do
+ @provider.stub(:valid_provider?).and_return(false)
+ @provider.stub(:valid_framework?).and_return(true)
+ @provider.should have(1).error_on(:deltacloud_provider)
+ @provider.errors[:deltacloud_provider].first.should eql(I18n.t("activerecord.errors.provider.deltacloud_provider"))
@provider.should_not be_valid
- deltacloud.should be_nil
end
it "should require unique name" do
diff --git a/src/spec/spec_helper.rb b/src/spec/spec_helper.rb
index 09bb9f3..00cb1fd 100644
--- a/src/spec/spec_helper.rb
+++ b/src/spec/spec_helper.rb
@@ -81,6 +81,10 @@ RSpec.configure do |config|
# activate_authlogic
#end
+ config.before(:each) do
+ Provider.any_instance.stub(:valid_provider?).and_return(true)
+ Provider.any_instance.stub(:valid_famework?).and_return(true)
+ end
#config.after(:each, :type => :controller) do
# current_user_session.destroy
#end
--
1.7.7.6
11 years, 11 months
[PATCH aeolus-configure] Apache handles web fonts properly
by Matt Wagner
Our Apache config was invalid for /fonts, though the problem wasn't apparent because the current UI doesn't use them. As we work towards a unified UI, we're using a web font and it wasn't showing in RPM builds due to the invalid reference. This fixes the Alias, tells Apache to not proxy those requests to Rails, and also sets Cache-Control headers on the fonts. I had to add a MIME type for *.woff manually to appease Apache.
This is not associated with a BZ. There is no need to carry this in the existing product release; it's only useful going forward when we add web fonts.
11 years, 11 months
[PATCH conductor 1/3] permissions denormalization: redmine #3155 and #3156
by Scott Seago
---
src/app/controllers/deployables_controller.rb | 1 +
src/app/models/base_permission_object.rb | 16 ++++++
src/app/models/catalog.rb | 19 ++++++-
src/app/models/catalog_entry.rb | 11 ++++-
src/app/models/deployable.rb | 8 ++-
src/app/models/deployment.rb | 14 +++++-
.../{permission.rb => derived_permission.rb} | 43 ++++++---------
src/app/models/hardware_profile.rb | 4 ++
src/app/models/instance.rb | 10 +++-
src/app/models/permission.rb | 32 +++++++++++
src/app/models/permissioned_object.rb | 51 ++++++++++++++++--
src/app/models/pool.rb | 16 +++++-
src/app/models/pool_family.rb | 21 +++++++
src/app/models/privilege.rb | 8 ++--
src/app/models/provider.rb | 12 ++++
src/app/models/provider_account.rb | 10 +++-
src/app/models/role.rb | 8 +++
src/app/models/user.rb | 1 +
.../20120424151000_create_derived_permissions.rb | 37 +++++++++++++
src/spec/models/deployable_spec.rb | 57 ++++++++++++++++++++
src/spec/models/deployment_spec.rb | 4 +-
src/spec/models/instance_observer_spec.rb | 1 +
22 files changed, 340 insertions(+), 44 deletions(-)
copy src/app/models/{permission.rb => derived_permission.rb} (75%)
create mode 100644 src/db/migrate/20120424151000_create_derived_permissions.rb
diff --git a/src/app/controllers/deployables_controller.rb b/src/app/controllers/deployables_controller.rb
index 8967e79..911e337 100644
--- a/src/app/controllers/deployables_controller.rb
+++ b/src/app/controllers/deployables_controller.rb
@@ -191,6 +191,7 @@ class DeployablesController < ApplicationController
end
end
+ # the name here is confusing; we may want to rename to multi_remove at some point
def multi_destroy
deleted = []
not_deleted = []
diff --git a/src/app/models/base_permission_object.rb b/src/app/models/base_permission_object.rb
index 8133a7f..ce25861 100644
--- a/src/app/models/base_permission_object.rb
+++ b/src/app/models/base_permission_object.rb
@@ -31,6 +31,9 @@ class BasePermissionObject < ActiveRecord::Base
has_many :permissions, :as => :permission_object, :dependent => :destroy,
:include => [:role],
:order => "permissions.id ASC"
+ has_many :derived_permissions, :as => :permission_object, :dependent => :destroy,
+ :include => [:role],
+ :order => "derived_permissions.id ASC"
validates_presence_of :name
validates_uniqueness_of :name
@@ -42,4 +45,17 @@ class BasePermissionObject < ActiveRecord::Base
base_permission = self.create!(:name => GENERAL_PERMISSION_SCOPE) unless base_permission
base_permission
end
+
+ def derived_subtree(role = nil)
+ subtree = super(role)
+ [Catalog, Deployable, PoolFamily, Pool, Deployment,
+ Instance, Provider, ProviderAccount, HardwareProfile].each do |obj_type|
+ subtree += obj_type.all if (role.nil? or role.privilege_target_match(obj_type))
+ end
+ subtree
+ end
+ def self.additional_privilege_target_types
+ [HardwareProfile, Catalog, Deployable, PoolFamily, Pool,
+ Deployment, Instance, Provider, ProviderAccount]
+ end
end
diff --git a/src/app/models/catalog.rb b/src/app/models/catalog.rb
index 1f3ac9a..5ab51c4 100644
--- a/src/app/models/catalog.rb
+++ b/src/app/models/catalog.rb
@@ -38,18 +38,30 @@ class Catalog < ActiveRecord::Base
has_many :permissions, :as => :permission_object, :dependent => :destroy,
:include => [:role],
:order => "permissions.id ASC"
+ has_many :derived_permissions, :as => :permission_object, :dependent => :destroy,
+ :include => [:role],
+ :order => "derived_permissions.id ASC"
before_destroy :destroy_deployables_related_only_to_self
before_create :set_pool_family
+ after_update :update_deployable_permissions
validates_presence_of :pool
validates_presence_of :name
validates_uniqueness_of :name
validates_length_of :name, :maximum => 1024
- def object_list
+ def perm_ancestors
super + [pool, pool_family]
end
+ def derived_subtree(role = nil)
+ subtree = super(role)
+ subtree += deployables if (role.nil? or role.privilege_target_match(Deployable))
+ subtree
+ end
+ def self.additional_privilege_target_types
+ [Deployable]
+ end
class << self
alias orig_list_for_user_include list_for_user_include
alias orig_list_for_user_conditions list_for_user_conditions
@@ -80,6 +92,11 @@ class Catalog < ActiveRecord::Base
self[:pool_family_id] = pool.pool_family_id
end
+ def update_deployable_permissions
+ update_derived_permissions_for_ancestors
+ deployables.each {|d| d.update_derived_permissions_for_ancestors}
+ end
+
private
def self.apply_search_filter(search)
diff --git a/src/app/models/catalog_entry.rb b/src/app/models/catalog_entry.rb
index 857d013..03461d2 100644
--- a/src/app/models/catalog_entry.rb
+++ b/src/app/models/catalog_entry.rb
@@ -36,9 +36,18 @@ class CatalogEntry < ActiveRecord::Base
validates_uniqueness_of :catalog_id, :scope => [:deployable_id]
after_destroy :destroy_deployable_if_last
+ after_create :update_deployable_permissions
+
+ def update_deployable_permissions
+ deployable.update_derived_permissions_for_ancestors
+ end
def destroy_deployable_if_last
- deployable.destroy if deployable.catalog_entries.blank?
+ if deployable.catalog_entries.blank?
+ deployable.destroy
+ else
+ deployable.update_derived_permissions_for_ancestors
+ end
end
# This probably goes away once we separate catalog entry creation from deployables
diff --git a/src/app/models/deployable.rb b/src/app/models/deployable.rb
index 5f4157e..02c53ff 100644
--- a/src/app/models/deployable.rb
+++ b/src/app/models/deployable.rb
@@ -34,6 +34,10 @@ class Deployable < ActiveRecord::Base
has_many :permissions, :as => :permission_object, :dependent => :destroy,
:include => [:role],
:order => "permissions.id ASC"
+ has_many :derived_permissions, :as => :permission_object, :dependent => :destroy,
+ :include => [:role],
+ :order => "derived_permissions.id ASC"
+
has_many :catalog_entries, :dependent => :destroy
has_many :catalogs, :through => :catalog_entries
belongs_to :pool_family
@@ -49,8 +53,8 @@ class Deployable < ActiveRecord::Base
PRESET_FILTERS_OPTIONS = []
- def object_list
- super + catalogs + catalogs.collect{|c| c.pool} + [pool_family]
+ def perm_ancestors
+ super + catalogs + catalogs.collect{|c| c.pool}.uniq + [pool_family]
end
class << self
alias orig_list_for_user_include list_for_user_include
diff --git a/src/app/models/deployment.rb b/src/app/models/deployment.rb
index 4ad2082..559f027 100644
--- a/src/app/models/deployment.rb
+++ b/src/app/models/deployment.rb
@@ -52,6 +52,10 @@ class Deployment < ActiveRecord::Base
has_many :permissions, :as => :permission_object, :dependent => :destroy,
:include => [:role],
:order => "permissions.id ASC"
+ has_many :derived_permissions, :as => :permission_object, :dependent => :destroy,
+ :include => [:role],
+ :order => "derived_permissions.id ASC"
+
belongs_to :owner, :class_name => "User", :foreign_key => "owner_id"
has_many :events, :as => :source, :dependent => :destroy
@@ -118,9 +122,17 @@ class Deployment < ActiveRecord::Base
errors.add(:pool, I18n.t('pools.errors.providers_disabled')) if pool and pool.pool_family.all_providers_disabled?
end
- def object_list
+ def perm_ancestors
super + [pool, pool_family]
end
+ def derived_subtree(role = nil)
+ subtree = super(role)
+ subtree += instances if (role.nil? or role.privilege_target_match(Instance))
+ subtree
+ end
+ def self.additional_privilege_target_types
+ [Instance]
+ end
class << self
alias orig_list_for_user_include list_for_user_include
alias orig_list_for_user_conditions list_for_user_conditions
diff --git a/src/app/models/permission.rb b/src/app/models/derived_permission.rb
similarity index 75%
copy from src/app/models/permission.rb
copy to src/app/models/derived_permission.rb
index ccda5f7..06e7e8e 100644
--- a/src/app/models/permission.rb
+++ b/src/app/models/derived_permission.rb
@@ -14,32 +14,12 @@
# limitations under the License.
#
-# == Schema Information
-# Schema version: 20110207110131
-#
-# Table name: permissions
-#
-# id :integer not null, primary key
-# role_id :integer not null
-# user_id :integer not null
-# permission_object_id :integer
-# permission_object_type :string(255)
-# lock_version :integer default(0)
-# created_at :datetime
-# updated_at :datetime
-#
-
-class Permission < ActiveRecord::Base
- belongs_to :role
- belongs_to :user
-
- validates_presence_of :role_id
-
- validates_presence_of :user_id
- validates_uniqueness_of :user_id, :scope => [:permission_object_id,
- :permission_object_type,
- :role_id]
+class DerivedPermission < ActiveRecord::Base
+ # the source permission for the denormalized object
+ belongs_to :permission
+ validates_presence_of :permission_id
+ # this is the object used for permission checks
belongs_to :permission_object, :polymorphic => true
# type-specific associations
belongs_to :pool_family, :class_name => "PoolFamily",
@@ -58,7 +38,20 @@ class Permission < ActiveRecord::Base
:foreign_key => "permission_object_id"
belongs_to :provider_account, :class_name => "ProviderAccount",
:foreign_key => "permission_object_id"
+ belongs_to :hardware_profile, :class_name => "hardwareProfile",
+ :foreign_key => "permission_object_id"
belongs_to :base_permission_object, :class_name => "BasePermissionObject",
:foreign_key => "permission_object_id"
+ # role is copied from source permission
+ belongs_to :role
+ validates_presence_of :role_id
+
+ # user is copied from source permission
+ belongs_to :user
+ validates_presence_of :user_id
+
+ validates_uniqueness_of :permission_id, :scope => [:permission_object_id,
+ :permission_object_type]
+
end
diff --git a/src/app/models/hardware_profile.rb b/src/app/models/hardware_profile.rb
index 9c325c1..2099214 100644
--- a/src/app/models/hardware_profile.rb
+++ b/src/app/models/hardware_profile.rb
@@ -41,6 +41,10 @@ class HardwareProfile < ActiveRecord::Base
end
include PermissionedObject
has_many :permissions, :as => :permission_object, :dependent => :destroy
+ has_many :derived_permissions, :as => :permission_object, :dependent => :destroy,
+ :include => [:role],
+ :order => "derived_permissions.id ASC"
+
has_many :instances
scope :frontend, :conditions => { :provider_id => nil }
has_many :provider_instances, :class_name => "Instance",
diff --git a/src/app/models/instance.rb b/src/app/models/instance.rb
index 062372e..84f1224 100644
--- a/src/app/models/instance.rb
+++ b/src/app/models/instance.rb
@@ -80,6 +80,10 @@ class Instance < ActiveRecord::Base
has_many :permissions, :as => :permission_object, :dependent => :destroy,
:include => [:role],
:order => "permissions.id ASC"
+ has_many :derived_permissions, :as => :permission_object, :dependent => :destroy,
+ :include => [:role],
+ :order => "derived_permissions.id ASC"
+
has_many :events, :as => :source, :dependent => :destroy
has_many :instance_parameters, :dependent => :destroy
has_many :tasks, :as =>:task_target, :dependent => :destroy
@@ -141,8 +145,10 @@ class Instance < ActiveRecord::Base
# changed if called from another Aeolus component, so attr_protected isn't quite what we want:
USER_MUTABLE_ATTRS = ['name']
- def object_list
- super + [deployment, pool, pool_family]
+ def perm_ancestors
+ ancestors = super
+ ancestors << deployment unless deployment.nil?
+ ancestors += [pool, pool_family]
end
class << self
alias orig_list_for_user_include list_for_user_include
diff --git a/src/app/models/permission.rb b/src/app/models/permission.rb
index ccda5f7..89b2268 100644
--- a/src/app/models/permission.rb
+++ b/src/app/models/permission.rb
@@ -58,7 +58,39 @@ class Permission < ActiveRecord::Base
:foreign_key => "permission_object_id"
belongs_to :provider_account, :class_name => "ProviderAccount",
:foreign_key => "permission_object_id"
+ belongs_to :hardware_profile, :class_name => "hardwareProfile",
+ :foreign_key => "permission_object_id"
belongs_to :base_permission_object, :class_name => "BasePermissionObject",
:foreign_key => "permission_object_id"
+ has_many :derived_permissions, :dependent => :destroy
+
+ after_save :update_derived_permissions
+
+ def update_derived_permissions
+ new_derived_permission_objects = permission_object.derived_subtree(role)
+ old_derived_permissions = derived_permissions
+ old_derived_permissions.each do |derived_perm|
+ if new_derived_permission_objects.delete(derived_perm.permission_object)
+ # object is in both old and new list -- update as necessary
+ derived_perm.role = role
+ derived_perm.user_id = user_id
+ derived_perm.save!
+ else
+ # object is in old but not new list -- remove it
+ derived_perm.destroy
+ end
+ end
+ new_derived_permission_objects.each do |perm_obj|
+ unless DerivedPermission.where(:permission_id => id,
+ :permission_object_id => perm_obj.id,
+ :permission_object_type => perm_obj.class.name).any?
+ derived_perm = DerivedPermission.new(:user_id => user_id,
+ :role_id => role_id,
+ :permission_object => perm_obj,
+ :permission => self)
+ derived_perm.save!
+ end
+ end
+ end
end
diff --git a/src/app/models/permissioned_object.rb b/src/app/models/permissioned_object.rb
index c534261..3f083ea 100644
--- a/src/app/models/permissioned_object.rb
+++ b/src/app/models/permissioned_object.rb
@@ -19,7 +19,7 @@ module PermissionedObject
def has_privilege(user, action, target_type=nil)
return false if user.nil? or action.nil?
target_type = self.class.default_privilege_target_type if target_type.nil?
- object_list.each do |obj|
+ perm_ancestors.each do |obj|
return true if obj and obj.permissions.find(:first,
:include => [:role => :privileges],
:conditions =>
@@ -35,10 +35,39 @@ module PermissionedObject
# Returns the list of objects to check for permissions on -- by default
# this object plus the Base permission object
- def object_list
+ # At the moment, the retuned list is not necessarily ordered
+ # FIXME: remove self once has_privilege stops using this method
+ def perm_ancestors
[self, BasePermissionObject.general_permission_scope]
end
-
+ # Returns the list of objects to generate derived permissions for
+ # -- by default just this object
+ def derived_subtree(role = nil)
+ [self]
+ end
+ # on obj creation, set inherited permissions for new object
+ def update_derived_permissions_for_ancestors
+ # for create hook this should normally be empty
+ old_derived_permissions = Hash[derived_permissions.map{|p| [p.permission.id,p]}]
+ perm_ancestors.each do |perm_obj|
+ perm_obj.permissions.each do |permission|
+ if permission.role.privilege_target_match(self.class.default_privilege_target_type)
+ unless old_derived_permissions.delete(permission.id)
+ derived_permissions.create(:user_id => permission.user_id,
+ :role_id => permission.role_id,
+ :permission => permission)
+ end
+ end
+ end
+ end
+ # anything remaining in old_derived_permissions should be removed,
+ # as would be expected if this hook is triggered by removing a
+ # catalog entry for a deployable
+ old_derived_permissions.each do |id, derived_perm|
+ derived_perm.destroy
+ end
+ #reload
+ end
# assign owner role so that the creating user has permissions on the object
# Any roles defined on default_privilege_target_type with assign_to_owner==true
# will be assigned to the passed-in user on this object
@@ -49,14 +78,28 @@ module PermissionedObject
roles.each do |role|
Permission.create!(:role => role, :user => user, :permission_object => self)
end
+ self.reload
end
# Any methods here will be able to use the context of the
# ActiveRecord model the module is included in.
def self.included(base)
base.class_eval do
+ after_create :update_derived_permissions_for_ancestors
+
+ # Returns the list of privilege target types that are relevant for
+ # permission checking purposes. This is used in setting derived
+ # permissions -- there's no need to create denormalized permissions
+ # for a role which only grants Provider privileges on a Pool
+ # object. By default, this is just the current object's type
+ def self.active_privilege_target_types
+ [self.default_privilege_target_type] + self.additional_privilege_target_types
+ end
+ def self.additional_privilege_target_types
+ []
+ end
def self.default_privilege_target_type
- self.name.constantize
+ self
end
def self.list_for_user_include
[:permissions]
diff --git a/src/app/models/pool.rb b/src/app/models/pool.rb
index 4604bd2..9110481 100644
--- a/src/app/models/pool.rb
+++ b/src/app/models/pool.rb
@@ -60,6 +60,9 @@ class Pool < ActiveRecord::Base
has_many :permissions, :as => :permission_object, :dependent => :destroy,
:include => [:role],
:order => "permissions.id ASC"
+ has_many :derived_permissions, :as => :permission_object, :dependent => :destroy,
+ :include => [:role],
+ :order => "derived_permissions.id ASC"
has_many :deployments, :dependent => :destroy
@@ -148,9 +151,20 @@ class Pool < ActiveRecord::Base
{:title => "pools.preset_filters.with_stopped_instances", :id => "with_stopped_instances", :query => includes(:deployments => :instances).where("instances.state" => "stopped")}
]
- def object_list
+ def perm_ancestors
super + [pool_family]
end
+ def derived_subtree(role = nil)
+ subtree = super(role)
+ subtree += deployments if (role.nil? or role.privilege_target_match(Deployment))
+ subtree += instances if (role.nil? or role.privilege_target_match(Instance))
+ subtree += catalogs if (role.nil? or role.privilege_target_match(Deployable))
+ subtree += catalogs.collect {|c| c.deployables}.flatten.uniq if (role.nil? or role.privilege_target_match(Deployable))
+ subtree
+ end
+ def self.additional_privilege_target_types
+ [Deployment, Instance, Catalog, Quota]
+ end
class << self
alias orig_list_for_user_include list_for_user_include
alias orig_list_for_user_conditions list_for_user_conditions
diff --git a/src/app/models/pool_family.rb b/src/app/models/pool_family.rb
index dd474a9..60fb0cb 100644
--- a/src/app/models/pool_family.rb
+++ b/src/app/models/pool_family.rb
@@ -43,6 +43,14 @@ class PoolFamily < ActiveRecord::Base
accepts_nested_attributes_for :quota
has_and_belongs_to_many :provider_accounts, :uniq => true, :order => "provider_accounts.priority asc"
has_many :permissions, :as => :permission_object, :dependent => :destroy
+ has_many :derived_permissions, :as => :permission_object, :dependent => :destroy,
+ :include => [:role],
+ :order => "derived_permissions.id ASC"
+
+ has_many :catalogs
+ has_many :deployables
+ has_many :instances
+ has_many :deployments
validates_length_of :name, :maximum => 255
validates_format_of :name, :with => /^[\w -]*$/n, :message => "must only contain: numbers, letters, spaces, '_' and '-'"
@@ -61,6 +69,19 @@ class PoolFamily < ActiveRecord::Base
MetadataObject.set(DEFAULT_POOL_FAMILY_KEY, self)
end
+ def derived_subtree(role = nil)
+ subtree = super(role)
+ subtree += pools if (role.nil? or role.privilege_target_match(Pool))
+ subtree += deployments if (role.nil? or role.privilege_target_match(Deployment))
+ subtree += instances if (role.nil? or role.privilege_target_match(Instance))
+ subtree += catalogs if (role.nil? or role.privilege_target_match(Deployable))
+ subtree += deployables if (role.nil? or role.privilege_target_match(Deployable))
+ subtree
+ end
+ def self.additional_privilege_target_types
+ [Pool, Quota]
+ end
+
def destroyable?
# A PoolFamily is destroyable if its pools are destroyable and it is not the default PoolFamily
pools.all? {|p| p.destroyable? } && self != PoolFamily.default
diff --git a/src/app/models/privilege.rb b/src/app/models/privilege.rb
index ae1f038..1d857db 100644
--- a/src/app/models/privilege.rb
+++ b/src/app/models/privilege.rb
@@ -51,14 +51,14 @@ class Privilege < ActiveRecord::Base
PERM_SET, PERM_VIEW]
TYPES = { BasePermissionObject => [MODIFY, PERM_SET, PERM_VIEW],
Pool => ACTIONS - [USE],
- PoolFamily => ACTIONS - [USE],
+ PoolFamily => ACTIONS,
Instance => ACTIONS,
Deployment => ACTIONS,
- CatalogEntry => ACTIONS,
+ Deployable => ACTIONS,
Quota => [VIEW, MODIFY],
- HardwareProfile => ACTIONS - [USE, VIEW],
+ HardwareProfile => ACTIONS - [USE],
Realm => ACTIONS - [VIEW],
- Provider => ACTIONS - [USE],
+ Provider => ACTIONS,
ProviderAccount => ACTIONS,
User => [ CREATE, MODIFY, VIEW] }
diff --git a/src/app/models/provider.rb b/src/app/models/provider.rb
index 2033a04..e1fb385 100644
--- a/src/app/models/provider.rb
+++ b/src/app/models/provider.rb
@@ -56,9 +56,21 @@ class Provider < ActiveRecord::Base
has_many :permissions, :as => :permission_object, :dependent => :destroy,
:include => [:role],
:order => "permissions.id ASC"
+ has_many :derived_permissions, :as => :permission_object, :dependent => :destroy,
+ :include => [:role],
+ :order => "derived_permissions.id ASC"
before_destroy :destroyable?
+ def derived_subtree(role = nil)
+ subtree = super(role)
+ subtree += provider_accounts if (role.nil? or role.privilege_target_match(ProviderAccount))
+ subtree
+ end
+ def self.additional_privilege_target_types
+ [ProviderAccount]
+ end
+
scope :enabled, where("enabled = ?", true)
def encoded_url_with_driver_and_provider
diff --git a/src/app/models/provider_account.rb b/src/app/models/provider_account.rb
index 232928e..0ebc848 100644
--- a/src/app/models/provider_account.rb
+++ b/src/app/models/provider_account.rb
@@ -48,6 +48,9 @@ class ProviderAccount < ActiveRecord::Base
has_many :permissions, :as => :permission_object, :dependent => :destroy,
:include => [:role],
:order => "permissions.id ASC"
+ has_many :derived_permissions, :as => :permission_object, :dependent => :destroy,
+ :include => [:role],
+ :order => "derived_permissions.id ASC"
# validation of credentials is done in provider_account validation, :validate => false prevents nested_attributes from validation
has_many :credentials, :dependent => :destroy, :validate => false
@@ -106,8 +109,11 @@ class ProviderAccount < ActiveRecord::Base
return true
end
- def object_list
- super << provider
+ def perm_ancestors
+ super + [provider]
+ end
+ def self.additional_privilege_target_types
+ [Quota]
end
class << self
alias orig_list_for_user_include list_for_user_include
diff --git a/src/app/models/role.rb b/src/app/models/role.rb
index 98f0a5a..dcf3178 100644
--- a/src/app/models/role.rb
+++ b/src/app/models/role.rb
@@ -30,6 +30,7 @@
class Role < ActiveRecord::Base
has_many :permissions, :dependent => :destroy
+ has_many :derived_permissions, :dependent => :destroy
has_many :privileges, :dependent => :destroy
validates_presence_of :scope
@@ -39,4 +40,11 @@ class Role < ActiveRecord::Base
validates_associated :privileges
validates_length_of :name, :maximum => 255
+
+ def privilege_target_types
+ privileges.collect {|x| Kernel.const_get(x.target_type)}.uniq
+ end
+ def privilege_target_match(obj_type)
+ (privilege_target_types & obj_type.active_privilege_target_types).any?
+ end
end
diff --git a/src/app/models/user.rb b/src/app/models/user.rb
index c2822ea..66565a7 100644
--- a/src/app/models/user.rb
+++ b/src/app/models/user.rb
@@ -59,6 +59,7 @@ class User < ActiveRecord::Base
attr_accessor :ignore_password
has_many :permissions, :dependent => :destroy
+ has_many :derived_permissions, :dependent => :destroy
has_many :owned_instances, :class_name => "Instance", :foreign_key => "owner_id"
has_many :deployments, :foreign_key => "owner_id"
has_many :view_states
diff --git a/src/db/migrate/20120424151000_create_derived_permissions.rb b/src/db/migrate/20120424151000_create_derived_permissions.rb
new file mode 100644
index 0000000..318d320
--- /dev/null
+++ b/src/db/migrate/20120424151000_create_derived_permissions.rb
@@ -0,0 +1,37 @@
+#
+# Copyright 2012 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+class CreateDerivedPermissions < ActiveRecord::Migration
+ def self.up
+ create_table :derived_permissions do |t|
+ t.integer :permission_id, :null => false
+ t.integer :role_id, :null => false
+ t.integer :user_id, :null => false
+ t.integer :permission_object_id
+ t.string :permission_object_type
+ t.integer :lock_version, :default => 0
+
+ t.timestamps
+ end
+ # create derived permissions for existing records
+ Permission.all.each do |permission|
+ permission.update_derived_permissions
+ end
+ end
+
+ def self.down
+ drop_table :derived_permissions
+ end
+end
diff --git a/src/spec/models/deployable_spec.rb b/src/spec/models/deployable_spec.rb
index 6b32968..a98eed7 100644
--- a/src/spec/models/deployable_spec.rb
+++ b/src/spec/models/deployable_spec.rb
@@ -71,4 +71,61 @@ describe Deployable do
deployable.xml = ''
deployable.should_not be_valid
end
+
+ it "should manage permissions on catalog changes" do
+ pool1 = FactoryGirl.create :pool
+ pool2 = FactoryGirl.create :pool
+ catalog1 = FactoryGirl.create :catalog #, :pool => :pool1
+ catalog2 = FactoryGirl.create :catalog
+ catalog1.pool.should_not == catalog2.pool
+ admin = FactoryGirl.create :admin_user
+ pool1_perm = Permission.create(:user => admin,
+ :role => Role.first(:conditions =>
+ ['name = ?', 'pool.admin']),
+ :permission_object => catalog1.pool)
+ pool2_perm = Permission.create(:user => admin,
+ :role => Role.first(:conditions =>
+ ['name = ?', 'pool.deployable.admin']),
+ :permission_object => catalog2.pool)
+ deployable = FactoryGirl.create :deployable, :catalogs => [catalog1]
+ catalog1.reload
+ catalog2.reload
+ catalog1.pool.permissions.should == [pool1_perm]
+ catalog2.pool.permissions.should == [pool2_perm]
+
+ catalog1.derived_permissions.collect {|p|
+ p.role.name}.should == ["pool.admin"]
+ catalog2.derived_permissions.collect {|p|
+ p.role.name}.should == ["pool.deployable.admin"]
+ deployable.derived_permissions.collect {|p|
+ p.role.name}.include?("pool.admin").should be_true
+ deployable.derived_permissions.collect {|p|
+ p.role.name}.include?("pool.deployable.admin").should be_false
+ deployable.catalogs.should == [catalog1]
+
+ deployable.catalogs << catalog2
+ deployable.reload
+ deployable.catalogs.should == [catalog1, catalog2]
+ deployable.derived_permissions.collect {|p|
+ p.role.name}.include?("pool.admin").should be_true
+ deployable.derived_permissions.collect {|p|
+ p.role.name}.include?("pool.deployable.admin").should be_true
+
+ deployable.catalog_entries.where(:catalog_id => catalog1.id).first.destroy
+ deployable.reload
+ deployable.catalogs.should == [catalog2]
+ deployable.derived_permissions.collect {|p|
+ p.role.name}.include?("pool.admin").should be_false
+ deployable.derived_permissions.collect {|p|
+ p.role.name}.include?("pool.deployable.admin").should be_true
+
+ catalog2.pool = catalog1.pool
+ catalog2.save
+ deployable.reload
+ deployable.catalogs.should == [catalog2]
+ deployable.derived_permissions.collect {|p|
+ p.role.name}.include?("pool.admin").should be_true
+ deployable.derived_permissions.collect {|p|
+ p.role.name}.include?("pool.deployable.admin").should be_false
+ end
end
diff --git a/src/spec/models/deployment_spec.rb b/src/spec/models/deployment_spec.rb
index f382eda..7706345 100644
--- a/src/spec/models/deployment_spec.rb
+++ b/src/spec/models/deployment_spec.rb
@@ -96,7 +96,7 @@ describe Deployment do
@deployment.save!
inst1 = Factory.create :mock_running_instance, :deployment_id => @deployment.id
inst2 = Factory.create :mock_running_instance, :deployment_id => @deployment.id
-
+ @deployment.reload
@deployment.should_not be_destroyable
@deployment.destroy.should == false
@@ -117,6 +117,7 @@ describe Deployment do
inst2.state = Instance::STATE_STOPPED
inst2.save!
inst3 = Factory.create :mock_running_instance, :deployment_id => @deployment.id
+ @deployment.reload
Taskomatic.stub!(:stop_instance).and_return(nil)
@deployment.stop_instances_and_destroy!
inst1.tasks.last.action.should == 'stop'
@@ -297,6 +298,7 @@ describe Deployment do
@deployment.save!
inst1 = Factory.create :mock_running_instance, :deployment_id => @deployment.id
inst2 = Factory.create :mock_running_instance, :deployment_id => @deployment.id
+ @deployment.reload
@deployment.stop_instances_and_destroy!
diff --git a/src/spec/models/instance_observer_spec.rb b/src/spec/models/instance_observer_spec.rb
index d014077..9cc70be 100644
--- a/src/spec/models/instance_observer_spec.rb
+++ b/src/spec/models/instance_observer_spec.rb
@@ -209,6 +209,7 @@ describe InstanceObserver do
it "should destroy the instance key when the instance is stopped" do
@instance = FactoryGirl.create :mock_running_instance
+ @instance_key = FactoryGirl.create :mock_instance_key, :instance => @instance
@instance.instance_key.should_not be_nil
@instance.state = Instance::STATE_STOPPED
@instance.save!
--
1.7.6.5
11 years, 11 months
[PATCH aeolus-conductor] Fixed build added changes to scss files
by Martyn Taylor
From: Martyn Taylor <mtaylor(a)redhat.com>
---
aeolus-conductor.spec.in | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/aeolus-conductor.spec.in b/aeolus-conductor.spec.in
index 3008b0c..d35597a 100644
--- a/aeolus-conductor.spec.in
+++ b/aeolus-conductor.spec.in
@@ -220,7 +220,7 @@ done
# precompile stylesheets
%{__mkdir} %{buildroot}%{app_root}/public/stylesheets/compiled
-for stylesheet in custom layout login header; do
+for stylesheet in layout login; do
sass --style compact ./src/app/stylesheets/$stylesheet.scss %{buildroot}%{app_root}/public/stylesheets/compiled/$stylesheet.css
done
@@ -366,6 +366,9 @@ fi
%files -n aeolus-all
%changelog
+* Thu May 03 2012 Martyn Taylor <mtaylor(a)redhat.com> - 0.9.0-1
+- Updated compilation of new sass files
+
* Mon Jan 09 2012 Steve Linabery <slinaber(a)redhat.com> - 0.8.0-2
- 18ba534 Merge branch 'master' of github.com:aeolusproject/conductor
- 0a37767 API - Added template checking when creating an image
--
1.7.6.4
11 years, 11 months
Added deployment state
by Jan Provazník
Hi,
this patchset adds deployment state attribute. This attribute will be used for
tracking deployment's state which will be needed especially for doing rollback
when launching a deployment. It also replaces 'status' method which computed deployment's
state from states of all instances.
This patchset introduces state transitions (IOW now it's not possible to change
deployment's state from 'running' to 'pending' or from 'stopped' to 'shutting down').
deployment's state is now mostly changed on a user's action (e.g. a user clicks stop
button -> state is changed to 'shutting down'), though some transitions are done
automatically ('pending' -> 'running', 'shutting down' -> 'stopped', all rollback
state transitions will be automatic too).
Drawback of setting state when an action is performed is that deployment's state may not describe
real state of all instances properly, for example if a deployment is running and all instances are
suddenly changed to 'stopped' (from outside of conductor), then deployment's state will be 'incomplete'
until a user stops/deletes the deployment from conductor.
Which reminds me I've added another deployment state: 'incomplete', this state is used when a deployment
is running and then some (or all) instances unexpectedly change state (wiki page Robust_instance_launching
is updated too).
11 years, 11 months
[PATCH configure] RM 3181 - delayed_job support - rev 2
by Richard Su
Start and stop conductor-delayed_job service with aeolus-configure
and aeolus-cleanup.
rev 2 - added conductor-delayed_job as dependency to ensure service has
stopped before dropping conductor database
---
recipes/aeolus/manifests/conductor.pp | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/recipes/aeolus/manifests/conductor.pp b/recipes/aeolus/manifests/conductor.pp
index f06ae16..786c658 100644
--- a/recipes/aeolus/manifests/conductor.pp
+++ b/recipes/aeolus/manifests/conductor.pp
@@ -62,7 +62,8 @@ class aeolus::conductor inherits aeolus {
}
service { ['aeolus-conductor',
- 'conductor-dbomatic' ]:
+ 'conductor-dbomatic',
+ 'conductor-delayed_job']:
ensure => 'running',
enable => true,
hasstatus => true,
@@ -158,7 +159,8 @@ class aeolus::conductor::disabled {
require => Service['aeolus-conductor',
'conductor-dbomatic'] }
service { ['aeolus-conductor',
- 'conductor-dbomatic']:
+ 'conductor-dbomatic',
+ 'conductor-delayed_job']:
ensure => 'stopped',
enable => false,
hasstatus => true }
@@ -169,7 +171,8 @@ class aeolus::conductor::disabled {
cwd => "/usr/share/aeolus-conductor",
rails_env => "production",
require => Service["aeolus-conductor",
- "conductor-dbomatic"]}
+ "conductor-dbomatic",
+ "conductor-delayed_job"]}
postgres::user{"aeolus":
ensure => 'dropped',
require => Rails::Drop::Db["drop_aeolus_database"]}
--
1.7.7.6
11 years, 11 months