Skip to content

Commit

Permalink
Add method to copy service templates
Browse files Browse the repository at this point in the history
  • Loading branch information
d-m-u committed Feb 26, 2019
1 parent cb18388 commit 35e2a4a
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 1 deletion.
4 changes: 4 additions & 0 deletions app/models/miq_provision_request_template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ def request_task_class
MiqProvision
end

def service_template_resource_copy
dup.tap(&:save!)
end

def execute
# Should not be called.
raise _("Provision Request Templates do not support the execute method.")
Expand Down
6 changes: 6 additions & 0 deletions app/models/service_template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ class ServiceTemplate < ApplicationRecord
include ArchivedMixin
include CiFeatureMixin
include_concern 'Filter'
include_concern 'Copy'

validates :name, :presence => true
belongs_to :tenant
# # These relationships are used to specify children spawned from a parent service
# has_many :child_services, :class_name => "ServiceTemplate", :foreign_key => :service_template_id
Expand Down Expand Up @@ -435,6 +437,10 @@ def provision_workflow(user, dialog_options = nil, request_options = {})
end
end

def initialize_copy(_orig)
super.tap { |obj| obj.update_attributes(:guid => nil, :created_at => Time.zone.now, :updated_at => Time.zone.now) }
end

def add_resource(rsc, options = {})
super
adjust_service_type
Expand Down
17 changes: 17 additions & 0 deletions app/models/service_template/copy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module ServiceTemplate::Copy
extend ActiveSupport::Concern

def template_copy(new_name = "Copy of " + name + Time.zone.now.to_s)
if template_valid? && type != 'ServiceTemplateAnsiblePlaybook'
ActiveRecord::Base.transaction do
dup.tap do |template|
template.update_attributes(:name => new_name, :display => false)
service_resources.each do |sr|
resource = sr.resource.respond_to?(:service_template_resource_copy) ? sr.resource.service_template_resource_copy : sr.resource
template.add_resource(resource, sr)
end
end.save!
end
end
end
end
8 changes: 7 additions & 1 deletion app/models/service_template_ansible_tower.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,13 @@ def self.create_catalog_item(options, _auth_user = nil)

def remove_invalid_resource
# remove the resource from both memory and table
service_resources.to_a.delete_if { |r| r.destroy unless r.reload.resource.present? }
service_resources.to_a.delete_if do |r|
if r.persisted?
r.destroy if r.reload.resource.blank?
elsif r.resource.blank?
r.destroy
end
end
end

def create_subtasks(_parent_service_task, _parent_service)
Expand Down
185 changes: 185 additions & 0 deletions spec/models/service_template_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,191 @@
end
end

context "#template_copy" do
let(:service_template_ansible_tower) { FactoryBot.create(:service_template_ansible_tower, :name => "thing") }
let(:service_template_orchestration) { FactoryBot.create(:service_template_orchestration, :name => "thing2") }
before do
@st1 = FactoryBot.create(:service_template)
end

context "with given name" do
it "without resource " do
expect(ServiceTemplate.count).to eq(1)
@st1.template_copy("drew")
expect(ServiceTemplate.count).to eq(2)
expect(ServiceTemplate.find_by(:name => "drew")).not_to be(nil)
expect(ServiceTemplate.find_by(:name => "drew").display).to be(false)
expect(ServiceTemplate.find_by(:name => "drew").guid).not_to eq(@st1.guid)
end

it "with non-copyable resource (configuration script base)" do
@st1.add_resource(FactoryBot.create(:configuration_script_base))
expect(ServiceTemplate.count).to eq(1)
@st1.template_copy("thing")
expect(ServiceTemplate.count).to eq(2)
expect(ServiceTemplate.find_by(:name => "thing").service_resources).not_to be(nil)
expect(@st1.service_resources.first.resource).not_to be(nil)
expect(ServiceTemplate.find_by(:name => "thing").service_resources.first.resource).to eq(@st1.service_resources.first.resource)
expect(ConfigurationScriptBase.count).to eq(1)
expect(ServiceTemplate.find_by(:name => "thing").display).to be(false)
expect(ServiceTemplate.find_by(:name => "thing").guid).not_to eq(@st1.guid)
end

it "with non-copyable resource (ext management system)" do
@st1.add_resource(FactoryBot.create(:ext_management_system))
expect(ServiceTemplate.count).to eq(1)
@st1.template_copy("thing")
expect(ServiceTemplate.count).to eq(2)
expect(ServiceTemplate.find_by(:name => "thing").service_resources.first.resource_id).to eq(@st1.service_resources.first.resource_id)
expect(ExtManagementSystem.count).to eq(1)
expect(ServiceTemplate.find_by(:name => "thing").guid).not_to eq(@st1.guid)
expect(ServiceTemplate.find_by(:name => "thing").service_resources).not_to be(nil)
expect(ServiceTemplate.find_by(:name => "thing").display).to be(false)
expect(@st1.service_resources.first.resource).not_to be(nil)
end

