Yaniv Bronhaim has uploaded a new change for review. Change subject: API: host-deploy: Adding ssh username, port and fingerprint to host information ......................................................................
API: host-deploy: Adding ssh username, port and fingerprint to host information Those additional fields are used to authenticate with the host during deploy process. Currently we use default port (22) and root user to connect to host. This patch adds the capability to use configurable port and specific user values, and avoiding using root password to install or update new host. Change-Id: Ic18e91f1602af42e7c73acea5d875c54545cb3c2 Signed-off-by: Yaniv Bronhaim <[email protected]> --- 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/test/java/org/ovirt/engine/api/restapi/resource/BackendHostResourceTest.java M backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendHostsResourceTest.java M backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendResourceTest.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 9 files changed, 121 insertions(+), 9 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/85/16685/1 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 108bca9..3639964 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 @@ -142,6 +142,8 @@ <xs:element name="network" type="Network" minOccurs="0"/> <!-- when installing a host, a root password is required --> <xs:element name="root_password" type="xs:string" minOccurs="0" maxOccurs="1"/> + <!-- when installing a host, ssh configuration is required --> + <xs:element ref="ssh" minOccurs="0" maxOccurs="1"/> <!-- when installing a rhev-h host, an ISO image file is required --> <xs:element name="image" type="xs:string" minOccurs="0" maxOccurs="1"/> <!-- for host fence action --> @@ -1268,6 +1270,7 @@ <!-- when creating a new host, a root password is required, but this is not subsequently included in the representation --> <xs:element name="root_password" type="xs:string" minOccurs="0" maxOccurs="1"/> + <xs:element ref="ssh" minOccurs="0" maxOccurs="1"/> <xs:element name="statistics" type="Statistics" minOccurs="0" maxOccurs="1"/> <xs:element ref="cpu" minOccurs="0" maxOccurs="1"/> <xs:element name="memory" type="xs:long" minOccurs="0"/> @@ -1464,6 +1467,19 @@ </xs:complexContent> </xs:complexType> + <xs:element name="ssh" type="SSH"/> + <xs:complexType name="SSH"> + <xs:complexContent> + <xs:extension base="BaseResource"> + <xs:sequence> + <xs:element name="port" type="xs:int" minOccurs="0" maxOccurs="1"/> + <xs:element name="fingerprint" type="xs:string" minOccurs="0" maxOccurs="1"/> + <xs:element ref="user" minOccurs="0" maxOccurs="1"/> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:element name="group" type="Group"/> <xs:element name="groups" type="Groups"/> 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 dbb0ad2..69c6e02 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 @@ -1796,7 +1796,8 @@ parameterType: Host signatures: - mandatoryArguments: {} - optionalArguments: {host.name: 'xs:string', host.address: 'xs:string', host.root_password: 'xs:string', host.display.address: 'xs:string', host.cluster.id|name: 'xs:string', + optionalArguments: {host.name: 'xs:string', host.address: 'xs:string', host.root_password: 'xs:string', host.ssh.port: 'xs:int', host.ssh.fingerprint: 'xs:string', + host.ssh.password: 'xs:string', host.display.address: 'xs:string', host.cluster.id|name: 'xs:string', host.port: 'xs:int', host.storage_manager.priority: 'xs:int', host.power_management.type: 'xs:string', host.power_management.enabled: 'xs:boolean', host.power_management.address: 'xs:string', host.power_management.username: 'xs:string', host.power_management.password: 'xs:string', host.power_management.options.option--COLLECTION: {option.name: 'xs:string', option.value: 'xs:string'}, host.power_management.pm_proxy--COLLECTION: {propietary : 'xs:string'}, host.power_management.agents.agent--COLLECTION:{type: 'xs:string', address: 'xs:string', user_name: 'xs:string', password: 'xs:string', options.option--COLLECTION: {option.name: 'xs:string', option.value: 'xs:string'}}} @@ -1811,7 +1812,8 @@ parameterType: Host signatures: - mandatoryArguments: {host.name: 'xs:string', host.address: 'xs:string', host.root_password: 'xs:string', host.cluster.id|name: 'xs:string'} - optionalArguments: {host.port: 'xs:int', host.display.address: 'xs:string', host.storage_manager.priority: 'xs:int', host.power_management.type: 'xs:string', + optionalArguments: {host.ssh.port: 'xs:int', host.ssh.fingerprint: 'xs:string', host.ssh.password: 'xs:string', host.port: 'xs:int', + host.display.address: 'xs:string', host.storage_manager.priority: 'xs:int', host.power_management.type: 'xs:string', host.power_management.enabled: 'xs:boolean', host.power_management.address: 'xs:string', host.power_management.username: 'xs:string', host.power_management.password: 'xs:string', host.power_management.options.option--COLLECTION: {option.name: 'xs:string', option.value: 'xs:string'}, host.power_management.pm_proxy--COLLECTION: {propietary : 'xs:string'}, host.power_management.agents.agent--COLLECTION:{type: 'xs:string', address: 'xs:string', user_name: 'xs:string', password: 'xs:string', options.option--COLLECTION: {option.name: 'xs:string', option.value: 'xs:string'}}, host.reboot_after_installation: 'xs:boolean'} urlparams: {} 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 9918efa..e89b942 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 @@ -99,6 +99,23 @@ // REVISIT fencing options VDS vds = getEntity(); UpdateVdsActionParameters params = new UpdateVdsActionParameters(vds.getStaticData(), action.getRootPassword(), true); + if (action.isSetSsh()) { + if (action.getSsh().isSetUser()) { + if (action.getSsh().getUser().isSetPassword()) { + params.setRootPassword(action.getSsh().getUser().getPassword()); + } + // TODO: adding username support. + //if (action.getSsh().getUser().isSetUserName()) { + // params.getvds().setSshUsername(action.getSsh().getUser().getUserName()); + //} + } + if (action.getSsh().isSetPort()) { + params.getvds().setSshPort(action.getSsh().getPort().intValue()); + } + if (action.getSsh().isSetFingerprint()) { + params.getvds().setSshKeyFingerprint(action.getSsh().getFingerprint()); + } + } if (vds.getVdsType()==VDSType.oVirtNode) { params.setIsReinstallOrUpgrade(true); if (action.isSetImage()) { 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 0310821..8ad08d0 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 @@ -96,6 +96,23 @@ if (host.isSetRebootAfterInstallation()) { addParams.setRebootAfterInstallation(host.isRebootAfterInstallation()); } + if (host.isSetSsh()) { + if (host.getSsh().isSetUser()) { + if (host.getSsh().getUser().isSetPassword()) { + addParams.setRootPassword(host.getSsh().getUser().getPassword()); + } + // TODO: adding username support. + //if (action.getSsh().getUser().isSetUserName()) { + // addParams.getvds().setSshUsername(action.getSsh().getUser().getUserName()); + //} + } + if (host.getSsh().isSetPort()) { + addParams.getvds().setSshPort(host.getSsh().getPort().intValue()); + } + if (host.getSsh().isSetFingerprint()) { + addParams.getvds().setSshKeyFingerprint(host.getSsh().getFingerprint()); + } + } return performCreate(VdcActionType.AddVds, addParams, new QueryIdResolver<Guid>(VdcQueryType.GetVdsByVdsId, IdQueryParameters.class)); diff --git a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendHostResourceTest.java b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendHostResourceTest.java index 72c6023..dc04d1b 100644 --- a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendHostResourceTest.java +++ b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendHostResourceTest.java @@ -667,10 +667,9 @@ @Override protected VDS getEntity(int index) { - VDS entity = setUpEntityExpectations(control.createMock(VDS.class), index); VdsStatic vdsStatic = control.createMock(VdsStatic.class); expect(vdsStatic.getId()).andReturn(GUIDS[index]).anyTimes(); - expect(entity.getStaticData()).andReturn(vdsStatic).anyTimes(); + VDS entity = setUpEntityExpectations(control.createMock(VDS.class), null, vdsStatic, index); expect(entity.getStoragePoolId()).andReturn(GUIDS[1]).anyTimes(); return entity; } diff --git a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendHostsResourceTest.java b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendHostsResourceTest.java index a35b69b..c7cb894 100644 --- a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendHostsResourceTest.java +++ b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendHostsResourceTest.java @@ -18,6 +18,7 @@ import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VDSStatus; +import org.ovirt.engine.core.common.businessentities.VdsStatic; import org.ovirt.engine.core.common.businessentities.VdsStatistics; import org.ovirt.engine.core.common.interfaces.SearchType; import org.ovirt.engine.core.common.queries.IdQueryParameters; @@ -298,18 +299,22 @@ @Override protected VDS getEntity(int index) { - return setUpEntityExpectations(control.createMock(VDS.class), control.createMock(VdsStatistics.class), index); + return setUpEntityExpectations(control.createMock(VDS.class), + control.createMock(VdsStatistics.class), + control.createMock(VdsStatic.class), + index); } static VDS setUpEntityExpectations(VDS entity, int index) { - return setUpEntityExpectations(entity, null, index); + return setUpEntityExpectations(entity, null, null, index); } - static VDS setUpEntityExpectations(VDS entity, VdsStatistics statistics, int index) { + static VDS setUpEntityExpectations(VDS entity, VdsStatistics statistics, VdsStatic vdsStatic, int index) { expect(entity.getId()).andReturn(GUIDS[index]).anyTimes(); expect(entity.getName()).andReturn(NAMES[index]).anyTimes(); expect(entity.getHostName()).andReturn(ADDRESSES[index]).anyTimes(); expect(entity.getStatus()).andReturn(VDS_STATUS[index]).anyTimes(); + expect(entity.getStaticData()).andReturn(vdsStatic).anyTimes(); if (statistics != null) { setUpStatisticalEntityExpectations(entity, statistics); } diff --git a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendResourceTest.java b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendResourceTest.java index 28de390..874eb46 100644 --- a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendResourceTest.java +++ b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendResourceTest.java @@ -153,10 +153,9 @@ protected VDS getEntity(int index) { - VDS vds = setUpEntityExpectations(control.createMock(VDS.class), index); VdsStatic vdsStatic = control.createMock(VdsStatic.class); expect(vdsStatic.getId()).andReturn(GUIDS[2]).anyTimes(); - expect(vds.getStaticData()).andReturn(vdsStatic).anyTimes(); + VDS vds = setUpEntityExpectations(control.createMock(VDS.class), null, vdsStatic, index); return vds; } } 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 3711f47..0cb95ec 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 @@ -17,6 +17,7 @@ import org.ovirt.engine.api.model.Hook; import org.ovirt.engine.api.model.Hooks; import org.ovirt.engine.api.model.Host; +import org.ovirt.engine.api.model.User; import org.ovirt.engine.api.model.HostStatus; import org.ovirt.engine.api.model.HostType; import org.ovirt.engine.api.model.IscsiDetails; @@ -32,6 +33,7 @@ import org.ovirt.engine.api.model.TransparentHugePages; import org.ovirt.engine.api.model.Version; import org.ovirt.engine.api.model.VmSummary; +import org.ovirt.engine.api.model.SSH; import org.ovirt.engine.api.restapi.utils.GuidUtils; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VDSStatus; @@ -73,6 +75,9 @@ } else { entity.setPort(DEFAULT_VDSM_PORT); } + if (model.isSetSsh()) { + map(model.getSsh(), entity); + } if (model.isSetPowerManagement()) { entity = map(model.getPowerManagement(), entity); } @@ -85,6 +90,23 @@ entity.setConsoleAddress("".equals(model.getDisplay().getAddress()) ? null : model.getDisplay().getAddress()); } + return entity; + } + + @Mapping(from = SSH.class, to = VdsStatic.class) + public static VdsStatic map(SSH model, VdsStatic template) { + VdsStatic entity = template != null ? template : new VdsStatic(); + /* TODO: add when configured ssh username is enabled + if (model.isSetUser() && model.getUser().isSetUserName()) { + entity.setSshUsername(model.getUser().getUserName()); + } + */ + if (model.isSetPort() && model.getPort() > 0) { + entity.setSshPort(model.getPort()); + } + if (model.isSetFingerprint()) { + entity.setSshKeyFingerprint(model.getFingerprint()); + } return entity; } @@ -261,6 +283,7 @@ } model.setPowerManagement(map(entity, (PowerManagement)null)); model.setHardwareInformation(map(entity, (HardwareInformation)null)); + model.setSsh(map(entity.getStaticData(),(SSH) null)); CPU cpu = new CPU(); CpuTopology cpuTopology = new CpuTopology(); if (entity.getCpuSockets() != null) { @@ -362,6 +385,16 @@ return model; } + @Mapping(from = VdsStatic.class, to = SSH.class) + public static SSH map(VdsStatic entity, SSH template) { + SSH model = template != null ? template : new SSH(); + model.setPort(entity.getSshPort()); + model.setUser(new User()); + model.getUser().setUserName(entity.getSshUsername()); + model.setFingerprint(entity.getSshKeyFingerprint()); + return model; + } + @Mapping(from = VDS.class, to = PowerManagement.class) public static PowerManagement map(VDS entity, PowerManagement template) { PowerManagement model = template != null ? template : new PowerManagement(); 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 34a0f8a..0111825 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,8 @@ 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.SSH; +import org.ovirt.engine.api.model.User; import org.ovirt.engine.api.model.PowerManagement; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VdsStatic; @@ -35,6 +37,9 @@ inverse.setHostName(to.getHostName()); inverse.setVdsGroupId(to.getVdsGroupId()); inverse.setPort(to.getPort()); + inverse.setSshKeyFingerprint(to.getSshKeyFingerprint()); + inverse.setSshPort(to.getSshPort()); + inverse.setSshUsername(to.getSshUsername()); inverse.setVdsSpmPriority(to.getVdsSpmPriority()); inverse.setConsoleAddress(to.getConsoleAddress()); return inverse; @@ -211,6 +216,25 @@ } @Test + public void testUpdateSshHost() { + SSH sshConf = new SSH(); + sshConf.setPort(22); + sshConf.setUser(new User()); + sshConf.getUser().setUserName("root"); + sshConf.setFingerprint("1234"); + + VdsStatic vdsStatic = new VdsStatic(); + vdsStatic.setSshUsername("root"); + vdsStatic.setSshPort(22); + vdsStatic.setSshKeyFingerprint("1234"); + + VdsStatic mappedVdsStatic = HostMapper.map(sshConf, vdsStatic); + assertEquals(mappedVdsStatic.getSshPort(), 22); + assertEquals(mappedVdsStatic.getSshKeyFingerprint(), "1234"); + assertEquals(mappedVdsStatic.getSshUsername(), "root"); + } + + @Test public void testUpdatePowerManagementHostFromAgents() { String[] ip = { "1.1.1.111", "1.1.1.112"}; PowerManagement powerMgmt = new PowerManagement(); -- To view, visit http://gerrit.ovirt.org/16685 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic18e91f1602af42e7c73acea5d875c54545cb3c2 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Yaniv Bronhaim <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
