Greg Padgett has uploaded a new change for review. Change subject: restapi: hosted engine maintenance operations ......................................................................
restapi: hosted engine maintenance operations Add REST API information/commands for hosted engine maintenance. In the host XML, a <HostedEngine> tag will provide information about Hosted Engine on that host (active, configured, score, global and local maintenance status). This will be present only if the request contains the 'All-Content: true' and the HA agent is configurd on the host. Additionally, a new VM action, hosted_engine_maintenance, is provided allowing global maintenance mode to be enabled/disabled through the host the engine vm is currently running on. Change-Id: I72bb087eb6037c2c9f039e989b7261b54534adee Bug-Url: https://bugzilla.redhat.com/1073051 Signed-off-by: Greg Padgett <[email protected]> --- M backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/ReflectionHelper.java M backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/VmResource.java M backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd M backend/manager/modules/restapi/interface/definition/src/main/resources/rsdl_metadata.yaml M backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostResource.java M backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostsResource.java M backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendVmResource.java M backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/utils/FeaturesHelper.java M backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendVmResourceTest.java M backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendVmsResourceTest.java M backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/HostMapper.java M backend/manager/modules/restapi/types/src/test/java/org/ovirt/engine/api/restapi/types/HostMapperTest.java 12 files changed, 132 insertions(+), 5 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/09/26709/1 diff --git a/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/ReflectionHelper.java b/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/ReflectionHelper.java index b6c4040..e491e7a 100644 --- a/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/ReflectionHelper.java +++ b/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/ReflectionHelper.java @@ -38,6 +38,7 @@ private static final String GET_ROOT = "get"; private static final String SET_ROOT = "set"; + private static final String IS_ROOT = "is"; private static final String IS_SET_ROOT = "isSet"; private ReflectionHelper() {} @@ -100,8 +101,9 @@ } public static Method getGetter(Object o, String name) { - String getterName = GET_ROOT + capitalize(name); - return getMethod(o, getterName); + String capitalizedName = capitalize(name); + Method method = getMethod(o, GET_ROOT + capitalizedName); + return (method != null ? method : getMethod(o, IS_ROOT + capitalizedName)); } public static Class<?> getReturnType(Object o, String name) { diff --git a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/VmResource.java b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/VmResource.java index 12ed946..8bc138e 100644 --- a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/VmResource.java +++ b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/VmResource.java @@ -34,7 +34,7 @@ @Produces({ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, ApiMediaType.APPLICATION_X_YAML}) public interface VmResource extends UpdatableResource<VM>, AsynchronouslyCreatedResource, MeasurableResource { - @Path("{action: (start|stop|shutdown|reboot|suspend|detach|migrate|export|move|ticket|cancelmigration|preview_snapshot|commit_snapshot|undo_snapshot)}/{oid}") + @Path("{action: (start|stop|shutdown|reboot|suspend|detach|migrate|export|move|ticket|cancelmigration|preview_snapshot|commit_snapshot|undo_snapshot|maintenance)}/{oid}") public ActionResource getActionSubresource(@PathParam("action")String action, @PathParam("oid")String oid); @POST @@ -136,6 +136,13 @@ @Path("cancelmigration") public Response cancelMigration(Action action); + @POST + @Formatted + @Consumes({ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, ApiMediaType.APPLICATION_X_YAML}) + @Actionable + @Path("maintenance") + public Response maintenance(Action action); + @Path("applications") public VmApplicationsResource getApplicationsResource(); diff --git a/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd b/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd index fa71127..0e8a05c 100644 --- a/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd +++ b/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd @@ -203,6 +203,8 @@ <xs:element name="job" type="Job" minOccurs="0"/> <!-- indicates whether to import the image as template or not --> <xs:element name="import_as_template" type="xs:boolean" minOccurs="0" maxOccurs="1"/> + <!-- for VM hosted engine maintenance actions --> + <xs:element name="maintenance_enabled" type="xs:boolean" minOccurs="0" maxOccurs="1"/> </xs:sequence> </xs:group> @@ -1466,6 +1468,7 @@ <xs:element name="libvirt_version" type="Version" minOccurs="0" maxOccurs="1"/> <!-- Optionally specify the display address of this host explicitly --> <xs:element ref="display" minOccurs="0"/> + <xs:element name="hosted_engine" type="HostedEngine" minOccurs="0" maxOccurs="1"/> </xs:sequence> </xs:extension> </xs:complexContent> @@ -1487,6 +1490,18 @@ </xs:simpleContent> </xs:complexType> + <xs:element name="hosted_engine" type="HostedEngine"/> + + <xs:complexType name="HostedEngine"> + <xs:sequence> + <xs:element name="configured" type="xs:boolean" minOccurs="0" maxOccurs="1"/> + <xs:element name="active" type="xs:boolean" minOccurs="0" maxOccurs="1"/> + <xs:element name="score" type="xs:int" minOccurs="0" maxOccurs="1"/> + <xs:element name="global_maintenance" type="xs:boolean" minOccurs="0" maxOccurs="1"/> + <xs:element name="local_maintenance" type="xs:boolean" minOccurs="0" maxOccurs="1"/> + </xs:sequence> + </xs:complexType> + <xs:element name="host_states" type="HostStates"/> <xs:complexType name="HostStates"> diff --git a/backend/manager/modules/restapi/interface/definition/src/main/resources/rsdl_metadata.yaml b/backend/manager/modules/restapi/interface/definition/src/main/resources/rsdl_metadata.yaml index 1a8575b..5b92600 100644 --- a/backend/manager/modules/restapi/interface/definition/src/main/resources/rsdl_metadata.yaml +++ b/backend/manager/modules/restapi/interface/definition/src/main/resources/rsdl_metadata.yaml @@ -996,6 +996,19 @@ Content-Type: {value: application/xml|json, required: true} Expect: {value: 201-created, required: false} Correlation-Id: {value: 'any string', required: false} +- name: /vms/{vm:id}/maintenance|rel=maintenance + description: enable or disable maintenance mode for this virtual machine + request: + body: + parameterType: Action + signatures: + - mandatoryArguments: {action.maintenance_enabled: 'xs:boolean'} + optionalArguments: {action.async: 'xs:boolean', action.grace_period.expiry: 'xs:long'} + description: enable or disable maintenance mode for this virtual machine + urlparams: {} + headers: + Content-Type: {value: application/xml|json, required: true} + Correlation-Id: {value: 'any string', required: false} - name: /disks|rel=get description: get a list of disks in the system request: diff --git a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostResource.java b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostResource.java index f82f2a4..757a42c 100644 --- a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostResource.java +++ b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostResource.java @@ -362,7 +362,8 @@ @Override protected Host doPopulate(Host model, VDS entity) { - return model; + Host host = parent.addHostedEngineIfConfigured(model, entity); + return host; } @Override diff --git a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostsResource.java b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostsResource.java index 75ffb46..516263b 100644 --- a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostsResource.java +++ b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostsResource.java @@ -11,6 +11,7 @@ import org.ovirt.engine.api.model.Action; import org.ovirt.engine.api.model.Certificate; import org.ovirt.engine.api.model.Host; +import org.ovirt.engine.api.model.HostedEngine; import org.ovirt.engine.api.model.Hosts; import org.ovirt.engine.api.model.Statistic; import org.ovirt.engine.api.model.Statistics; @@ -112,7 +113,8 @@ @Override protected Host doPopulate(Host model, VDS entity) { - return model; + Host host = addHostedEngineIfConfigured(model, entity); + return host; } @Override @@ -183,4 +185,13 @@ ? host.getCluster().getName() : "Default")).getId(); } + + Host addHostedEngineIfConfigured(Host host, VDS entity) { + /* Add entity data only if the hosted engine agent is configured on this host */ + if (entity.getHighlyAvailableIsConfigured()) { + HostedEngine hostedEngine = getMapper(VDS.class, HostedEngine.class).map(entity, null); + host.setHostedEngine(hostedEngine); + } + return host; + } } diff --git a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendVmResource.java b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendVmResource.java index c84a0ee..e04149f 100644 --- a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendVmResource.java +++ b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendVmResource.java @@ -40,6 +40,7 @@ import org.ovirt.engine.api.resource.VmResource; import org.ovirt.engine.api.resource.WatchdogsResource; import org.ovirt.engine.api.restapi.logging.Messages; +import org.ovirt.engine.api.restapi.resource.AbstractBackendResource.QueryIdResolver; import org.ovirt.engine.api.restapi.types.VmMapper; import org.ovirt.engine.core.common.VdcObjectType; import org.ovirt.engine.core.common.action.ChangeVMClusterParameters; @@ -50,6 +51,7 @@ import org.ovirt.engine.core.common.action.RestoreAllSnapshotsParameters; import org.ovirt.engine.core.common.action.RunVmOnceParams; import org.ovirt.engine.core.common.action.RunVmParams; +import org.ovirt.engine.core.common.action.SetHaMaintenanceParameters; import org.ovirt.engine.core.common.action.SetVmTicketParameters; import org.ovirt.engine.core.common.action.ShutdownVmParameters; import org.ovirt.engine.core.common.action.StopVmParameters; @@ -59,6 +61,7 @@ import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.action.VmManagementParametersBase; import org.ovirt.engine.core.common.action.VmOperationParameterBase; +import org.ovirt.engine.core.common.businessentities.HaMaintenanceMode; import org.ovirt.engine.core.common.businessentities.InitializationType; import org.ovirt.engine.core.common.businessentities.SnapshotActionEnum; import org.ovirt.engine.core.common.businessentities.VDS; @@ -504,4 +507,25 @@ public VmReportedDevicesResource getVmReportedDevicesResource() { return inject(new BackendVmReportedDevicesResource(guid)); } + + @Override + public Response maintenance(Action action) { + validateParameters(action, "maintenanceEnabled"); + + org.ovirt.engine.core.common.businessentities.VM entity = + getEntity(org.ovirt.engine.core.common.businessentities.VM.class, + VdcQueryType.GetVmByVmId, + new IdQueryParameters(guid), + id); + if (!entity.isHostedEngine()) { + throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST) + .entity("Moving to maintenance mode is currently only available for the VM containing the hosted engine.") + .build()); + } + + return doAction(VdcActionType.SetHaMaintenance, + new SetHaMaintenanceParameters(entity.getRunOnVds(), + HaMaintenanceMode.GLOBAL, action.isMaintenanceEnabled()), + action); + } } diff --git a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/utils/FeaturesHelper.java b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/utils/FeaturesHelper.java index 574665e..9001afc 100644 --- a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/utils/FeaturesHelper.java +++ b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/utils/FeaturesHelper.java @@ -77,6 +77,7 @@ addFeatureCopyMoveDiskInAdditionalContext(features); addNetworkLabelsFeature(features); addRebootFeature(features); + addMaintenanceFeature(features); } return features; } @@ -416,4 +417,11 @@ feature.setDescription("Abilitiy to provision networks on hosts via labels."); features.getFeature().add(feature); } + + private void addMaintenanceFeature(Features features) { + Feature feature = new Feature(); + feature.setName("Maintenance"); + feature.setDescription("Enable or disable VM maintenance mode."); + features.getFeature().add(feature); + } } diff --git a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendVmResourceTest.java b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendVmResourceTest.java index 4477ce1..3d62dbf 100644 --- a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendVmResourceTest.java +++ b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendVmResourceTest.java @@ -47,6 +47,7 @@ import org.ovirt.engine.core.common.action.RestoreAllSnapshotsParameters; import org.ovirt.engine.core.common.action.RunVmOnceParams; import org.ovirt.engine.core.common.action.RunVmParams; +import org.ovirt.engine.core.common.action.SetHaMaintenanceParameters; import org.ovirt.engine.core.common.action.SetVmTicketParameters; import org.ovirt.engine.core.common.action.ShutdownVmParameters; import org.ovirt.engine.core.common.action.StopVmParameters; @@ -833,6 +834,19 @@ verifyQuery(statisticsResource.getQuery(), entity); } + @Test + public void testMaintenance() throws Exception { + setUpGetEntityExpectations(1); + setUriInfo(setUpActionExpectations(VdcActionType.SetHaMaintenance, + SetHaMaintenanceParameters.class, + new String[] { "IsEnabled" }, + new Object[] { true })); + + Action action = new Action(); + action.setMaintenanceEnabled(true); + verifyActionResponse(resource.maintenance(action)); + } + protected org.ovirt.engine.core.common.businessentities.VM setUpStatisticalExpectations() throws Exception { VmStatistics stats = control.createMock(VmStatistics.class); org.ovirt.engine.core.common.businessentities.VM entity = diff --git a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendVmsResourceTest.java b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendVmsResourceTest.java index 70622aa..a7295429 100644 --- a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendVmsResourceTest.java +++ b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendVmsResourceTest.java @@ -1266,6 +1266,7 @@ expect(entity.getNumOfMonitors()).andReturn(2).anyTimes(); expect(entity.getVmType()).andReturn(VmType.Server).anyTimes(); expect(entity.getRunOnVdsName()).andReturn(NAMES[NAMES.length -1]).anyTimes(); + expect(entity.isHostedEngine()).andReturn(index == 0).anyTimes(); setUpStatisticalEntityExpectations(entity, statistics); return entity; } diff --git a/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/HostMapper.java b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/HostMapper.java index d903b07..65dcd40 100644 --- a/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/HostMapper.java +++ b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/HostMapper.java @@ -21,6 +21,7 @@ import org.ovirt.engine.api.model.Host; import org.ovirt.engine.api.model.HostStatus; import org.ovirt.engine.api.model.HostType; +import org.ovirt.engine.api.model.HostedEngine; import org.ovirt.engine.api.model.IscsiDetails; import org.ovirt.engine.api.model.KSM; import org.ovirt.engine.api.model.OperatingSystem; @@ -393,6 +394,17 @@ return model; } + @Mapping(from = VDS.class, to = HostedEngine.class) + public static HostedEngine map(VDS entity, HostedEngine template) { + HostedEngine hostedEngine = template != null ? template : new HostedEngine(); + hostedEngine.setConfigured(entity.getHighlyAvailableIsConfigured()); + hostedEngine.setActive(entity.getHighlyAvailableIsActive()); + hostedEngine.setScore(entity.getHighlyAvailableScore()); + hostedEngine.setGlobalMaintenance(entity.getHighlyAvailableGlobalMaintenance()); + hostedEngine.setLocalMaintenance(entity.getHighlyAvailableLocalMaintenance()); + return hostedEngine; + } + private static OperatingSystem getHostOs(String hostOs) { if (hostOs == null || hostOs.trim().length() == 0) { return null; diff --git a/backend/manager/modules/restapi/types/src/test/java/org/ovirt/engine/api/restapi/types/HostMapperTest.java b/backend/manager/modules/restapi/types/src/test/java/org/ovirt/engine/api/restapi/types/HostMapperTest.java index 9e3372b..f4544f4 100644 --- a/backend/manager/modules/restapi/types/src/test/java/org/ovirt/engine/api/restapi/types/HostMapperTest.java +++ b/backend/manager/modules/restapi/types/src/test/java/org/ovirt/engine/api/restapi/types/HostMapperTest.java @@ -6,6 +6,7 @@ import org.ovirt.engine.api.model.Agent; import org.ovirt.engine.api.model.Agents; import org.ovirt.engine.api.model.Host; +import org.ovirt.engine.api.model.HostedEngine; import org.ovirt.engine.api.model.PowerManagement; import org.ovirt.engine.api.model.SSH; import org.ovirt.engine.api.model.User; @@ -282,4 +283,22 @@ assertEquals(Long.valueOf(host.getLibvirtVersion().getBuild()), Long.valueOf(10)); assertEquals(host.getLibvirtVersion().getFullVersion(), "libvirt-0.9.10-21.el6_3.4"); } + + @Test + public void testHostedEngineMapping() { + VDS vds = new VDS(); + vds.setId(Guid.Empty); + vds.setHighlyAvailableIsConfigured(true); + vds.setHighlyAvailableIsActive(false); + vds.setHighlyAvailableScore(123); + vds.setHighlyAvailableGlobalMaintenance(true); + vds.setHighlyAvailableLocalMaintenance(false); + HostedEngine hostedEngine = HostMapper.map(vds, (HostedEngine) null); + assertNotNull(hostedEngine); + assertEquals(hostedEngine.isConfigured(), Boolean.TRUE); + assertEquals(hostedEngine.isActive(), Boolean.FALSE); + assertEquals(hostedEngine.getScore(), Integer.valueOf(123)); + assertEquals(hostedEngine.isGlobalMaintenance(), Boolean.TRUE); + assertEquals(hostedEngine.isLocalMaintenance(), Boolean.FALSE); + } } -- To view, visit http://gerrit.ovirt.org/26709 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I72bb087eb6037c2c9f039e989b7261b54534adee Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: ovirt-engine-3.4 Gerrit-Owner: Greg Padgett <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