it "with non-copyable resource (orchestration template)" do
@st1.add_resource(FactoryBot.create(:orchestration_template))
expect(ServiceTemplate.count).to eq(1)
@st1.template_copy("thing")
expect(ServiceTemplate.count).to eq(2)
expect(ServiceTemplate.find_by(:name => "thing").service_resources.first.resource_id).to eq(@st1.service_resources.first.resource_id)
expect(OrchestrationTemplate.count).to eq(1)
expect(ServiceTemplate.find_by(:name => "thing").guid).not_to eq(@st1.guid)
expect(ServiceTemplate.find_by(:name => "thing").service_resources).not_to be(nil)
expect(ServiceTemplate.find_by(:name => "thing").display).to be(false)
expect(@st1.service_resources.first.resource).not_to be(nil)
end

it "with copyable resource" do
admin = FactoryBot.create(:user_admin)
vm_template = FactoryBot.create(:vm_openstack, :ext_management_system => FactoryBot.create(:ext_management_system))
ptr = FactoryBot.create(:miq_provision_request_template, :requester => admin, :src_vm_id => vm_template.id)
@st1.add_resource(ptr)
expect(ServiceTemplate.count).to eq(1)
@st1.template_copy("thing1")
expect(ServiceTemplate.count).to eq(2)
expect(MiqProvisionRequestTemplate.count).to eq(2)
expect(ServiceTemplate.find_by(:name => "thing1").guid).not_to eq(@st1.guid)
expect(ServiceTemplate.find_by(:name => "thing1").display).to be(false)
expect(ServiceTemplate.find_by(:name => "thing1").service_resources).not_to be(nil)
expect(@st1.service_resources.first.resource).not_to be(nil)
end

it "with copyable resource copies sr options" do
admin = FactoryBot.create(:user_admin)
vm_template = FactoryBot.create(:vm_openstack, :ext_management_system => FactoryBot.create(:ext_management_system))
ptr = FactoryBot.create(:miq_provision_request_template, :requester => admin, :src_vm_id => vm_template.id)
@st1.add_resource(ptr)
@st1.service_resources.first.update_attributes(:scaling_min => 4)
expect(ServiceTemplate.count).to eq(1)
expect(@st1.service_resources.first.scaling_min).to eq(4)
@st1.template_copy("thing1")
expect(ServiceTemplate.count).to eq(2)
expect(MiqProvisionRequestTemplate.count).to eq(2)
expect(ServiceTemplate.find_by(:name => "thing1").guid).not_to eq(@st1.guid)
expect(ServiceTemplate.find_by(:name => "thing1").display).to be(false)
expect(ServiceTemplate.find_by(:name => "thing1").service_resources.first.scaling_min).to eq(4)
expect(ServiceTemplate.find_by(:name => "thing1").service_resources).not_to be(nil)
expect(@st1.service_resources.first.resource).not_to be(nil)
end

it "service template ansible tower with copyable resource" do
admin = FactoryBot.create(:user_admin)
vm_template = FactoryBot.create(:vm_openstack, :ext_management_system => FactoryBot.create(:ext_management_system))
ptr = FactoryBot.create(:miq_provision_request_template, :requester => admin, :src_vm_id => vm_template.id)
service_template_ansible_tower.add_resource(ptr)
expect(ServiceTemplate.count).to eq(2)
service_template_ansible_tower.template_copy("thing1")
expect(ServiceTemplate.count).to eq(3)
expect(MiqProvisionRequestTemplate.count).to eq(2)
expect(ServiceTemplate.find_by(:name => "thing1").guid).not_to eq(service_template_ansible_tower.guid)
expect(ServiceTemplate.find_by(:name => "thing1").display).to be(false)
expect(ServiceTemplate.find_by(:name => "thing1").service_resources).not_to be(nil)
expect(service_template_ansible_tower.service_resources.first.resource).not_to be(nil)
end

it "service template orchestration with copyable resource" do
admin = FactoryBot.create(:user_admin)
vm_template = FactoryBot.create(:vm_openstack, :ext_management_system => FactoryBot.create(:ext_management_system))
ptr = FactoryBot.create(:miq_provision_request_template, :requester => admin, :src_vm_id => vm_template.id)
service_template_orchestration.add_resource(ptr)
expect(ServiceTemplate.count).to eq(2)
service_template_orchestration.template_copy("thing1")
expect(ServiceTemplate.count).to eq(3)
expect(MiqProvisionRequestTemplate.count).to eq(2)
expect(ServiceTemplate.find_by(:name => "thing1").guid).not_to eq(service_template_orchestration.guid)
expect(ServiceTemplate.find_by(:name => "thing1").display).to be(false)
expect(ServiceTemplate.find_by(:name => "thing1").service_resources).not_to be(nil)
expect(service_template_orchestration.service_resources.first.resource).not_to be(nil)
end
end

