diff --git a/app/helpers/request_info_helper.rb b/app/helpers/request_info_helper.rb index b3bc5b62621..b65c0a111c4 100644 --- a/app/helpers/request_info_helper.rb +++ b/app/helpers/request_info_helper.rb @@ -1,4 +1,8 @@ module RequestInfoHelper + include RequestInfoTabsHelper::RequestInfoServiceHelper + include RequestInfoTabsHelper::RequestInfoEnvironmentHelper + include RequestInfoTabsHelper::RequestInfoHardwareHelper + private PROV_FIELD_TYPES = [:vm, :host, :ds, :template, :vc, :pxe_img, :iso_img, :window_image].freeze @@ -9,7 +13,65 @@ def provision_tab_configuration(workflow) prov_tab_labels = workflow.provisioning_tab_list.map do |dialog| {:name => dialog[:name], :text => dialog[:description]} end - return prov_tab_labels, workflow.get_dialog_order + prov_tab_conditions = prov_tab_keys(workflow) + return prov_tab_labels, workflow.get_dialog_order, prov_tab_conditions + end + + def prov_tab_keys(workflow) + tab_keys = [] + workflow.get_dialog_order.map do |name| + tab_keys.push({name.to_sym => service_keys(workflow)}) if name.to_sym == :service + tab_keys.push({name.to_sym => environment_keys(workflow)}) if name.to_sym == :environment + tab_keys.push({name.to_sym => hardware_keys(workflow)}) if name.to_sym == :hardware + end + return tab_keys + end + + def is_credential_key(key) + [:allocated_disk_storage, :cpu_limit, :cpu_reserve, :entitled_processors, :dns_servers, :dns_suffixes, :gateway, + :hostname, :ip_addr, :linux_host_name, :linux_domain_name, + :mac_address, :owner_address, :owner_city, :owner_company, + :owner_country, :owner_department, :owner_email, + :owner_first_name, :owner_last_name, :owner_load_ldap, + :owner_office, :owner_manager, :owner_manager_mail, + :owner_manager_phone, :owner_phone, :owner_phone_mobile, + :owner_state, :owner_title, :owner_zip, :request_notes, + :subnet_mask, :memory_limit, :memory_reserve, + :root_username, :root_password, :ssh_public_key, :sysprep_password, :sysprep_domain_admin, + :sysprep_domain_password, :sysprep_workgroup_name, + :sysprep_full_name, :sysprep_organization, + :sysprep_product_id, :sysprep_computer_name, + :sysprep_per_server_max_connections, :vm_description, + :vm_name, :wins_servers, :sysprep_domain, + :sysprep_admin_password, :sysprep_product_key, :sysprep_locale_ui, + :sysprep_locale_input, :sysprep_locale_system, :sysprep_locale_user, + :sysprep_machine_object_ou].include?(key) + end + + def is_field_checkbox(key) + [:linked_clone, :migratable, :placement_auto, :stateless, :sysprep_auto_logon, :sysprep_change_sid, :seal_template, + :sysprep_delete_accounts, :sysprep_spec_override, :vm_auto_start, :vm_dynamic_memory, :is_preemptible, :public_network, + :cpu_hot_add, :cpu_hot_remove, :memory_hot_add].include?(key) + end + + def is_field_radio(key) + [:addr_mode, :disk_format, :sysprep_identification, :schedule_type, :cloud_network_selection_method, :disk_sparsity].include?(field) + end + + def prov_tab_fields(keys, workflow, tabKey) + rows = [] + if keys.any? + keys.each do |key| + field_hash = workflow.get_field(key, tabKey) + if !field_hash.blank? && field_hash[:display] && field_hash[:display].to_s != "hide" + field_id = tabKey.to_s + "__" + key.to_s + value = {:key => key, :label => field_hash[:description]} + value[:input] = {:input => "checkbox", :name => "display", :checked => false, :disabled => true, :label => ''} if is_field_checkbox(key) + rows.push(value) + end + end + end + return rows end def display_prov_grid(field) diff --git a/app/helpers/request_info_tabs_helper/request_info_environment_helper.rb b/app/helpers/request_info_tabs_helper/request_info_environment_helper.rb new file mode 100644 index 00000000000..179efbf14df --- /dev/null +++ b/app/helpers/request_info_tabs_helper/request_info_environment_helper.rb @@ -0,0 +1,31 @@ +module RequestInfoTabsHelper::RequestInfoEnvironmentHelper + ENV_KEYS = { + :placement => [:placement_auto], + :data_center => [:placement_dc_name], + :cluster => [:cluster_filter, :placement_cluster_name], + :resource_pool => [:rp_filter, :placement_rp_name], + :folder => [:placement_folder_name], + :host => [:host_filter, :placement_host_name], + :datastore => [:ds_filter, :placement_storage_profile, :placement_ds_name], + :placement_options => [ + :cloud_tenant, :availability_zone_filter, :placement_availability_zone, :cloud_network_selection_method, :cloud_subnet, :security_groups, :floating_ip_address, :resource_group, :public_network + ], + :cloud_network => [:cloud_network], + :network_port => [:network_port] + }.freeze + + def environment_placement(wf) + { + :title => _('Placement'), + :rows => environment_prov_tab_fields(ENV_KEYS[:placement], wf), + } + end + + def environment_prov_tab_fields(keys, wf) + prov_tab_fields(keys, wf, :environment) + end + + def environment_keys(wf) + [environment_placement(wf)] + end +end diff --git a/app/helpers/request_info_tabs_helper/request_info_hardware_helper.rb b/app/helpers/request_info_tabs_helper/request_info_hardware_helper.rb new file mode 100644 index 00000000000..1cc95f4f089 --- /dev/null +++ b/app/helpers/request_info_tabs_helper/request_info_hardware_helper.rb @@ -0,0 +1,68 @@ +module RequestInfoTabsHelper::RequestInfoHardwareHelper + HARDWARE_KEYS = { + :hardware_properties => [ + :instance_type, :sys_type, :cloud_volumes, :storage_type, :number_of_cpus, :entitled_processors, :number_of_sockets, :cores_per_socket, :vm_memory, :network_adapters, :disk_format, :allocated_disk_storage, :disk_sparsity, :guest_access_key_pair, :monitoring, + :vm_dynamic_memory, :vm_minimum_memory, :vm_maximum_memory, :boot_disk_size, :is_preemptible, + :cpu_hot_add, :cpu_hot_remove, :memory_hot_add, :ssh_public_key + ], + :vm_limits => [:cpu_limit, :memory_limit], + :vm_reservations => [:cpu_reserve, :memory_reserve], + + }.freeze + + def hardware_properties(cloud_manager, workflow) + { + :title => cloud_manager ? _("Properties") : _("Hardware"), + :rows => hardware_prov_tab_fields(:hardware_properties, workflow), + } + end + + def hardware_vm_limit(workflow) + { + :title => _("VM Limits"), + :rows => hardware_prov_tab_fields(:vm_limits, workflow), + } + end + + def hardware_vm_reservations(workflow) + { + :title => _("VM Reservations"), + :rows => hardware_prov_tab_fields(:vm_reservations, workflow), + } + end + + def hardware_cloud_quota + { + :title => _("Cloud Quota - move to a new component if possible"), + :rows => [ + {:key => :cloud_tenant, :label => _("Cloud Tenant")}, + {:key => :instance_type, :label => _("Instance Type")}, + ], + } + end + + + def hardware_prov_tab_fields(key, workflow) + prov_tab_fields(HARDWARE_KEYS[key], workflow, :hardware) + end + + def hardware_conditions(workflow) + { + :is_cloud_manager => workflow.kind_of?(ManageIQ::Providers::CloudManager::ProvisionWorkflow), + :is_open_stack => workflow.kind_of?(ManageIQ::Providers::Openstack::CloudManager::ProvisionWorkflow) + } + end + + def hardware_keys(workflow) + condition = hardware_conditions(workflow) + data = [hardware_properties(condition[:is_cloud_manager], workflow)] + unless condition[:is_cloud_manager] + data.push(hardware_vm_limit(workflow)) + data.push(hardware_vm_reservations(workflow)) + end + if condition[:is_open_stack] + data.push(hardware_cloud_quota) + end + data + end +end diff --git a/app/helpers/request_info_tabs_helper/request_info_service_helper.rb b/app/helpers/request_info_tabs_helper/request_info_service_helper.rb new file mode 100644 index 00000000000..8d4e5e714cc --- /dev/null +++ b/app/helpers/request_info_tabs_helper/request_info_service_helper.rb @@ -0,0 +1,123 @@ +module RequestInfoTabsHelper::RequestInfoServiceHelper + SERVICE_KEYS = { + :selected_vms => [:src_vm_id, :provision_type, :linked_clone, :seal_template], + :select => [:vm_filter, :src_vm_id, :provision_type, :linked_clone, :snapshot], + :supports_pxe => [:pxe_server_id, :pxe_image_id, :windows_image_id], + :supports_iso => [:iso_image_id], + :number_of_vms => [:number_of_vms], + :naming => [:vm_name, :vm_description, :vm_prefix], + }.freeze + + REQUEST_KEYS = { + :request_information => [ + :owner_email, :owner_first_name, :owner_last_name, :owner_address, :owner_city, :owner_state, :owner_zip, :owner_country, :owner_title, :owner_company, :owner_department, :owner_office, :owner_phone, :owner_phone_mobile, :request_notes + ], + :manager => [:owner_manager, :owner_manager_mail, :owner_manager_phone], + }.freeze + + PURPOSE_KEYS = { + :tags => [:vm_tags], + }.freeze + + # VOLUME_KEYS = { + # workflow.volume_dialog_keys + # } + + NETWORK_KEYS = { + :network_adapter => [:vlan, :mac_address, :public_network], + }.freeze + + CUSTOMIZE_KEYS = { + :compute_details => [:sysprep_admin_password, :sysprep_computer_name, :sysprep_organization, :sysprep_product_key], + :credentials => [:root_password, :root_username], + :customize_template => [:customization_template_id], + :custom_specification => [:sysprep_custom_spec, :sysprep_spec_override], + :custom_specification_2 => [:sysprep_custom_spec], + :dns => [:dns_servers, :dns_suffixes], + :domain_information => [:sysprep_domain, :sysprep_domain_admin, :sysprep_domain_password, :sysprep_machine_object_ou], + :domain_information_2 => [:sysprep_domain_admin, :sysprep_domain_name, :sysprep_domain_password], + :identification => [:sysprep_identification], + :ip_address => [:addr_mode, :gateway, :hostname, :ip_addr, :subnet_mask], + :ip_address_2 => [:addr_mode, :gateway, :ip_addr, :subnet_mask], + :localization => [:sysprep_locale_input, :sysprep_locale_system, :sysprep_locale_ui, :sysprep_timezone], + :naming => [:linux_domain_name, :linux_host_name], + :others => [:migratable, :pin_policy], + :placement_group => [:placement_group], + :selected_template => [:customization_template_script], + :server_licences => [:sysprep_per_server_max_connections, :sysprep_server_license_mode], + :shared_processor_pool => [:shared_processor_pool], + :unattended_gui => [:sysprep_auto_logon, :sysprep_auto_logon_count, :sysprep_password, :sysprep_timezone], + :upload_file => [:sysprep_upload_file], + :upload_file_2 => [:user_script], + :upload_text => [:sysprep_upload_text], + :user_data => [:sysprep_computer_name, :sysprep_full_name, :sysprep_organization, :sysprep_product_id], + :user_script_text => [:user_script_text], + :windows_options => [:sysprep_change_sid, :sysprep_delete_accounts], + :wins_server => [:wins_servers], + }.freeze + + def service_selected_vms(workflow) + { + :title => _('Selected VM'), + :rows => service_prov_tab_fields(:selected_vms, workflow), + } + end + + def service_select(workflow) + { + :title => _('Select'), + :rows => service_prov_tab_fields(:select, workflow), + } + end + + def service_supports_pxe(workflow) + { + :title => _('PXE'), + :rows => service_prov_tab_fields(:supports_pxe, workflow), + } + end + + def service_supports_iso(workflow) + { + :title => _('ISO'), + :rows => service_prov_tab_fields(:supports_iso, workflow), + } + end + + def service_cloud_manager(cloud_manager, workflow) + { + :title => cloud_manager ? _('Number of Instances') : _('Number of VMs'), + :rows => service_prov_tab_fields(:number_of_vms, workflow), + } + end + + def service_naming(workflow) + { + :title => _('Naming'), + :rows => service_prov_tab_fields(:naming, workflow), + } + end + + def service_prov_tab_fields(key, workflow) + prov_tab_fields(SERVICE_KEYS[key], workflow, :service) + end + + def service_conditions(workflow) + { + :is_ovirt => workflow.kind_of?(ManageIQ::Providers::Ovirt::InfraManager::ProvisionWorkflow), + :supports_pxe => workflow.supports_pxe?, + :supports_iso => workflow.supports_iso?, + :is_cloud_manager => workflow.kind_of?(ManageIQ::Providers::CloudManager::ProvisionWorkflow), + } + end + + def service_keys(workflow) + condition = service_conditions(workflow) + data = [condition[:is_ovirt] ? service_selected_vms(workflow) : service_select(workflow)] + data.push(service_supports_pxe(workflow)) if condition[:supports_pxe] + data.push(service_supports_iso(workflow)) if condition[:supports_iso] + data.push(service_cloud_manager(condition[:is_cloud_manager], workflow)) + data.push(service_naming(workflow)) + data + end +end diff --git a/app/javascript/components/catalog-item-request-info/helper.js b/app/javascript/components/catalog-item-request-info/helper.js new file mode 100644 index 00000000000..30ae25a0211 --- /dev/null +++ b/app/javascript/components/catalog-item-request-info/helper.js @@ -0,0 +1,39 @@ +// const serviceSelectedVms = { +// label: __('Selected VM'), +// keys: ['src_vm_id', 'provision_type', 'linked_clone', 'seal_template'], +// }; + +// const serviceSelect = { +// label: __('Select'), +// keys: ['vm_filter', 'src_vm_id', 'provision_type', 'linked_clone', 'snapshot'], +// }; + +// const serviceSupportsPxe = { +// label: __('PXE'), +// keys: ['pxe_server_id', 'pxe_image_id', 'windows_image_id'], +// }; + +// const serviceSupportsIso = { +// label: __('ISO'), +// keys: ['iso_image_id'], +// }; + +// const serviceCloudManager = (cloudManager) => ({ +// label: cloudManager ? __('Number of Instances') : __('Number of VMs'), +// keys: ['number_of_vms'], +// }); + +// const serviceNaming = { +// label: __('Naming'), +// keys: ['vm_name', 'vm_description', 'vm_prefix'], +// }; + +// export const serviceKeys = (item) => { +// const serviceData = []; +// serviceData.push(item.isOvirtInfraManager ? serviceSelectedVms : serviceSelect); +// if (item.supportsPxe) serviceData.push(serviceSupportsPxe); +// if (item.supportsIso) serviceData.push(serviceSupportsIso); +// serviceData.push(serviceCloudManager(item.cloudManager)); +// serviceData.push(serviceNaming); +// return serviceData; +// }; diff --git a/app/javascript/components/catalog-item-request-info/index.jsx b/app/javascript/components/catalog-item-request-info/index.jsx new file mode 100644 index 00000000000..09099ec9fcd --- /dev/null +++ b/app/javascript/components/catalog-item-request-info/index.jsx @@ -0,0 +1,121 @@ +/* eslint-disable camelcase */ +/* eslint-disable no-prototype-builtins */ +import React, { useEffect, useState } from 'react'; +import PropTypes from 'prop-types'; +import { Tabs, Tab, Loading } from 'carbon-components-react'; +import MiqStructuredList from '../miq-structured-list'; + +const CatalogItemRequestInfo = ({ recordId, tabLabels, tabConditions }) => { + console.log('tabLabels=', tabLabels); + console.log('tabConditions=', tabConditions); + + const [data, setData] = useState({ + isLoading: true, + tabContents: undefined, + currentTab: tabLabels ? tabLabels[0].name : undefined, + }); + + useEffect(() => { + if (recordId) { + API.get(`/api/service_templates/${recordId}?expand=resources`).then(({ config_info }) => { + tabConditions.forEach((tabKey) => { + Object.values(tabKey).forEach((items) => { + items.forEach((item) => { + item.rows.forEach((row) => { + console.log(row.key); + row.value = row.input ? row.input : config_info[row.key]; + }); + }); + }); + }); + setData({ + ...data, + isLoading: false, + tabContents: tabConditions, + }); + }); + } + }, [recordId]); + + const checkType = (data) => { + if (Array.isArray(data)) { + return data[1]; + } if (typeof data === 'object' && data !== null) { + return data; + } if (typeof data === 'string') { + return data; + } if (typeof data === 'number') { + return data.toString(); + } + return data; + }; + + const rowData = (rows) => rows.map((row) => ({ label: row.label, value: checkType(row.value) })); + + /** Function to render the tab contents */ + const renderTabContent = (name) => { + if (data.isLoading) { + return ( +