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

Reply via email to