diff --git a/app/models/manageiq/providers/vmware/infra_manager/provision/customization.rb b/app/models/manageiq/providers/vmware/infra_manager/provision/customization.rb index 7f9e14c6e..23632be5c 100644 --- a/app/models/manageiq/providers/vmware/infra_manager/provision/customization.rb +++ b/app/models/manageiq/providers/vmware/infra_manager/provision/customization.rb @@ -23,8 +23,9 @@ def build_customization_spec spec = VimHash.new("CustomizationSpec") if spec.nil? # Create customization spec based on platform - case source.platform - when 'linux', 'windows' + if customization_template + identity = customization_identity_cloud_init(spec) + elsif %w[linux windows].include?(source.platform) identity = send("customization_identity_#{source.platform}", spec) return if identity.nil? spec.identity = identity @@ -106,6 +107,12 @@ def customization_identity_linux(spec) identity end + def customization_identity_cloud_init(spec) + identity = find_build_spec_path(spec, "CustomizationCloudinitPrep", "identity") + identity.userdata = userdata_payload + identity + end + def collect_nic_settings nics = Array.wrap(options[:nic_settings]) nic = nics[0] @@ -273,4 +280,11 @@ def set_spec_array_option(obj, property, key, override_value = nil) _log.info "#{property} was NOT set due to blank values" end end + + def userdata_payload + return nil unless customization_template + + options = prepare_customization_template_substitution_options + customization_template.script_with_substitution(options) + end end diff --git a/app/models/manageiq/providers/vmware/infra_manager/provision_workflow.rb b/app/models/manageiq/providers/vmware/infra_manager/provision_workflow.rb index 4e1773616..696c5c5b9 100644 --- a/app/models/manageiq/providers/vmware/infra_manager/provision_workflow.rb +++ b/app/models/manageiq/providers/vmware/infra_manager/provision_workflow.rb @@ -1,4 +1,5 @@ class ManageIQ::Providers::Vmware::InfraManager::ProvisionWorkflow < ManageIQ::Providers::InfraManager::ProvisionWorkflow + include CloudInitTemplateMixin include DialogFieldValidation def self.default_dialog_file @@ -17,6 +18,13 @@ def supports_pxe? get_value(@values[:provision_type]).to_s == 'pxe' end + def supports_cloud_init? + ems_id = get_value(values[:src_ems_id]) + ems = ExtManagementSystem.find(ems_id) if ems_id + + ems&.api_version && Gem::Version.new(ems&.api_version) >= Gem::Version.new('7.0.3') + end + def dialog_name_from_automate(message = 'get_dialog_name') super(message, {'platform' => 'vmware'}) end @@ -173,6 +181,12 @@ def allowed_storage_profiles(_options = {}) end end + def allowed_customization_templates(options = {}) + return [] unless supports_cloud_init? + + allowed_cloud_init_customization_templates(options) + end + def set_on_vm_id_changed super @filters[:StorageProfile] = nil diff --git a/content/miq_dialogs/miq_provision_vmware_dialogs_clone_to_vm.yaml b/content/miq_dialogs/miq_provision_vmware_dialogs_clone_to_vm.yaml index c48939195..ccf926b55 100644 --- a/content/miq_dialogs/miq_provision_vmware_dialogs_clone_to_vm.yaml +++ b/content/miq_dialogs/miq_provision_vmware_dialogs_clone_to_vm.yaml @@ -240,6 +240,14 @@ :display: :edit :default: false :data_type: :boolean + :customization_template_id: + :values_from: + :method: :allowed_customization_templates + :auto_select_single: false + :description: Script Name + :required: false + :display: :edit + :data_type: :integer :addr_mode: :values: static: Static diff --git a/spec/models/manageiq/providers/vmware/infra_manager/provision_workflow_spec.rb b/spec/models/manageiq/providers/vmware/infra_manager/provision_workflow_spec.rb index 90112d93e..53a2b90b6 100644 --- a/spec/models/manageiq/providers/vmware/infra_manager/provision_workflow_spec.rb +++ b/spec/models/manageiq/providers/vmware/infra_manager/provision_workflow_spec.rb @@ -147,6 +147,73 @@ end end + context '#supports_cloud_init?' do + let(:ems) { FactoryBot.create(:ems_vmware_with_authentication, :api_version => api_version) } + let(:template) { FactoryBot.create(:template_vmware, :ext_management_system => ems) } + before do + workflow.instance_variable_set(:@values, :src_vm_id => template.id, :src_ems_id => ems.id) + end + + context "with a 7.0.0 vcenter" do + let(:api_version) { "7.0.0" } + + it "returns not supported" do + expect(workflow.supports_cloud_init?).to be_falsey + end + end + + context "with a 7.0.3 vcenter" do + let(:api_version) { "7.0.3" } + + it "returns supported" do + expect(workflow.supports_cloud_init?).to be_truthy + end + end + end + + context '#allowed_customization_templates' do + let(:ems) { FactoryBot.create(:ems_vmware_with_authentication, :api_version => api_version) } + let(:template) { FactoryBot.create(:template_vmware, :ext_management_system => ems) } + before do + workflow.instance_variable_set(:@values, :src_vm_id => template.id, :src_ems_id => ems.id) + end + + context "with a 7.0.0 vcenter" do + let(:api_version) { "7.0.0" } + + it "returns an empty array" do + expect(workflow.allowed_customization_templates).to be_empty + end + end + + context "with a 7.0.3 vcenter" do + let(:api_version) { "7.0.3" } + + context "with no cloud-init customizaion templates" do + let!(:kickstart_template) { FactoryBot.create(:customization_template_kickstart) } + + it "returns an empty array" do + expect(workflow.allowed_customization_templates).to be_empty + end + end + + context "with a cloud-init customization template" do + let!(:cloud_init_template) { FactoryBot.create(:customization_template_cloud_init) } + + it "returns an the template" do + expect(workflow.allowed_customization_templates.count).to eq(1) + + template = workflow.allowed_customization_templates.first + expect(template).to have_attributes( + :evm_object_class => :CustomizationTemplate, + :id => cloud_init_template.id, + :name => cloud_init_template.name + ) + end + end + end + end + context '#set_on_vm_id_changed' do before(:each) do workflow.instance_variable_set(:@filters, :Host => {21 => "ESX 6.0"}, :StorageProfile => {1 => "Tag 1"})