Skip to content

Commit 87ee866

Browse files
authored
ui: vmware vm import-unmanage (#5075)
Adds UI for importing and unmanaging VMs. A new navigation section - Tools has been added in the UI. Doc PR: apache/cloudstack-documentation#221 Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
1 parent 37f3fc3 commit 87ee866

File tree

20 files changed

+2246
-127
lines changed

20 files changed

+2246
-127
lines changed

api/src/main/java/org/apache/cloudstack/api/response/UnmanagedInstanceResponse.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ public class UnmanagedInstanceResponse extends BaseResponse {
4343
@Param(description = "the ID of the host to which virtual machine belongs")
4444
private String hostId;
4545

46+
@SerializedName(ApiConstants.HOST_NAME)
47+
@Param(description = "the name of the host to which virtual machine belongs")
48+
private String hostName;
49+
4650
@SerializedName(ApiConstants.POWER_STATE)
4751
@Param(description = "the power state of the virtual machine")
4852
private String powerState;
@@ -108,6 +112,14 @@ public void setHostId(String hostId) {
108112
this.hostId = hostId;
109113
}
110114

115+
public String getHostName() {
116+
return hostName;
117+
}
118+
119+
public void setHostName(String hostName) {
120+
this.hostName = hostName;
121+
}
122+
111123
public String getPowerState() {
112124
return powerState;
113125
}

server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,6 @@
2525

2626
import javax.inject.Inject;
2727

28-
import com.cloud.agent.api.PrepareUnmanageVMInstanceAnswer;
29-
import com.cloud.agent.api.PrepareUnmanageVMInstanceCommand;
30-
import com.cloud.event.ActionEvent;
31-
import com.cloud.exception.UnsupportedServiceException;
32-
import com.cloud.storage.Snapshot;
33-
import com.cloud.storage.SnapshotVO;
34-
import com.cloud.storage.dao.SnapshotDao;
35-
import com.cloud.vm.NicVO;
36-
import com.cloud.vm.UserVmVO;
37-
import com.cloud.vm.dao.UserVmDao;
38-
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
3928
import org.apache.cloudstack.api.ApiConstants;
4029
import org.apache.cloudstack.api.ApiErrorCode;
4130
import org.apache.cloudstack.api.ResponseGenerator;
@@ -59,12 +48,15 @@
5948
import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
6049
import org.apache.commons.collections.CollectionUtils;
6150
import org.apache.commons.collections.MapUtils;
51+
import org.apache.commons.lang3.StringUtils;
6252
import org.apache.log4j.Logger;
6353

6454
import com.cloud.agent.AgentManager;
6555
import com.cloud.agent.api.Answer;
6656
import com.cloud.agent.api.GetUnmanagedInstancesAnswer;
6757
import com.cloud.agent.api.GetUnmanagedInstancesCommand;
58+
import com.cloud.agent.api.PrepareUnmanageVMInstanceAnswer;
59+
import com.cloud.agent.api.PrepareUnmanageVMInstanceCommand;
6860
import com.cloud.capacity.CapacityManager;
6961
import com.cloud.configuration.Config;
7062
import com.cloud.configuration.Resource;
@@ -75,6 +67,7 @@
7567
import com.cloud.deploy.DeployDestination;
7668
import com.cloud.deploy.DeploymentPlanner;
7769
import com.cloud.deploy.DeploymentPlanningManager;
70+
import com.cloud.event.ActionEvent;
7871
import com.cloud.event.EventTypes;
7972
import com.cloud.event.UsageEventUtils;
8073
import com.cloud.exception.InsufficientAddressCapacityException;
@@ -83,6 +76,7 @@
8376
import com.cloud.exception.InvalidParameterValueException;
8477
import com.cloud.exception.PermissionDeniedException;
8578
import com.cloud.exception.ResourceAllocationException;
79+
import com.cloud.exception.UnsupportedServiceException;
8680
import com.cloud.host.Host;
8781
import com.cloud.host.HostVO;
8882
import com.cloud.host.Status;
@@ -103,6 +97,8 @@
10397
import com.cloud.service.dao.ServiceOfferingDao;
10498
import com.cloud.storage.GuestOS;
10599
import com.cloud.storage.GuestOSHypervisor;
100+
import com.cloud.storage.Snapshot;
101+
import com.cloud.storage.SnapshotVO;
106102
import com.cloud.storage.StoragePool;
107103
import com.cloud.storage.VMTemplateStoragePoolVO;
108104
import com.cloud.storage.VMTemplateVO;
@@ -112,6 +108,7 @@
112108
import com.cloud.storage.dao.DiskOfferingDao;
113109
import com.cloud.storage.dao.GuestOSDao;
114110
import com.cloud.storage.dao.GuestOSHypervisorDao;
111+
import com.cloud.storage.dao.SnapshotDao;
115112
import com.cloud.storage.dao.VMTemplateDao;
116113
import com.cloud.storage.dao.VMTemplatePoolDao;
117114
import com.cloud.storage.dao.VolumeDao;
@@ -127,15 +124,19 @@
127124
import com.cloud.utils.net.NetUtils;
128125
import com.cloud.vm.DiskProfile;
129126
import com.cloud.vm.NicProfile;
127+
import com.cloud.vm.NicVO;
130128
import com.cloud.vm.UserVmManager;
129+
import com.cloud.vm.UserVmVO;
131130
import com.cloud.vm.VMInstanceVO;
132131
import com.cloud.vm.VirtualMachine;
133132
import com.cloud.vm.VirtualMachineManager;
134133
import com.cloud.vm.VirtualMachineProfile;
135134
import com.cloud.vm.VirtualMachineProfileImpl;
136135
import com.cloud.vm.VmDetailConstants;
137136
import com.cloud.vm.dao.NicDao;
137+
import com.cloud.vm.dao.UserVmDao;
138138
import com.cloud.vm.dao.VMInstanceDao;
139+
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
139140
import com.google.common.base.Strings;
140141
import com.google.gson.Gson;
141142

@@ -243,6 +244,7 @@ private UnmanagedInstanceResponse createUnmanagedInstanceResponse(UnmanagedInsta
243244
}
244245
if (host != null) {
245246
response.setHostId(host.getUuid());
247+
response.setHostName(host.getName());
246248
}
247249
response.setPowerState(instance.getPowerState().toString());
248250
response.setCpuCores(instance.getCpuCores());
@@ -1078,6 +1080,10 @@ public ListResponse<UnmanagedInstanceResponse> listUnmanagedInstances(ListUnmana
10781080
if (cluster.getHypervisorType() != Hypervisor.HypervisorType.VMware) {
10791081
throw new InvalidParameterValueException(String.format("VM ingestion is currently not supported for hypervisor: %s", cluster.getHypervisorType().toString()));
10801082
}
1083+
String keyword = cmd.getKeyword();
1084+
if (StringUtils.isNotEmpty(keyword)) {
1085+
keyword = keyword.toLowerCase();
1086+
}
10811087
List<HostVO> hosts = resourceManager.listHostsInClusterByStatus(clusterId, Status.Up);
10821088
List<String> additionalNameFilters = getAdditionalNameFilters(cluster);
10831089
List<UnmanagedInstanceResponse> responses = new ArrayList<>();
@@ -1097,11 +1103,15 @@ public ListResponse<UnmanagedInstanceResponse> listUnmanagedInstances(ListUnmana
10971103
continue;
10981104
}
10991105
GetUnmanagedInstancesAnswer unmanagedInstancesAnswer = (GetUnmanagedInstancesAnswer) answer;
1100-
HashMap<String, UnmanagedInstanceTO> unmanagedInstances = new HashMap<>();
1101-
unmanagedInstances.putAll(unmanagedInstancesAnswer.getUnmanagedInstances());
1106+
HashMap<String, UnmanagedInstanceTO> unmanagedInstances = new HashMap<>(unmanagedInstancesAnswer.getUnmanagedInstances());
11021107
Set<String> keys = unmanagedInstances.keySet();
11031108
for (String key : keys) {
1104-
responses.add(createUnmanagedInstanceResponse(unmanagedInstances.get(key), cluster, host));
1109+
UnmanagedInstanceTO instance = unmanagedInstances.get(key);
1110+
if (StringUtils.isNotEmpty(keyword) &&
1111+
!instance.getName().toLowerCase().contains(keyword)) {
1112+
continue;
1113+
}
1114+
responses.add(createUnmanagedInstanceResponse(instance, cluster, host));
11051115
}
11061116
}
11071117
ListResponse<UnmanagedInstanceResponse> listResponses = new ListResponse<>();

ui/public/locales/en.json

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@
219219
"label.action.lock.account.processing": "Locking account....",
220220
"label.action.manage.cluster": "Manage Cluster",
221221
"label.action.manage.cluster.processing": "Managing Cluster....",
222+
"label.action.import.export.instances":"Import-Export Instances",
222223
"label.action.migrate.instance": "Migrate Instance",
223224
"label.action.migrate.instance.processing": "Migrating Instance....",
224225
"label.action.migrate.router": "Migrate Router",
@@ -276,6 +277,8 @@
276277
"label.action.unmanage.cluster": "Unmanage Cluster",
277278
"label.action.unmanage.cluster.processing": "Unmanaging Cluster....",
278279
"label.action.unmanage.virtualmachine": "Unmanage VM",
280+
"label.action.unmanage.instance": "Unmanage Instance",
281+
"label.action.unmanage.instances": "Unmanage Instances",
279282
"label.action.update.offering.access": "Update Offering Access",
280283
"label.action.update.os.preference": "Update OS Preference",
281284
"label.action.update.os.preference.processing": "Updating OS Preference....",
@@ -461,6 +464,8 @@
461464
"label.asyncbackup": "Async Backup",
462465
"label.author.email": "Author e-mail",
463466
"label.author.name": "Author name",
467+
"label.auto.assign.diskoffering.disk.size": "Automatically assign offering matching the disk size",
468+
"label.auto.assign.random.ip": "Automatically assign a random IP address",
464469
"label.autoscale": "AutoScale",
465470
"label.autoscale.configuration.wizard": "AutoScale Configuration Wizard",
466471
"label.availability": "Availability",
@@ -773,6 +778,7 @@
773778
"label.disk.offering.access": "Disk offering access",
774779
"label.disk.offering.details": "Disk offering details",
775780
"label.disk.offerings": "Disk Offerings",
781+
"label.disk.selection": "Disk Selection",
776782
"label.disk.size": "Disk Size",
777783
"label.disk.volume": "Disk Volume",
778784
"label.diskbytesreadrate": "Disk Read Rate (BPS)",
@@ -1057,6 +1063,7 @@
10571063
"label.ikeversion": "IKE Version",
10581064
"label.images": "Images",
10591065
"label.import.backup.offering": "Import Backup Offering",
1066+
"label.import.instance": "Import Instance",
10601067
"label.import.offering": "Import Offering",
10611068
"label.import.role": "Import Role",
10621069
"label.in.progress": "in progress",
@@ -1301,6 +1308,7 @@
13011308
"label.manage.resources": "Manage Resources",
13021309
"label.manage.vpn.user": "Manage VPN Users",
13031310
"label.managedstate": "Managed State",
1311+
"label.managed.instances": "Managed Instances",
13041312
"label.management": "Management",
13051313
"label.management.ips": "Management IP Addresses",
13061314
"label.management.server": "Management Server",
@@ -1383,6 +1391,7 @@
13831391
"label.metrics.network.usage": "Network Usage",
13841392
"label.metrics.network.write": "Write",
13851393
"label.metrics.num.cpu.cores": "Cores",
1394+
"label.migrate.allowed": "Migrate Allowed",
13861395
"label.migrate.data.from.image.store": "Migrate Data from Image store",
13871396
"label.migrate.instance.to": "Migrate instance to",
13881397
"label.migrate.instance.to.host": "Migrate instance to another host",
@@ -1453,6 +1462,7 @@
14531462
"label.network.offering.display.text": "Network Offering Display Text",
14541463
"label.network.offering.name": "Network Offering Name",
14551464
"label.network.offerings": "Network Offerings",
1465+
"label.network.selection": "Network Selection",
14561466
"label.network.service.providers": "Network Service Providers",
14571467
"label.networkcidr": "Network CIDR",
14581468
"label.networkdevicetype": "Type",
@@ -1493,6 +1503,7 @@
14931503
"label.nfscachepath": "Path",
14941504
"label.nfscachezoneid": "Zone",
14951505
"label.nfsserver": "NFS Server",
1506+
"label.nic": "NIC",
14961507
"label.nicadaptertype": "NIC adapter type",
14971508
"label.nicira.controller.address": "Controller Address",
14981509
"label.nicira.nvp.details": "Nicira NVP details",
@@ -1844,6 +1855,7 @@
18441855
"label.rolename": "Role",
18451856
"label.roles": "Roles",
18461857
"label.roletype": "Role Type",
1858+
"label.rootdisk": "ROOT disk",
18471859
"label.rootdisksize": "Root disk size (GB)",
18481860
"label.root.certificate": "Root certificate",
18491861
"label.root.disk.offering": "Root Disk Offering",
@@ -2133,6 +2145,8 @@
21332145
"label.templatesubject": "Subject",
21342146
"label.templatetotal": "Template",
21352147
"label.templatetype": "Template Type",
2148+
"label.template.temporary.import": "Use a temporary template for import",
2149+
"label.template.select.existing": "Select an existing template",
21362150
"label.tftp.dir": "TFTP Directory",
21372151
"label.tftpdir": "Tftp root directory",
21382152
"label.theme.default": "Default Theme",
@@ -2151,6 +2165,7 @@
21512165
"label.to": "to",
21522166
"label.token": "Token",
21532167
"label.token.for.dashboard.login": "Token for dashboard login can be retrieved using following command",
2168+
"label.tools": "Tools",
21542169
"label.total": "Total",
21552170
"label.total.hosts": "Total Hosts",
21562171
"label.total.memory": "Total Memory",
@@ -2177,6 +2192,9 @@
21772192
"label.unit": "Usage Unit",
21782193
"label.unknown": "Unknown",
21792194
"label.unlimited": "Unlimited",
2195+
"label.unmanage.instance": "Unmanage Instance",
2196+
"label.unmanaged.instance": "Unmanaged Instance",
2197+
"label.unmanaged.instances": "Unmanaged Instances",
21802198
"label.untagged": "Untagged",
21812199
"label.update.instance.group": "Update Instance Group",
21822200
"label.update.physical.network": "Update Physical Network",
@@ -2487,7 +2505,10 @@
24872505
"message.action.stop.router": "All services provided by this virtual router will be interrupted. Please confirm that you want to stop this router.",
24882506
"message.action.stop.systemvm": "Please confirm that you want to stop this system VM.",
24892507
"message.action.unmanage.cluster": "Please confirm that you want to unmanage the cluster.",
2508+
"message.action.unmanage.instance": "Please confirm that you want to unmanage the instance.",
2509+
"message.action.unmanage.instances": "Please confirm that you want to unmanage the instances.",
24902510
"message.action.unmanage.virtualmachine": "Please confirm that you want to unmanage the virtual machine.",
2511+
"message.action.unmanage.virtualmachines": "Please confirm that you want to unmanage the virtual machines.",
24912512
"message.action.vmsnapshot.create": "Please confirm that you want to take a snapshot of this instance. <br>Please notice that the instance will be paused during the snapshoting, and resumed after snapshotting, if it runs on KVM.",
24922513
"message.action.vmsnapshot.delete": "Please confirm that you want to delete this VM snapshot. <br>Please notice that the instance will be paused before the snapshot deletion, and resumed after deletion, if it runs on KVM.",
24932514
"message.action.vmsnapshot.revert": "Revert VM snapshot",
@@ -2786,6 +2807,7 @@
27862807
"message.enabling.zone.dots": "Enabling zone...",
27872808
"message.enter.seperated.list.multiple.cidrs": "Please enter a comma separated list of CIDRs if more than one",
27882809
"message.enter.token": "Please enter the token that you were given in your invite e-mail.",
2810+
"message.enter.valid.nic.ip": "Please enter a valid IP address for NIC",
27892811
"message.error.access.key": "Please enter Access Key",
27902812
"message.error.add.guest.network": "Either IPv4 fields or IPv6 fields need to be filled when adding a guest network",
27912813
"message.error.add.secondary.ipaddress": "There was an error adding the secondary IP Address",
@@ -2917,6 +2939,7 @@
29172939
"message.guestnetwork.state.shutdown": "Indicates the network configuration is being destroyed",
29182940
"message.host.dedicated": "Host Dedicated",
29192941
"message.host.dedication.released": "Host dedication released",
2942+
"message.desc.importexportinstancewizard": "Import and export instances to/from an existing VMware zone.<br/><br/>This feature only applies Cloudstack VMware zones. By choosing to Manage an instance, CloudStack takes over the orchestration of that instance. The instance is left running and not physically moved. Unmanaging instances, removes CloudStack ability to mange them (but they are left running and not destroyed)",
29202943
"message.info.cloudian.console": "Cloudian Management Console should open in another window",
29212944
"message.installwizard.click.retry": "Click the button to retry launch.",
29222945
"message.installwizard.copy.whatisacluster": "A cluster provides a way to group hosts. The hosts in a cluster all have identical hardware, run the same hypervisor, are on the same subnet, and access the same shared storage. Virtual machine instances (VMs) can be live-migrated from one host to another within the same cluster, without interrupting service to the user. A cluster is the third-largest organizational unit within a CloudStack™; deployment. Clusters are contained within pods, and pods are contained within zones.<br/><br/>CloudStack™; allows multiple clusters in a cloud deployment, but for a Basic Installation, we only need one cluster.",
@@ -2952,10 +2975,13 @@
29522975
"message.installwizard.tooltip.configureguesttraffic.guestnetmask": "The netmask in use on the subnet that the guests should use",
29532976
"message.installwizard.tooltip.configureguesttraffic.gueststartip": "The range of IP addresses that will be available for allocation to guests in this zone. If one NIC is used, these IPs should be in the same CIDR as the pod CIDR.",
29542977
"message.installwizard.tooltip.configureguesttraffic.name": "A name for your network",
2955-
"message.instance.scaled.up.confirm": "Do you really want to scale Up your instance ?",
2978+
"message.instances.managed": "Instances or VMs controlled by CloudStack",
2979+
"message.instances.scaled.up.confirm": "Do you really want to scale Up your instance ?",
2980+
"message.instances.unmanaged": "Instances or VMs not controlled by CloudStack",
29562981
"message.instancewizard.notemplates": "You do not have any templates available; please add a compatible template, and re-launch the instance wizard.",
29572982
"message.interloadbalance.not.return.elementid": "error: listInternalLoadBalancerElements API doesn't return Internal LB Element Id",
29582983
"message.ip.address.changed": "Your IP addresses may have changed; would you like to refresh the listing? Note that in this case the details pane will close.",
2984+
"message.ip.address.changes.effect.after.vm.restart": "IP address changes takes effect only after VM restart.",
29592985
"message.iso.desc": "Disc image containing data or bootable media for OS",
29602986
"message.join.project": "You have now joined a project. Please switch to Project view to see the project.",
29612987
"message.kubeconfig.cluster.not.available": "Kubernetes cluster kubeconfig not available currently",
@@ -3037,6 +3063,7 @@
30373063
"message.pending.projects.2": "To view, please go to the projects section, then select invitations from the drop-down.",
30383064
"message.please.add.at.lease.one.traffic.range": "Please add at least one traffic range.",
30393065
"message.please.confirm.remove.ssh.key.pair": "Please confirm that you want to remove this SSH Key Pair",
3066+
"message.please.enter.valid.value": "Please enter a valid value",
30403067
"message.please.enter.value": "Please enter values",
30413068
"message.please.proceed": "Please proceed to the next step.",
30423069
"message.please.select.a.configuration.for.your.zone": "Please select a configuration for your zone.",
@@ -3110,10 +3137,12 @@
31103137
"message.select.a.zone": "A zone typically corresponds to a single datacenter. Multiple zones help make the cloud more reliable by providing physical isolation and redundancy.",
31113138
"message.select.affinity.groups": "Please select any affinity groups you want this VM to belong to:",
31123139
"message.select.destination.image.stores": "Please select Image Store(s) to which data is to be migrated to",
3140+
"message.select.disk.offering": "Please select a disk offering for disk",
31133141
"message.select.instance": "Please select an instance.",
31143142
"message.select.iso": "Please select an ISO for your new virtual instance.",
31153143
"message.select.item": "Please select an item.",
31163144
"message.select.migration.policy": "Please select a migration Policy",
3145+
"message.select.nic.network": "Please select a network for NIC",
31173146
"message.select.security.groups": "Please select security group(s) for your new VM",
31183147
"message.select.template": "Please select a template for your new virtual instance.",
31193148
"message.select.tier": "Please select a tier",
@@ -3184,6 +3213,7 @@
31843213
"message.success.edit.acl": "Successfully edited ACL rule",
31853214
"message.success.edit.rule": "Successfully edited rule",
31863215
"message.success.enable.saml.auth": "Successfully enabled SAML Authorization",
3216+
"message.success.import.instance": "Successfully imported instance",
31873217
"message.success.migrate.volume": "Successfully migrated volume",
31883218
"message.success.migrating": "Migration completed successfully for",
31893219
"message.success.move.acl.order": "Successfully moved ACL rule",
@@ -3213,6 +3243,7 @@
32133243
"message.success.upload.iso.description": "This ISO file has been uploaded. Please check its status in the Images > ISOs menu",
32143244
"message.success.upload.template.description": "This template file has been uploaded. Please check its status at Templates menu",
32153245
"message.success.upload.volume.description": "This Volume has been uploaded. Please check its status in the Volumes menu",
3246+
"message.success.unmanage.instance": "Successfully unmanaged instance",
32163247
"message.suspend.project": "Are you sure you want to suspend this project?",
32173248
"message.sussess.discovering.feature": "Discovered all available features!",
32183249
"message.switch.to": "Switched to",
@@ -3221,6 +3252,7 @@
32213252
"message.template.copying": "Template is being copied.",
32223253
"message.template.desc": "OS image that can be used to boot VMs",
32233254
"message.template.iso": "Please select a template or ISO to continue",
3255+
"message.template.import.vm.temporary": "If a temporary template is used, reset VM operation will not work after import.",
32243256
"message.tier.required": "Tier is required",
32253257
"message.tooltip.dns.1": "Name of a DNS server for use by VMs in the zone. The public IP addresses for the zone must have a route to this server.",
32263258
"message.tooltip.dns.2": "A second DNS server name for use by VMs in the zone. The public IP addresses for the zone must have a route to this server.",

0 commit comments

Comments
 (0)