context "without given name" do
it "without resource" do
expect(ServiceTemplate.count).to eq(1)
@st1.template_copy
expect(ServiceTemplate.count).to eq(2)
expect(ServiceTemplate.find_by("name ILIKE ?", "Copy of service%").guid).not_to eq(@st1.guid)
expect(ServiceTemplate.find_by("name ILIKE ?", "Copy of service%").display).to be(false)
expect(ServiceTemplate.find_by("name ILIKE ?", "Copy of service%").service_resources.count).to eq(0)
expect(@st1.service_resources.count).to eq(0)
end

it "with non-copyable resource (configuration_script_base)" do
@st1.add_resource(FactoryBot.create(:configuration_script_base))
expect(ServiceTemplate.count).to eq(1)
@st1.template_copy
expect(ServiceTemplate.count).to eq(2)
expect(ServiceTemplate.where("name ILIKE ?", "Copy of service%").first.service_resources.first.resource_id).to eq(@st1.service_resources.first.resource_id)
expect(ConfigurationScriptBase.count).to eq(1)
expect(ServiceTemplate.find_by("name ILIKE ?", "Copy of service%").display).to be(false)
expect(ServiceTemplate.find_by("name ILIKE ?", "Copy of service%").guid).not_to eq(@st1.guid)
end

it "with non-copyable resource (ext management system)" do
@st1.add_resource(FactoryBot.create(:ext_management_system))
expect(ServiceTemplate.count).to eq(1)
@st1.template_copy
expect(ServiceTemplate.count).to eq(2)
expect(ServiceTemplate.where("name ILIKE ?", "Copy of service%").first.service_resources.first.resource_id).to eq(@st1.service_resources.first.resource_id)
expect(ExtManagementSystem.count).to eq(1)
expect(ServiceTemplate.find_by("name ILIKE ?", "Copy of service%").guid).not_to eq(@st1.guid)
expect(ServiceTemplate.find_by("name ILIKE ?", "Copy of service%").display).to be(false)
expect(ServiceTemplate.find_by("name ILIKE ?", "Copy of service%").service_resources).not_to be(nil)
expect(@st1.service_resources.first.resource).not_to be(nil)
end

it "with non-copyable resource (orchestration template)" do
@st1.add_resource(FactoryBot.create(:orchestration_template))
expect(ServiceTemplate.count).to eq(1)
@st1.template_copy
expect(ServiceTemplate.count).to eq(2)
expect(ServiceTemplate.where("name ILIKE ?", "Copy of service%").first.service_resources.first.resource_id).to eq(@st1.service_resources.first.resource_id)
expect(OrchestrationTemplate.count).to eq(1)
expect(ServiceTemplate.find_by("name ILIKE ?", "Copy of service%").guid).not_to eq(@st1.guid)
expect(ServiceTemplate.find_by("name ILIKE ?", "Copy of service%").display).to be(false)
expect(ServiceTemplate.find_by("name ILIKE ?", "Copy of service%").service_resources).not_to be(nil)
expect(@st1.service_resources.first.resource).not_to be(nil)
end

it "with copyable resource" do
admin = FactoryBot.create(:user_admin)
vm_template = FactoryBot.create(:vm_openstack, :ext_management_system => FactoryBot.create(:ext_management_system))
ptr = FactoryBot.create(:miq_provision_request_template, :requester => admin, :src_vm_id => vm_template.id)
@st1.add_resource(ptr)
expect(ServiceTemplate.count).to eq(1)
@st1.template_copy
expect(ServiceTemplate.count).to eq(2)
expect(MiqProvisionRequestTemplate.count).to eq(2)
expect(ServiceTemplate.find_by("name ILIKE ?", "Copy of service%").guid).not_to eq(@st1.guid)
expect(ServiceTemplate.find_by("name ILIKE ?", "Copy of service%").display).to be(false)
expect(ServiceTemplate.find_by("name ILIKE ?", "Copy of service%").service_resources).not_to be(nil)
expect(@st1.service_resources.first.resource).not_to be(nil)
end
end
end

context "#composite?" do
before do
@st1 = FactoryBot.create(:service_template)
Expand Down

0 comments on commit 35e2a4a

Please sign in to comment.