diff --git a/playbooks/run_migration_from_conversion_host.yml b/playbooks/run_migration_from_conversion_host.yml index a655833a..b8c8cdad 100644 --- a/playbooks/run_migration_from_conversion_host.yml +++ b/playbooks/run_migration_from_conversion_host.yml @@ -27,3 +27,4 @@ vars: flavor_name_or_uuid: "{{ data.openstack.flavor_name_or_uuid }}" vm_name: "{{ data.vm_name }}" + vm_dest_name: "{{ data.vm_dest_name | default('') }}" diff --git a/plugins/modules/src/create_network_port/create_network_port.go b/plugins/modules/src/create_network_port/create_network_port.go index e79e959f..367c20fa 100644 --- a/plugins/modules/src/create_network_port/create_network_port.go +++ b/plugins/modules/src/create_network_port/create_network_port.go @@ -31,6 +31,9 @@ type ModuleArgs struct { Cloud osm_os.DstCloud `json:"cloud"` OsMigrateNicsFilePath string `json:"os_migrate_nics_file_path"` VmName string `json:"vm_name"` + // DestName is an optional override for port naming. + // When provided it is used instead of SafeVmName(VmName). + DestName string `json:"destname"` UsedMappedNetworks bool `json:"used_mapped_networks"` SecurityGroups []string `json:"security_groups"` NetworkName string `json:"network_name"` @@ -181,7 +184,11 @@ func main() { } } } - portName := fmt.Sprintf("%s-NIC-%d-VLAN-%s", moduleArgs.VmName, nicIndex, nic.Vlan) + portBaseName := moduleArgs.VmName + if moduleArgs.DestName != "" { + portBaseName = moduleArgs.DestName + } + portName := fmt.Sprintf("%s-NIC-%d-VLAN-%s", portBaseName, nicIndex, nic.Vlan) port, err := osm_os.CreatePort(provider, portName, network.ID, nic.Mac, nic.Subnet, moduleArgs.SecurityGroups, nic.FixedIPs) if err != nil { diff --git a/plugins/modules/src/create_server/create_server.go b/plugins/modules/src/create_server/create_server.go index 44e65dbd..d7f569c8 100644 --- a/plugins/modules/src/create_server/create_server.go +++ b/plugins/modules/src/create_server/create_server.go @@ -20,6 +20,7 @@ import ( "context" "encoding/json" "os" + moduleutils "vmware-migration-kit/plugins/module_utils" "vmware-migration-kit/plugins/module_utils/ansible" "vmware-migration-kit/plugins/module_utils/logger" osm_os "vmware-migration-kit/plugins/module_utils/openstack" @@ -62,6 +63,10 @@ type ModuleArgs struct { Cloud osm_os.DstCloud `json:"cloud"` State string `json:"state"` Name string `json:"name"` + // DestName is an optional override for the OpenStack instance name. + // When provided it is used as-is, bypassing SafeVmName sanitisation. + // When absent, SafeVmName(Name) is used (default behaviour). + DestName string `json:"destname"` Nics []interface{} `json:"nics"` BootVolume string `json:"boot_volume"` Volumes []string `json:"volumes"` @@ -80,6 +85,14 @@ type ModuleResponse struct { ID string `json:"id"` } +// resolveInstanceName returns DestName if set, otherwise SafeVmName(Name). +func resolveInstanceName(args ModuleArgs) string { + if args.DestName != "" { + return args.DestName + } + return moduleutils.SafeVmName(args.Name) +} + func success(changed bool, id string) { res := ModuleResponse{ Changed: changed, @@ -153,7 +166,7 @@ func main() { } ServerAgrs := osm_os.ServerArgs{ - Name: moduleArgs.Name, + Name: resolveInstanceName(moduleArgs), Flavor: moduleArgs.Flavor, BootVolume: moduleArgs.BootVolume, SecurityGroups: moduleArgs.SecurityGroups, @@ -172,7 +185,7 @@ func main() { } ServerAgrs := osm_os.ServerArgs{ - Name: moduleArgs.Name, + Name: resolveInstanceName(moduleArgs), Flavor: moduleArgs.Flavor, BootVolume: moduleArgs.BootVolume, SecurityGroups: moduleArgs.SecurityGroups, diff --git a/plugins/modules/src/migrate/migrate.go b/plugins/modules/src/migrate/migrate.go index f12500b5..8ac45720 100644 --- a/plugins/modules/src/migrate/migrate.go +++ b/plugins/modules/src/migrate/migrate.go @@ -69,6 +69,9 @@ type MigrationConfig struct { Server string Libdir string VmName string + // DestName is the optional destination name used for Cinder volume naming. + // If empty, SafeVmName(VmName) is used instead (default behaviour). + DestName string VolumeAz string VolumeType string AssumeZero bool @@ -104,6 +107,10 @@ type ModuleArgs struct { Server string Libdir string VmName string + // DestName is the optional destination name used for Cinder volume naming. + // When provided, it replaces SafeVmName(VmName) for resource naming while + // VmName continues to be used to locate the VM in vCenter. + DestName string `json:"destname"` VolumeAz string VolumeType string VolumeTypeMapping []VolumeTypeMapping `json:"volume_type_mapping"` @@ -127,6 +134,16 @@ type ModuleArgs struct { ExtraOpts string } +// resourceName returns the name to use when creating OpenStack resources +// (Cinder volumes). If DestName is set it is used as-is; otherwise the +// VMware VM name is sanitised with SafeVmName. +func (c *MigrationConfig) resourceName(vmName string) string { + if c.DestName != "" { + return c.DestName + } + return moduleutils.SafeVmName(vmName) +} + func (c *MigrationConfig) VMMigration(parentCtx context.Context, runV2V bool) (string, error) { syncVol := false ctx, cancel := context.WithCancel(context.Background()) @@ -144,7 +161,7 @@ func (c *MigrationConfig) VMMigration(parentCtx context.Context, runV2V bool) (s return "", err } diskNameStr := strconv.Itoa(int(c.NbdkitConfig.VddkConfig.DiskKey)) - volume, err := osm_os.GetVolumeID(c.OSClient, vmName, diskNameStr) + volume, err := osm_os.GetVolumeID(c.OSClient, c.resourceName(vmName), diskNameStr) if err != nil { logger.Log.Infof("Failed to get volume: %v", err) return "", err @@ -223,7 +240,7 @@ func (c *MigrationConfig) VMMigration(parentCtx context.Context, runV2V bool) (s // volumeMetadata["hw_scsi_model"] = "virtio-scsi" // } volOpts := osm_os.VolOpts{ - Name: vmName + "-" + diskNameStr, + Name: c.resourceName(vmName) + "-" + diskNameStr, Size: int(diskSize[diskNameStr] / 1024 / 1024), VolumeType: c.VolumeType, AvailabilityZone: c.VolumeAz, @@ -418,6 +435,7 @@ func main() { password := ansible.RequireField(moduleArgs.Password, "Password is required") server := ansible.RequireField(moduleArgs.Server, "Server is required") vmname := ansible.RequireField(moduleArgs.VmName, "VM name is required") + destname := moduleArgs.DestName libdir := ansible.DefaultIfEmpty(moduleArgs.Libdir, "/usr/lib/vmware-vix-disklib") vddkpath := ansible.DefaultIfEmpty(moduleArgs.VddkPath, "/ha-datacenter/vm/") osmdatadir := ansible.DefaultIfEmpty(moduleArgs.OSMDataDir, "/tmp/") @@ -447,8 +465,13 @@ func main() { response.Msg = "Failed to generate random string" ansible.FailJson(response) } + // Use destname for the log file name if provided, otherwise use the sanitised VM name safeVmName := moduleutils.SafeVmName(vmname) - LogFile := "/tmp/osm-nbdkit-" + safeVmName + "-" + r + ".log" + logBaseName := safeVmName + if destname != "" { + logBaseName = destname + } + LogFile := "/tmp/osm-nbdkit-" + logBaseName + "-" + r + ".log" logger.InitLogger(LogFile) ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -536,6 +559,7 @@ func main() { HostPool: hostPool, }, ManageExtVol: externalVolume, + DestName: destname, OSMDataDir: osmdatadir, OSClient: provider, CBTSync: cbtsync, diff --git a/roles/convert_metadata/tasks/main.yml b/roles/convert_metadata/tasks/main.yml index c2b1dc16..2db2d05b 100644 --- a/roles/convert_metadata/tasks/main.yml +++ b/roles/convert_metadata/tasks/main.yml @@ -56,6 +56,7 @@ content: | { "vm_name": "{{ vm_import.vm_name }}", + "vm_dest_name": "{{ vm_import.vm_dest_name | default('') }}", "openstack": {{ vm_import.openstack | to_json }}, "vmware_guest_info": {{ guest_info | combine(vm_import.vmware_guest_info) | to_json }}, "migration": {{ vm_import.migration | to_json }} diff --git a/roles/convert_metadata/templates/import_workloads.json.j2 b/roles/convert_metadata/templates/import_workloads.json.j2 index f7a1390e..1f4b4388 100644 --- a/roles/convert_metadata/templates/import_workloads.json.j2 +++ b/roles/convert_metadata/templates/import_workloads.json.j2 @@ -1,5 +1,6 @@ { "vm_name": "{{ vm_name }}", + "vm_dest_name": "{{ vm_dest_name | default('') }}", "openstack": { "flavor_name_or_uuid": "{{ flavor_name_or_uuid }}", "openstack_private_network": "", diff --git a/roles/import_workloads/tasks/create_network_port.yml b/roles/import_workloads/tasks/create_network_port.yml index accc5342..c7346528 100644 --- a/roles/import_workloads/tasks/create_network_port.yml +++ b/roles/import_workloads/tasks/create_network_port.yml @@ -7,6 +7,7 @@ cloud: "{{ dst_cloud }}" os_migrate_nics_file_path: "{{ os_migrate_vmw_data_dir }}/{{ vm_name }}/nics.json" vm_name: "{{ vm_name }}" + destname: "{{ vm_dest_name | default('') }}" used_mapped_networks: true security_groups: ["{{ security_groups | default('default') }}"] use_fixed_ips: "{{ import_workloads_use_fixed_ips | default(false) | bool }}" @@ -27,6 +28,7 @@ cloud: "{{ dst_cloud }}" os_migrate_nics_file_path: "{{ os_migrate_vmw_data_dir }}/{{ vm_name }}/macs.json" vm_name: "{{ vm_name }}" + destname: "{{ vm_dest_name | default('') }}" used_mapped_networks: false security_groups: ["{{ security_groups | default('default') }}"] network_name: "{{ openstack_private_network }}" @@ -39,3 +41,4 @@ ansible.builtin.set_fact: nics: "{{ ports_uuid.ports | default([]) }}" when: os_migrate_create_network_port|default(true)|bool + diff --git a/roles/import_workloads/tasks/create_os_instance.yml b/roles/import_workloads/tasks/create_os_instance.yml index 1035a080..616ac5ba 100644 --- a/roles/import_workloads/tasks/create_os_instance.yml +++ b/roles/import_workloads/tasks/create_os_instance.yml @@ -15,14 +15,14 @@ - name: Get volume information for virt-v2v os_migrate.vmware_migration_kit.volume_info: cloud: "{{ dst_cloud }}" - name: "{{ vm_name }}-sda" + name: "{{ vm_dest_name | default(vm_name) }}-sda" register: volume_result when: import_workloads_os_migrate_virt_v2v - name: Get volume information for Cinder boot os_migrate.vmware_migration_kit.volume_info: cloud: "{{ dst_cloud }}" - name: "{{ vm_name }}" + name: "{{ vm_dest_name | default(vm_name) }}" register: cinder_volume_result when: import_workloads_boot_from_cinder @@ -71,6 +71,7 @@ cloud: "{{ dst_cloud }}" state: "present" name: "{{ vm_name }}" + destname: "{{ vm_dest_name | default('') }}" nics: "{{ nics }}" volumes: "{{ volumes_list }}" boot_volume: "{{ boot_volume_uuid }}" diff --git a/roles/import_workloads/tasks/nbdkit.yml b/roles/import_workloads/tasks/nbdkit.yml index 0853e03a..0df66acd 100644 --- a/roles/import_workloads/tasks/nbdkit.yml +++ b/roles/import_workloads/tasks/nbdkit.yml @@ -65,6 +65,7 @@ password: "{{ vcenter_password }}" server: "{{ vcenter_hostname }}" vmname: "{{ vm_name }}" + destname: "{{ vm_dest_name | default('') }}" volumeaz: "{{ import_workloads_cinder_az | default(omit) }}" volumetype: "{{ import_workloads_cinder_volume_type | default(omit) }}" assumezero: "{{ import_workloads_nbdkit_assume_zero | bool }}"