This includes models and model rspec tests for Assemblies, Deployments, and Deployables. Associated role/privilege additions needed for these types are also included.
Signed-off-by: Scott Seago sseago@redhat.com --- src/app/models/assembly.rb | 67 ++++++++++++++++ src/app/models/deployable.rb | 61 ++++++++++++++ src/app/models/deployment.rb | 84 ++++++++++++++++++++ src/app/models/image_warehouse_object.rb | 42 ++++++++++ src/app/models/instance.rb | 24 +++++- src/app/models/permission.rb | 6 ++ src/app/models/permissioned_object.rb | 2 +- src/app/models/privilege.rb | 9 ++ src/app/models/template.rb | 23 +----- src/db/migrate/20110207100700_create_assemblies.rb | 24 ++++++ .../migrate/20110207100800_update_deployables.rb | 24 ++++++ .../migrate/20110207100900_create_deployments.rb | 17 ++++ src/db/migrate/20110207101000_update_instances.rb | 21 +++++ src/db/migrate/20110207101100_deployment_roles.rb | 65 +++++++++++++++ src/db/seeds.rb | 17 +++- src/spec/factories/assembly.rb | 5 + src/spec/factories/deployable.rb | 4 + src/spec/factories/deployment.rb | 6 ++ src/spec/models/assembly_spec.rb | 25 ++++++ src/spec/models/deployable_spec.rb | 25 ++++++ src/spec/models/deployment_spec.rb | 59 ++++++++++++++ src/spec/models/instance_spec.rb | 13 +++- 22 files changed, 591 insertions(+), 32 deletions(-) create mode 100644 src/app/models/assembly.rb create mode 100644 src/app/models/deployment.rb create mode 100644 src/app/models/image_warehouse_object.rb create mode 100644 src/db/migrate/20110207100700_create_assemblies.rb create mode 100644 src/db/migrate/20110207100800_update_deployables.rb create mode 100644 src/db/migrate/20110207100900_create_deployments.rb create mode 100644 src/db/migrate/20110207101000_update_instances.rb create mode 100644 src/db/migrate/20110207101100_deployment_roles.rb create mode 100644 src/spec/factories/assembly.rb create mode 100644 src/spec/factories/deployable.rb create mode 100644 src/spec/factories/deployment.rb create mode 100644 src/spec/models/assembly_spec.rb create mode 100644 src/spec/models/deployable_spec.rb create mode 100644 src/spec/models/deployment_spec.rb
diff --git a/src/app/models/assembly.rb b/src/app/models/assembly.rb new file mode 100644 index 0000000..5a47525 --- /dev/null +++ b/src/app/models/assembly.rb @@ -0,0 +1,67 @@ +# +# Copyright (C) 2011 Red Hat, Inc. +# Written by Scott Seago sseago@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. + +require 'sunspot_rails' +class Assembly < ActiveRecord::Base + include PermissionedObject + include ImageWarehouseObject + searchable do + text :name, :as => :code_substring + text :architecture, :as => :code_substring + text :summary, :as => :code_substring + end + + has_and_belongs_to_many :templates + has_and_belongs_to_many :deployables + has_many :instances + + has_many :permissions, :as => :permission_object, :dependent => :destroy, + :include => [:role], + :order => "permissions.id ASC" + + before_validation :generate_uuid + before_save :update_xml + + has_many :permissions, :as => :permission_object, :dependent => :destroy, + :include => [:role], + :order => "permissions.id ASC" + + validates_presence_of :uuid + validates_uniqueness_of :uuid + validates_presence_of :name + validates_uniqueness_of :name + validates_length_of :name, :maximum => 255 + validates_presence_of :architecture + + def self.default_privilege_target_type + Template + end + + def update_xml + xml.name = self.name + xml.description = self.summary + xml.architecture = self.architecture + write_attribute(:xml, xml.to_xml) + end + + def self.find_or_create(id) + id ? Assembly.find(id) : Assembly.new + end + +end diff --git a/src/app/models/deployable.rb b/src/app/models/deployable.rb index f4891d8..9ed15ef 100644 --- a/src/app/models/deployable.rb +++ b/src/app/models/deployable.rb @@ -1,2 +1,63 @@ +# +# Copyright (C) 2011 Red Hat, Inc. +# Written by Scott Seago sseago@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. + +require 'sunspot_rails' class Deployable < ActiveRecord::Base + include PermissionedObject + include ImageWarehouseObject + searchable do + text :name, :as => :code_substring + text :summary, :as => :code_substring + end + + has_and_belongs_to_many :assemblies + has_many :deployments + + has_many :permissions, :as => :permission_object, :dependent => :destroy, + :include => [:role], + :order => "permissions.id ASC" + + before_validation :generate_uuid + before_save :update_xml + + has_many :permissions, :as => :permission_object, :dependent => :destroy, + :include => [:role], + :order => "permissions.id ASC" + + validates_presence_of :uuid + validates_uniqueness_of :uuid + validates_presence_of :name + validates_uniqueness_of :name + validates_length_of :name, :maximum => 255 + + def self.default_privilege_target_type + Template + end + + def update_xml + xml.name = self.name + xml.description = self.summary + write_attribute(:xml, xml.to_xml) + end + + def self.find_or_create(id) + id ? Deployable.find(id) : Deployable.new + end + end diff --git a/src/app/models/deployment.rb b/src/app/models/deployment.rb new file mode 100644 index 0000000..1b41871 --- /dev/null +++ b/src/app/models/deployment.rb @@ -0,0 +1,84 @@ +# +# Copyright (C) 2011 Red Hat, Inc. +# Written by Scott Seago sseago@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. + +require 'sunspot_rails' +class Deployment < ActiveRecord::Base + include SearchFilter + include PermissionedObject + + searchable do + text :name, :as => :code_substring + end + + belongs_to :pool + + belongs_to :deployable + has_many :instances + + belongs_to :realm + belongs_to :owner, :class_name => "User", :foreign_key => "owner_id" + + has_many :permissions, :as => :permission_object, :dependent => :destroy, + :include => [:role], + :order => "permissions.id ASC" + + validates_presence_of :pool_id + validates_presence_of :deployable_id + + validates_presence_of :name + validates_uniqueness_of :name, :scope => :pool_id + validates_length_of :name, :maximum => 1024 + + SEARCHABLE_COLUMNS = %w(name) + + def object_list + super << pool + end + class << self + alias orig_list_for_user_include list_for_user_include + alias orig_list_for_user_conditions list_for_user_conditions + end + + def self.list_for_user_include + includes = orig_list_for_user_include + includes << { :pool => {:permissions => {:role => :privileges}}} + includes + end + + def self.list_for_user_conditions + "(#{orig_list_for_user_conditions}) or + (permissions_pools.user_id=:user and + privileges_roles.target_type=:target_type and + privileges_roles.action=:action)" + end + + def get_action_list(user=nil) + # FIXME: how do actions and states interact for deployments? + # For instances the list comes from the provider based on current state. + # Deployments don't currently have an explicit state field, but + # something could be calculated from associated instances. + ["start", "stop", "reboot"] + end + + def valid_action?(action) + return get_action_list.include?(action) ? true : false + end + + +end diff --git a/src/app/models/image_warehouse_object.rb b/src/app/models/image_warehouse_object.rb new file mode 100644 index 0000000..48dd04f --- /dev/null +++ b/src/app/models/image_warehouse_object.rb @@ -0,0 +1,42 @@ +# +# Copyright (C) 2010 Red Hat, Inc. +# Written by Scott Seago sseago@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. +module ImageWarehouseObject + + WAREHOUSE_CONFIG = YAML.load_file("#{RAILS_ROOT}/config/image_warehouse.yml") + + def xml + @xml ||= ImageDescriptorXML.new(self[:xml].to_s) + end + + def upload + self.uri = File.join(WAREHOUSE_CONFIG['baseurl'], "#{uuid}") + response = Typhoeus::Request.put(self.uri, :body => xml.to_xml, :timeout => 30000) + if response.code == 200 + update_attribute(:uploaded, true) + else + raise "failed to upload template (code #{response.code}): #{response.body}" + end + end + + def generate_uuid + # TODO: generate real uuid here, e.g. with some ruby uuid generator + self.uuid ||= "#{self.name}-#{Time.now.to_f.to_s}" + end + +end diff --git a/src/app/models/instance.rb b/src/app/models/instance.rb index b84a596..68c7174 100644 --- a/src/app/models/instance.rb +++ b/src/app/models/instance.rb @@ -37,9 +37,11 @@ class Instance < ActiveRecord::Base
belongs_to :pool belongs_to :cloud_account + belongs_to :deployment
belongs_to :hardware_profile belongs_to :template + belongs_to :assembly belongs_to :realm belongs_to :owner, :class_name => "User", :foreign_key => "owner_id" belongs_to :instance_hwp @@ -51,7 +53,8 @@ class Instance < ActiveRecord::Base
validates_presence_of :pool_id validates_presence_of :hardware_profile_id - validates_presence_of :template_id + validates_presence_of :template_id, :unless => :deployment_id + validates_presence_of :assembly_id, :if => :deployment_id
#validates_presence_of :external_key # TODO: can we do uniqueness validation on indirect association @@ -79,8 +82,15 @@ class Instance < ActiveRecord::Base validates_inclusion_of :state, :in => STATES
+ def validate + if assembly and template + errors.add(:assembly, "Please specify either template or assembly, but not both") + errors.add(:template, "Please specify either template or assembly, but not both") + end + end + def object_list - super << pool + super + [pool, deployment] end class << self alias orig_list_for_user_include list_for_user_include @@ -89,15 +99,19 @@ class Instance < ActiveRecord::Base
def self.list_for_user_include includes = orig_list_for_user_include - includes << { :pool => {:permissions => {:role => :privileges}}} + includes << { :pool => {:permissions => {:role => :privileges}}, + :deployment => {:permissions => {:role => :privileges}}} includes end
def self.list_for_user_conditions "(#{orig_list_for_user_conditions}) or - (permissions_pools.user_id=:user and + (permissions_deployments.user_id=:user and privileges_roles.target_type=:target_type and - privileges_roles.action=:action)" + privileges_roles.action=:action) or + (permissions_pools.user_id=:user and + privileges_roles_2.target_type=:target_type and + privileges_roles_2.action=:action)" end
def get_action_list(user=nil) diff --git a/src/app/models/permission.rb b/src/app/models/permission.rb index 22b228a..03f75b7 100644 --- a/src/app/models/permission.rb +++ b/src/app/models/permission.rb @@ -35,12 +35,18 @@ class Permission < ActiveRecord::Base :foreign_key => "permission_object_id" belongs_to :instance, :class_name => "Instance", :foreign_key => "permission_object_id" + belongs_to :deployment, :class_name => "Deployment", + :foreign_key => "permission_object_id" belongs_to :provider, :class_name => "Provider", :foreign_key => "permission_object_id" belongs_to :cloud_account, :class_name => "CloudAccount", :foreign_key => "permission_object_id" belongs_to :template, :class_name => "Template", :foreign_key => "permission_object_id" + belongs_to :assembly, :class_name => "Assembly", + :foreign_key => "permission_object_id" + belongs_to :deployable, :class_name => "Deployable", + :foreign_key => "permission_object_id" belongs_to :base_permission_object, :class_name => "BasePermissionObject", :foreign_key => "permission_object_id"
diff --git a/src/app/models/permissioned_object.rb b/src/app/models/permissioned_object.rb index d46ed8f..d2a5878 100644 --- a/src/app/models/permissioned_object.rb +++ b/src/app/models/permissioned_object.rb @@ -22,7 +22,7 @@ module PermissionedObject 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| - return true if obj.permissions.find(:first, + return true if obj and obj.permissions.find(:first, :include => [:role => :privileges], :conditions => ["permissions.user_id=:user and diff --git a/src/app/models/privilege.rb b/src/app/models/privilege.rb index f7a61ef..f5a5887 100644 --- a/src/app/models/privilege.rb +++ b/src/app/models/privilege.rb @@ -43,6 +43,7 @@ class Privilege < ActiveRecord::Base Pool => ACTIONS - [USE], PoolFamily => ACTIONS - [USE], Instance => ACTIONS, + Deployment => ACTIONS, Quota => [VIEW, MODIFY], HardwareProfile => ACTIONS - [USE, VIEW], Realm => ACTIONS - [VIEW], @@ -99,6 +100,14 @@ class Privilege < ActiveRecord::Base # view_perms Can view permissions # set_perms Can set permissions (or can set instance permissions on this pool) # + # Instance This Deployment or deployments within this Pool + # view Can view + # use Can perform lifecycle actions on and/or view console + # modify Can modify + # create Can create (within this Pool) + # view_perms Can view permissions + # set_perms Can set permissions (or can set instance permissions on this pool) + # # Quota The Pool/CloudAccount/PoolFamily/User assigned the quota # view Can view quota on this obj # modify Can edit quota on this obj diff --git a/src/app/models/template.rb b/src/app/models/template.rb index 4e8ad27..d930294 100644 --- a/src/app/models/template.rb +++ b/src/app/models/template.rb @@ -3,6 +3,7 @@ require 'typhoeus'
class Template < ActiveRecord::Base include PermissionedObject + include ImageWarehouseObject searchable do text :name, :as => :code_substring text :platform, :as => :code_substring @@ -13,6 +14,7 @@ class Template < ActiveRecord::Base
has_many :images, :dependent => :destroy has_many :instances + has_and_belongs_to_many :assemblies before_validation :generate_uuid before_save :update_xml before_destroy :no_instances? @@ -21,8 +23,6 @@ class Template < ActiveRecord::Base :include => [:role], :order => "permissions.id ASC"
- WAREHOUSE_CONFIG = YAML.load_file("#{RAILS_ROOT}/config/image_warehouse.yml") - validates_presence_of :uuid validates_uniqueness_of :uuid validates_presence_of :name @@ -41,25 +41,6 @@ class Template < ActiveRecord::Base true end
- def xml - @xml ||= ImageDescriptorXML.new(self[:xml].to_s) - end - - def upload - self.uri = File.join(WAREHOUSE_CONFIG['baseurl'], "#{uuid}") - response = Typhoeus::Request.put(self.uri, :body => xml.to_xml, :timeout => 30000) - if response.code == 200 - update_attribute(:uploaded, true) - else - raise "failed to upload template (code #{response.code}): #{response.body}" - end - end - - def generate_uuid - # TODO: generate real uuid here, e.g. with some ruby uuid generator - self.uuid ||= "#{self.name}-#{Time.now.to_f.to_s}" - end - def update_xml xml.name = self.name xml.description = self.summary diff --git a/src/db/migrate/20110207100700_create_assemblies.rb b/src/db/migrate/20110207100700_create_assemblies.rb new file mode 100644 index 0000000..7e4be57 --- /dev/null +++ b/src/db/migrate/20110207100700_create_assemblies.rb @@ -0,0 +1,24 @@ +class CreateAssemblies < ActiveRecord::Migration + def self.up + create_table :assemblies do |t| + t.string :uuid, :null => false + t.binary :xml, :null => false + t.string :uri + t.string :name + t.string :architecture + t.text :summary + t.boolean :uploaded, :default => false + t.integer :lock_version, :default => 0 + t.timestamps + end + create_table :assemblies_templates, :id => false do |t| + t.integer :assembly_id, :null => false + t.integer :template_id, :null => false + end + end + + def self.down + drop_table :assemblies_templates + drop_table :assemblies + end +end diff --git a/src/db/migrate/20110207100800_update_deployables.rb b/src/db/migrate/20110207100800_update_deployables.rb new file mode 100644 index 0000000..4414560 --- /dev/null +++ b/src/db/migrate/20110207100800_update_deployables.rb @@ -0,0 +1,24 @@ +class UpdateDeployables < ActiveRecord::Migration + def self.up + change_table :deployables do |t| + t.integer :lock_version, :default => 0 + t.string :uuid, :null => false + t.binary :xml, :null => false + t.string :uri + t.text :summary + t.boolean :uploaded, :default => false + end + + create_table :assemblies_deployables, :id => false do |t| + t.integer :assembly_id, :null => false + t.integer :deployable_id, :null => false + end + end + + def self.down + drop_table :assemblies_deployables + change_table :deployables do |t| + t.remove :lock_version, :uuid, :xml, :uri, :summary, :uploaded + end + end +end diff --git a/src/db/migrate/20110207100900_create_deployments.rb b/src/db/migrate/20110207100900_create_deployments.rb new file mode 100644 index 0000000..d026f7b --- /dev/null +++ b/src/db/migrate/20110207100900_create_deployments.rb @@ -0,0 +1,17 @@ +class CreateDeployments < ActiveRecord::Migration + def self.up + create_table :deployments do |t| + t.string :name, :null => false, :limit => 1024 + t.integer :realm_id + t.integer :owner_id + t.integer :pool_id, :null => false + t.integer :deployable_id, :null => false + t.integer :lock_version, :default => 0 + t.timestamps + end + end + + def self.down + drop_table :deployments + end +end diff --git a/src/db/migrate/20110207101000_update_instances.rb b/src/db/migrate/20110207101000_update_instances.rb new file mode 100644 index 0000000..4b758f7 --- /dev/null +++ b/src/db/migrate/20110207101000_update_instances.rb @@ -0,0 +1,21 @@ +class UpdateInstances < ActiveRecord::Migration + def self.up + change_table :instances do |t| + t.integer :assembly_id + t.integer :deployment_id + t.change :template_id, :integer, :null => true + end + + create_table :assemblies_instances, :id => false do |t| + t.integer :assembly_id, :null => false + t.integer :deployable_id, :null => false + end + end + + def self.down + change_table :instances do |t| + t.remove :assembly_id, :deployment_id + t.change :template_id, :integer, :null => false + end + end +end diff --git a/src/db/migrate/20110207101100_deployment_roles.rb b/src/db/migrate/20110207101100_deployment_roles.rb new file mode 100644 index 0000000..b63413a --- /dev/null +++ b/src/db/migrate/20110207101100_deployment_roles.rb @@ -0,0 +1,65 @@ +class DeploymentRoles < ActiveRecord::Migration + VIEW = "view" + USE = "use" + MOD = "modify" + CRE = "create" + VPRM = "view_perms" + GPRM = "set_perms" + NEW_ROLES = { + Deployment => + {"Deployment Controller" => [false, {Deployment => [VIEW,USE], + Instance => [VIEW]}], + "Deployment Owner" => [true, {Deployment => [VIEW,USE,MOD, VPRM,GPRM], + Instance => [VIEW,USE,MOD]}]}, + Pool => + {"Pool User" => [false, {Pool => [VIEW], + Instance => [ CRE], + Deployment => [ CRE], + Quota => [VIEW]}], + "Pool Owner" => [true, {Pool => [VIEW, MOD, VPRM,GPRM], + Instance => [VIEW,USE,MOD,CRE], + Deployment => [VIEW,USE,MOD,CRE], + Quota => [VIEW]}]}, + BasePermissionObject => + {"Pool Administrator" => [false, {Pool => [VIEW, MOD,CRE,VPRM,GPRM], + Instance => [VIEW,USE,MOD,CRE,VPRM,GPRM], + Deployment => [VIEW,USE,MOD,CRE,VPRM,GPRM], + Quota => [VIEW, MOD], + PoolFamily => [VIEW, MOD,CRE,VPRM,GPRM]}], + "Administrator" => [false, {Provider => [VIEW, MOD,CRE,VPRM,GPRM], + CloudAccount => [VIEW,USE,MOD,CRE,VPRM,GPRM], + HardwareProfile => [ MOD,CRE,VPRM,GPRM], + Realm => [ USE,MOD,CRE,VPRM,GPRM], + User => [VIEW, MOD,CRE], + Pool => [VIEW, MOD,CRE,VPRM,GPRM], + Instance => [VIEW,USE,MOD,CRE,VPRM,GPRM], + Deployment => [VIEW,USE,MOD,CRE,VPRM,GPRM], + Quota => [VIEW, MOD], + PoolFamily => [VIEW, MOD,CRE,VPRM,GPRM], + Template => [VIEW,USE,MOD,CRE,VPRM,GPRM], + BasePermissionObject => [ MOD, VPRM,GPRM]}]}} + def self.up + unless Role.all.size == 0 + Role.transaction do + NEW_ROLES.each do |role_scope, scoped_hash| + scoped_hash.each do |role_name, role_def| + role = Role.find_or_initialize_by_name(role_name) + role.update_attributes({:name => role_name, :scope => role_scope.name, + :assign_to_owner => role_def[0]}) + role.privileges = {} + role.save! + role_def[1].each do |priv_type, priv_actions| + priv_actions.each do |action| + Privilege.create!(:role => role, :target_type => priv_type.name, + :action => action) + end + end + end + end + end + end + end + + def self.down + end +end diff --git a/src/db/seeds.rb b/src/db/seeds.rb index 71726bf..d0b6477 100644 --- a/src/db/seeds.rb +++ b/src/db/seeds.rb @@ -17,6 +17,11 @@ roles = {Instance => {"Instance Controller" => [false, {Instance => [VIEW,USE]}], "Instance Owner" => [true, {Instance => [VIEW,USE,MOD, VPRM,GPRM]}]}, + Deployment => + {"Deployment Controller" => [false, {Deployment => [VIEW,USE], + Instance => [VIEW]}], + "Deployment Owner" => [true, {Deployment => [VIEW,USE,MOD, VPRM,GPRM], + Instance => [VIEW,USE,MOD]}]}, PoolFamily => {"Pool Family User" => [false, {Pool => [VIEW]}], "Pool Family Owner" => [true, {PoolFamily => [VIEW, MOD, VPRM,GPRM], @@ -24,9 +29,11 @@ roles = Pool => {"Pool User" => [false, {Pool => [VIEW], Instance => [ CRE], + Deployment => [ CRE], Quota => [VIEW]}], "Pool Owner" => [true, {Pool => [VIEW, MOD, VPRM,GPRM], Instance => [VIEW,USE,MOD,CRE], + Deployment => [VIEW,USE,MOD,CRE], Quota => [VIEW]}]}, Provider => {"Provider Owner" => [true, {Provider => [VIEW, MOD, VPRM,GPRM], @@ -46,6 +53,7 @@ roles = "Pool Creator" => [false, {Pool => [ CRE]}], "Pool Administrator" => [false, {Pool => [VIEW, MOD,CRE,VPRM,GPRM], Instance => [VIEW,USE,MOD,CRE,VPRM,GPRM], + Deployment => [VIEW,USE,MOD,CRE,VPRM,GPRM], Quota => [VIEW, MOD], PoolFamily => [VIEW, MOD,CRE,VPRM,GPRM]}], "Template Administrator" => [false, {Template => [VIEW,USE,MOD,CRE,VPRM,GPRM]}], @@ -56,6 +64,7 @@ roles = User => [VIEW, MOD,CRE], Pool => [VIEW, MOD,CRE,VPRM,GPRM], Instance => [VIEW,USE,MOD,CRE,VPRM,GPRM], + Deployment => [VIEW,USE,MOD,CRE,VPRM,GPRM], Quota => [VIEW, MOD], PoolFamily => [VIEW, MOD,CRE,VPRM,GPRM], Template => [VIEW,USE,MOD,CRE,VPRM,GPRM], @@ -63,11 +72,11 @@ roles = Role.transaction do roles.each do |role_scope, scoped_hash| scoped_hash.each do |role_name, role_def| + role = Role.find_or_initialize_by_name(role_name) + role.update_attributes({:name => role_name, :scope => role_scope.name, + :assign_to_owner => role_def[0]}) + role.save! role_def[1].each do |priv_type, priv_actions| - role = Role.find_or_initialize_by_name(role_name) - role.update_attributes({:name => role_name, :scope => role_scope.name, - :assign_to_owner => role_def[0]}) - role.save! priv_actions.each do |action| Privilege.create!(:role => role, :target_type => priv_type.name, :action => action) diff --git a/src/spec/factories/assembly.rb b/src/spec/factories/assembly.rb new file mode 100644 index 0000000..af290dc --- /dev/null +++ b/src/spec/factories/assembly.rb @@ -0,0 +1,5 @@ +Factory.define :assembly do |a| + a.sequence(:name) { |n| "assembly#{n}" } + a.architecture 'x86_64' + a.templates { |t| [t.association(:template)] } +end diff --git a/src/spec/factories/deployable.rb b/src/spec/factories/deployable.rb new file mode 100644 index 0000000..60b160b --- /dev/null +++ b/src/spec/factories/deployable.rb @@ -0,0 +1,4 @@ +Factory.define :deployable do |a| + a.sequence(:name) { |n| "deployable#{n}" } + a.assemblies { |t| [t.association(:assembly)] } +end diff --git a/src/spec/factories/deployment.rb b/src/spec/factories/deployment.rb new file mode 100644 index 0000000..f3c0522 --- /dev/null +++ b/src/spec/factories/deployment.rb @@ -0,0 +1,6 @@ +Factory.define :deployment do |d| + d.sequence(:name) { |n| "deployment#{n}" } + d.association :deployable, :factory => :deployable + d.association :pool, :factory => :pool + d.association :owner, :factory => :user +end diff --git a/src/spec/models/assembly_spec.rb b/src/spec/models/assembly_spec.rb new file mode 100644 index 0000000..2693116 --- /dev/null +++ b/src/spec/models/assembly_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +describe Assembly do + + it "should have automatically generated uuid after validation" do + a = Factory.build(:assembly) + a.uuid = nil + a.save + a.uuid.should_not be_nil + end + + it "should not be valid if assembly name is too long" do + a = Factory.build(:assembly) + a.name = ('a' * 256) + a.valid?.should be_false + a.errors[:name].should_not be_nil + a.errors[:name].should =~ /^is too long.*/ + end + + it "should have associated template" do + a = Factory.build(:assembly) + a.templates.size.should eql(1) + end + +end diff --git a/src/spec/models/deployable_spec.rb b/src/spec/models/deployable_spec.rb new file mode 100644 index 0000000..af1fc9f --- /dev/null +++ b/src/spec/models/deployable_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +describe Deployable do + + it "should have automatically generated uuid after validation" do + d = Factory.build(:deployable) + d.uuid = nil + d.save + d.uuid.should_not be_nil + end + + it "should not be valid if deployable name is too long" do + d = Factory.build(:deployable) + d.name = ('a' * 256) + d.valid?.should be_false + d.errors[:name].should_not be_nil + d.errors[:name].should =~ /^is too long.*/ + end + + it "should have associated assembly" do + d = Factory.build(:deployable) + d.assemblies.size.should eql(1) + end + +end diff --git a/src/spec/models/deployment_spec.rb b/src/spec/models/deployment_spec.rb new file mode 100644 index 0000000..c8eda13 --- /dev/null +++ b/src/spec/models/deployment_spec.rb @@ -0,0 +1,59 @@ +require 'spec_helper' + +describe Deployment do + before(:each) do + @quota = Factory :quota + @pool = Factory(:pool, :quota_id => @quota.id) + @deployment = Factory.build(:deployment, :pool_id => @pool.id) + @actions = ['start', 'stop'] + end + + it "should require pool to be set" do + @deployment.pool_id = nil + @deployment.should_not be_valid + + @deployment.pool_id = 1 + @deployment.should be_valid + end + + it "should require deployable to be set" do + @deployment.deployable_id = nil + @deployment.should_not be_valid + + @deployment.deployable_id = 1 + @deployment.should be_valid + end + + it "should have a name of reasonable length" do + [nil, '', 'x'*1025].each do |invalid_name| + @deployment.name = invalid_name + @deployment.should_not be_valid + end + @deployment.name = 'x'*1024 + @deployment.should be_valid + + end + + it "should have unique name" do + @deployment.save! + second_deployment = Factory.build(:deployment, + :pool_id => @deployment.pool_id, + :name => @deployment.name) + second_deployment.should_not be_valid + + second_deployment.name = 'unique name' + second_deployment.should be_valid + end + + it "should tell apart valid and invalid actions" do + @deployment.stub!(:get_action_list).and_return(@actions) + @deployment.valid_action?('invalid action').should == false + @deployment.valid_action?('start').should == true + end + + it "should return action list" do + @deployment.get_action_list.should eql(["start", "stop", "reboot"]) + end + + +end diff --git a/src/spec/models/instance_spec.rb b/src/spec/models/instance_spec.rb index 625718d..787c0c5 100644 --- a/src/spec/models/instance_spec.rb +++ b/src/spec/models/instance_spec.rb @@ -24,14 +24,25 @@ describe Instance do @instance.should be_valid end
- it "should require template to be set" do + it "should require template to be set if there no deployment" do @instance.template_id = nil + @instance.deployment_id = nil @instance.should_not be_valid
@instance.template_id = 1 @instance.should be_valid end
+ it "should not allow template to be set if there's a deployment" do + @instance.deployment_id = 1 + @instance.template_id = 1 + @instance.should_not be_valid + + @instance.template_id = nil + @instance.assembly_id = 1 + @instance.should be_valid + end + it "should have a name of reasonable length" do [nil, '', 'x'*1025].each do |invalid_name| @instance.name = invalid_name