Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
Abhishek Kumar 2026-01-23 16:57:28 +05:30
parent f52b114c8d
commit 27844684c5
29 changed files with 1377 additions and 39 deletions

View File

@ -18,6 +18,7 @@
package org.apache.cloudstack.veeam.api;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
@ -37,11 +38,12 @@ import org.apache.cloudstack.veeam.api.dto.ProductInfo;
import org.apache.cloudstack.veeam.api.dto.Ref;
import org.apache.cloudstack.veeam.api.dto.SpecialObjectRef;
import org.apache.cloudstack.veeam.api.dto.SpecialObjects;
import org.apache.cloudstack.veeam.api.dto.Summary;
import org.apache.cloudstack.veeam.api.dto.ApiSummary;
import org.apache.cloudstack.veeam.api.dto.SummaryCount;
import org.apache.cloudstack.veeam.api.dto.Version;
import org.apache.cloudstack.veeam.utils.Negotiation;
import com.cloud.utils.UuidUtils;
import com.cloud.utils.component.ManagerBase;
public class ApiService extends ManagerBase implements RouteHandler {
@ -99,7 +101,7 @@ public class ApiService extends ManagerBase implements RouteHandler {
/* ---------------- Product info ---------------- */
ProductInfo productInfo = new ProductInfo();
productInfo.instanceId = UUID.randomUUID().toString();
productInfo.instanceId = UuidUtils.nameUUIDFromBytes(VeeamControlService.BindAddress.value().getBytes(StandardCharsets.UTF_8)).toString();
productInfo.name = "oVirt Engine";
Version version = new Version();
@ -125,7 +127,7 @@ public class ApiService extends ManagerBase implements RouteHandler {
api.specialObjects = specialObjects;
/* ---------------- Summary ---------------- */
Summary summary = new Summary();
ApiSummary summary = new ApiSummary();
summary.hosts = new SummaryCount(1, 1);
summary.storageDomains = new SummaryCount(1, 2);
summary.users = new SummaryCount(1, 1);

View File

@ -32,10 +32,10 @@ import org.apache.cloudstack.veeam.api.dto.Clusters;
import org.apache.cloudstack.veeam.utils.Negotiation;
import org.apache.cloudstack.veeam.utils.PathUtil;
import com.cloud.api.query.dao.DataCenterJoinDao;
import com.cloud.api.query.vo.DataCenterJoinVO;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ManagerBase;
@ -46,7 +46,7 @@ public class ClustersRouteHandler extends ManagerBase implements RouteHandler {
ClusterDao clusterDao;
@Inject
DataCenterDao dataCenterDao;
DataCenterJoinDao dataCenterJoinDao;
@Override
public boolean start() {
@ -78,7 +78,7 @@ public class ClustersRouteHandler extends ManagerBase implements RouteHandler {
Pair<String, String> idAndSubPath = PathUtil.extractIdAndSubPath(sanitizedPath, BASE_ROUTE);
if (idAndSubPath != null) {
// /api/disks/{id}
// /api/clusters/{id}
if (idAndSubPath.first() != null) {
if (idAndSubPath.second() == null) {
handleGetById(idAndSubPath.first(), resp, outFormat, io);
@ -114,10 +114,10 @@ public class ClustersRouteHandler extends ManagerBase implements RouteHandler {
io.getWriter().write(resp, 200, response, outFormat);
}
private DataCenterVO getZoneById(Long zoneId) {
private DataCenterJoinVO getZoneById(Long zoneId) {
if (zoneId == null) {
return null;
}
return dataCenterDao.findById(zoneId);
return dataCenterJoinDao.findById(zoneId);
}
}

View File

@ -26,21 +26,26 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.cloudstack.veeam.RouteHandler;
import org.apache.cloudstack.veeam.VeeamControlServlet;
import org.apache.cloudstack.veeam.api.converter.DataCenterVOToDataCenterConverter;
import org.apache.cloudstack.veeam.api.converter.DataCenterJoinVOToDataCenterConverter;
import org.apache.cloudstack.veeam.api.converter.NetworkVOToNetworkConverter;
import org.apache.cloudstack.veeam.api.converter.StoreVOToStorageDomainConverter;
import org.apache.cloudstack.veeam.api.dto.DataCenter;
import org.apache.cloudstack.veeam.api.dto.DataCenters;
import org.apache.cloudstack.veeam.api.dto.Network;
import org.apache.cloudstack.veeam.api.dto.Networks;
import org.apache.cloudstack.veeam.api.dto.StorageDomain;
import org.apache.cloudstack.veeam.api.dto.StorageDomains;
import org.apache.cloudstack.veeam.utils.Negotiation;
import org.apache.cloudstack.veeam.utils.PathUtil;
import com.cloud.api.query.dao.DataCenterJoinDao;
import com.cloud.api.query.dao.ImageStoreJoinDao;
import com.cloud.api.query.dao.StoragePoolJoinDao;
import com.cloud.api.query.vo.DataCenterJoinVO;
import com.cloud.api.query.vo.ImageStoreJoinVO;
import com.cloud.api.query.vo.StoragePoolJoinVO;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ManagerBase;
@ -51,7 +56,7 @@ public class DataCentersRouteHandler extends ManagerBase implements RouteHandler
private static final int DEFAULT_PAGE = 1;
@Inject
DataCenterDao dataCenterDao;
DataCenterJoinDao dataCenterJoinDao;
@Inject
StoragePoolJoinDao storagePoolJoinDao;
@ -59,6 +64,9 @@ public class DataCentersRouteHandler extends ManagerBase implements RouteHandler
@Inject
ImageStoreJoinDao imageStoreJoinDao;
@Inject
NetworkDao networkDao;
@Override
public boolean start() {
return true;
@ -99,6 +107,10 @@ public class DataCentersRouteHandler extends ManagerBase implements RouteHandler
handleGetStorageDomainsByDcId(idAndSubPath.first(), resp, outFormat, io);
return;
}
if ("networks".equals(idAndSubPath.second())) {
handleGetNetworksByDcId(idAndSubPath.first(), resp, outFormat, io);
return;
}
}
}
@ -107,24 +119,24 @@ public class DataCentersRouteHandler extends ManagerBase implements RouteHandler
public void handleGet(final HttpServletRequest req, final HttpServletResponse resp,
Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
final List<DataCenter> result = DataCenterVOToDataCenterConverter.toDCList(listDCs());
final List<DataCenter> result = DataCenterJoinVOToDataCenterConverter.toDCList(listDCs());
final DataCenters response = new DataCenters(result);
io.getWriter().write(resp, 200, response, outFormat);
}
protected List<DataCenterVO> listDCs() {
return dataCenterDao.listAll();
protected List<DataCenterJoinVO> listDCs() {
return dataCenterJoinDao.listAll();
}
public void handleGetById(final String id, final HttpServletResponse resp, final Negotiation.OutFormat outFormat,
final VeeamControlServlet io) throws IOException {
final DataCenterVO dataCenterVO = dataCenterDao.findByUuid(id);
final DataCenterJoinVO dataCenterVO = dataCenterJoinDao.findByUuid(id);
if (dataCenterVO == null) {
io.notFound(resp, "DataCenter not found: " + id, outFormat);
return;
}
DataCenter response = DataCenterVOToDataCenterConverter.toDataCenter(dataCenterVO);
DataCenter response = DataCenterJoinVOToDataCenterConverter.toDataCenter(dataCenterVO);
io.getWriter().write(resp, 200, response, outFormat);
}
@ -137,9 +149,13 @@ public class DataCentersRouteHandler extends ManagerBase implements RouteHandler
return imageStoreJoinDao.listAll();
}
protected List<NetworkVO> listNetworksByDcId(final long dcId) {
return networkDao.listAll();
}
public void handleGetStorageDomainsByDcId(final String id, final HttpServletResponse resp, final Negotiation.OutFormat outFormat,
final VeeamControlServlet io) throws IOException {
final DataCenterVO dataCenterVO = dataCenterDao.findByUuid(id);
final VeeamControlServlet io) throws IOException {
final DataCenterJoinVO dataCenterVO = dataCenterJoinDao.findByUuid(id);
if (dataCenterVO == null) {
io.notFound(resp, "DataCenter not found: " + id, outFormat);
return;
@ -151,4 +167,18 @@ public class DataCentersRouteHandler extends ManagerBase implements RouteHandler
io.getWriter().write(resp, 200, response, outFormat);
}
public void handleGetNetworksByDcId(final String id, final HttpServletResponse resp, final Negotiation.OutFormat outFormat,
final VeeamControlServlet io) throws IOException {
final DataCenterJoinVO dataCenterVO = dataCenterJoinDao.findByUuid(id);
if (dataCenterVO == null) {
io.notFound(resp, "DataCenter not found: " + id, outFormat);
return;
}
List<Network> networks = NetworkVOToNetworkConverter.toNetworkList(listNetworksByDcId(dataCenterVO.getId()), (dcId) -> dataCenterVO);
Networks response = new Networks(networks);
io.getWriter().write(resp, 200, response, outFormat);
}
}

View File

@ -0,0 +1,111 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.veeam.api;
import java.io.IOException;
import java.util.List;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.cloudstack.veeam.RouteHandler;
import org.apache.cloudstack.veeam.VeeamControlServlet;
import org.apache.cloudstack.veeam.api.converter.HostJoinVOToHostConverter;
import org.apache.cloudstack.veeam.api.dto.Host;
import org.apache.cloudstack.veeam.api.dto.Hosts;
import org.apache.cloudstack.veeam.utils.Negotiation;
import org.apache.cloudstack.veeam.utils.PathUtil;
import com.cloud.api.query.dao.HostJoinDao;
import com.cloud.api.query.vo.HostJoinVO;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ManagerBase;
public class HostsRouteHandler extends ManagerBase implements RouteHandler {
public static final String BASE_ROUTE = "/api/hosts";
@Inject
HostJoinDao hostJoinDao;
@Override
public boolean start() {
return true;
}
@Override
public int priority() {
return 5;
}
@Override
public boolean canHandle(String method, String path) {
return getSanitizedPath(path).startsWith(BASE_ROUTE);
}
@Override
public void handle(HttpServletRequest req, HttpServletResponse resp, String path, Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
final String method = req.getMethod();
if (!"GET".equalsIgnoreCase(method)) {
io.methodNotAllowed(resp, "GET", outFormat);
return;
}
final String sanitizedPath = getSanitizedPath(path);
if (sanitizedPath.equals(BASE_ROUTE)) {
handleGet(req, resp, outFormat, io);
return;
}
Pair<String, String> idAndSubPath = PathUtil.extractIdAndSubPath(sanitizedPath, BASE_ROUTE);
if (idAndSubPath != null) {
// /api/hosts/{id}
if (idAndSubPath.first() != null) {
if (idAndSubPath.second() == null) {
handleGetById(idAndSubPath.first(), resp, outFormat, io);
return;
}
}
}
resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Not found");
}
public void handleGet(final HttpServletRequest req, final HttpServletResponse resp,
Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
final List<Host> result = HostJoinVOToHostConverter.toHostList(listHosts());
final Hosts response = new Hosts(result);
io.getWriter().write(resp, 200, response, outFormat);
}
protected List<HostJoinVO> listHosts() {
return hostJoinDao.listAll();
}
public void handleGetById(final String id, final HttpServletResponse resp, final Negotiation.OutFormat outFormat,
final VeeamControlServlet io) throws IOException {
final HostJoinVO vo = hostJoinDao.findByUuid(id);
if (vo == null) {
io.notFound(resp, "DataCenter not found: " + id, outFormat);
return;
}
Host response = HostJoinVOToHostConverter.toHost(vo);
io.getWriter().write(resp, 200, response, outFormat);
}
}

View File

@ -0,0 +1,123 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.veeam.api;
import java.io.IOException;
import java.util.List;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.cloudstack.veeam.RouteHandler;
import org.apache.cloudstack.veeam.VeeamControlServlet;
import org.apache.cloudstack.veeam.api.converter.NetworkVOToNetworkConverter;
import org.apache.cloudstack.veeam.api.dto.Network;
import org.apache.cloudstack.veeam.api.dto.Networks;
import org.apache.cloudstack.veeam.utils.Negotiation;
import org.apache.cloudstack.veeam.utils.PathUtil;
import com.cloud.api.query.dao.DataCenterJoinDao;
import com.cloud.api.query.vo.DataCenterJoinVO;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ManagerBase;
public class NetworksRouteHandler extends ManagerBase implements RouteHandler {
public static final String BASE_ROUTE = "/api/networks";
@Inject
NetworkDao networkDao;
@Inject
DataCenterJoinDao dataCenterJoinDao;
@Override
public boolean start() {
return true;
}
@Override
public int priority() {
return 5;
}
@Override
public boolean canHandle(String method, String path) {
return getSanitizedPath(path).startsWith(BASE_ROUTE);
}
@Override
public void handle(HttpServletRequest req, HttpServletResponse resp, String path, Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
final String method = req.getMethod();
if (!"GET".equalsIgnoreCase(method)) {
io.methodNotAllowed(resp, "GET", outFormat);
return;
}
final String sanitizedPath = getSanitizedPath(path);
if (sanitizedPath.equals(BASE_ROUTE)) {
handleGet(req, resp, outFormat, io);
return;
}
Pair<String, String> idAndSubPath = PathUtil.extractIdAndSubPath(sanitizedPath, BASE_ROUTE);
if (idAndSubPath != null) {
// /api/networks/{id}
if (idAndSubPath.first() != null) {
if (idAndSubPath.second() == null) {
handleGetById(idAndSubPath.first(), resp, outFormat, io);
return;
}
}
}
resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Not found");
}
public void handleGet(final HttpServletRequest req, final HttpServletResponse resp,
Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
final List<Network> result = NetworkVOToNetworkConverter.toNetworkList(listNetworks(), this::getZoneById);
final Networks response = new Networks(result);
io.getWriter().write(resp, 200, response, outFormat);
}
protected List<NetworkVO> listNetworks() {
return networkDao.listAll();
}
public void handleGetById(final String id, final HttpServletResponse resp, final Negotiation.OutFormat outFormat,
final VeeamControlServlet io) throws IOException {
final NetworkVO vo = networkDao.findByUuid(id);
if (vo == null) {
io.notFound(resp, "DataCenter not found: " + id, outFormat);
return;
}
Network response = NetworkVOToNetworkConverter.toNetwork(vo, this::getZoneById);
io.getWriter().write(resp, 200, response, outFormat);
}
private DataCenterJoinVO getZoneById(Long zoneId) {
if (zoneId == null) {
return null;
}
return dataCenterJoinDao.findById(zoneId);
}
}

View File

@ -208,5 +208,4 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
}
return hostJoinDao.findById(hostId);
}
}

View File

@ -0,0 +1,123 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.veeam.api;
import java.io.IOException;
import java.util.List;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.cloudstack.veeam.RouteHandler;
import org.apache.cloudstack.veeam.VeeamControlServlet;
import org.apache.cloudstack.veeam.api.converter.NetworkVOToVnicProfileConverter;
import org.apache.cloudstack.veeam.api.dto.VnicProfile;
import org.apache.cloudstack.veeam.api.dto.VnicProfiles;
import org.apache.cloudstack.veeam.utils.Negotiation;
import org.apache.cloudstack.veeam.utils.PathUtil;
import com.cloud.api.query.dao.DataCenterJoinDao;
import com.cloud.api.query.vo.DataCenterJoinVO;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ManagerBase;
public class VnicProfilesRouteHandler extends ManagerBase implements RouteHandler {
public static final String BASE_ROUTE = "/api/vnicprofiles";
@Inject
NetworkDao networkDao;
@Inject
DataCenterJoinDao dataCenterJoinDao;
@Override
public boolean start() {
return true;
}
@Override
public int priority() {
return 5;
}
@Override
public boolean canHandle(String method, String path) {
return getSanitizedPath(path).startsWith(BASE_ROUTE);
}
@Override
public void handle(HttpServletRequest req, HttpServletResponse resp, String path, Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
final String method = req.getMethod();
if (!"GET".equalsIgnoreCase(method)) {
io.methodNotAllowed(resp, "GET", outFormat);
return;
}
final String sanitizedPath = getSanitizedPath(path);
if (sanitizedPath.equals(BASE_ROUTE)) {
handleGet(req, resp, outFormat, io);
return;
}
Pair<String, String> idAndSubPath = PathUtil.extractIdAndSubPath(sanitizedPath, BASE_ROUTE);
if (idAndSubPath != null) {
// /api/vnicprofiles/{id}
if (idAndSubPath.first() != null) {
if (idAndSubPath.second() == null) {
handleGetById(idAndSubPath.first(), resp, outFormat, io);
return;
}
}
}
resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Not found");
}
public void handleGet(final HttpServletRequest req, final HttpServletResponse resp,
Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
final List<VnicProfile> result = NetworkVOToVnicProfileConverter.toVnicProfileList(listNetworks(), this::getZoneById);
final VnicProfiles response = new VnicProfiles(result);
io.getWriter().write(resp, 200, response, outFormat);
}
protected List<NetworkVO> listNetworks() {
return networkDao.listAll();
}
public void handleGetById(final String id, final HttpServletResponse resp, final Negotiation.OutFormat outFormat,
final VeeamControlServlet io) throws IOException {
final NetworkVO vo = networkDao.findByUuid(id);
if (vo == null) {
io.notFound(resp, "DataCenter not found: " + id, outFormat);
return;
}
VnicProfile response = NetworkVOToVnicProfileConverter.toVnicProfile(vo, this::getZoneById);
io.getWriter().write(resp, 200, response, outFormat);
}
private DataCenterJoinVO getZoneById(Long zoneId) {
if (zoneId == null) {
return null;
}
return dataCenterJoinDao.findById(zoneId);
}
}

View File

@ -19,7 +19,6 @@ package org.apache.cloudstack.veeam.api.converter;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;
@ -31,11 +30,12 @@ import org.apache.cloudstack.veeam.api.dto.Cluster;
import org.apache.cloudstack.veeam.api.dto.Link;
import org.apache.cloudstack.veeam.api.dto.Ref;
import com.cloud.api.query.vo.DataCenterJoinVO;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.DataCenterVO;
import com.cloud.utils.UuidUtils;
public class ClusterVOToClusterConverter {
public static Cluster toCluster(final ClusterVO vo, final Function<Long, DataCenterVO> dataCenterResolver) {
public static Cluster toCluster(final ClusterVO vo, final Function<Long, DataCenterJoinVO> dataCenterResolver) {
final Cluster c = new Cluster();
final String basePath = VeeamControlService.ContextPath.value();
@ -131,7 +131,7 @@ public class ClusterVOToClusterConverter {
// --- data_center ref mapping (CloudStack cluster -> pod -> zone)
if (dataCenterResolver != null) {
final DataCenterVO zone = dataCenterResolver.apply(vo.getDataCenterId());
final DataCenterJoinVO zone = dataCenterResolver.apply(vo.getDataCenterId());
if (zone != null) {
c.dataCenter = Ref.of(basePath + DataCentersRouteHandler.BASE_ROUTE + "/" + zone.getUuid(), zone.getUuid());
}
@ -157,7 +157,7 @@ public class ClusterVOToClusterConverter {
}
public static List<Cluster> toClusterList(final List<ClusterVO> voList,
final Function<Long, DataCenterVO> dataCenterResolver) {
final Function<Long, DataCenterJoinVO> dataCenterResolver) {
return voList.stream()
.map(vo -> toCluster(vo, dataCenterResolver))
.collect(Collectors.toList());
@ -165,6 +165,6 @@ public class ClusterVOToClusterConverter {
private static String stableUuid(final String key) {
// deterministic UUID, so the same ClusterVO maps to same "ovirt id" every time
return UUID.nameUUIDFromBytes(key.getBytes()).toString();
return UuidUtils.nameUUIDFromBytes(key.getBytes()).toString();
}
}

View File

@ -29,11 +29,11 @@ import org.apache.cloudstack.veeam.api.dto.Ref;
import org.apache.cloudstack.veeam.api.dto.SupportedVersions;
import org.apache.cloudstack.veeam.api.dto.Version;
import com.cloud.dc.DataCenterVO;
import com.cloud.api.query.vo.DataCenterJoinVO;
import com.cloud.org.Grouping;
public class DataCenterVOToDataCenterConverter {
public static DataCenter toDataCenter(final DataCenterVO zone) {
public class DataCenterJoinVOToDataCenterConverter {
public static DataCenter toDataCenter(final DataCenterJoinVO zone) {
final String id = zone.getUuid();
final String basePath = VeeamControlService.ContextPath.value();
final String href = basePath + DataCentersRouteHandler.BASE_ROUTE + DataCentersRouteHandler.BASE_ROUTE + "/" + id;
@ -72,9 +72,9 @@ public class DataCenterVOToDataCenterConverter {
return dc;
}
public static List<DataCenter> toDCList(final List<DataCenterVO> srcList) {
public static List<DataCenter> toDCList(final List<DataCenterJoinVO> srcList) {
return srcList.stream()
.map(DataCenterVOToDataCenterConverter::toDataCenter)
.map(DataCenterJoinVOToDataCenterConverter::toDataCenter)
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,113 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.veeam.api.converter;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.cloudstack.veeam.VeeamControlService;
import org.apache.cloudstack.veeam.api.ClustersRouteHandler;
import org.apache.cloudstack.veeam.api.HostsRouteHandler;
import org.apache.cloudstack.veeam.api.dto.Cpu;
import org.apache.cloudstack.veeam.api.dto.Host;
import org.apache.cloudstack.veeam.api.dto.Ref;
import org.apache.cloudstack.veeam.api.dto.Topology;
import com.cloud.api.query.vo.HostJoinVO;
import com.cloud.host.Status;
import com.cloud.resource.ResourceState;
public class HostJoinVOToHostConverter {
/**
* Convert CloudStack HostJoinVO -> oVirt-like Host.
*
* @param vo HostJoinVO from listHosts (join query)
*/
public static Host toHost(final HostJoinVO vo) {
final Host h = new Host();
final String hostUuid = vo.getUuid();
h.setId(hostUuid);
final String basePath = VeeamControlService.ContextPath.value();
h.setHref(basePath + HostsRouteHandler.BASE_ROUTE + "/" + hostUuid);
// --- name / address ---
// Prefer DNS name if set; otherwise fall back to IP
final String name = vo.getName() != null ? vo.getName() : ("host-" + hostUuid);
h.setName(name);
String addr = vo.getPrivateIpAddress();
h.setAddress(addr);
h.setStatus(mapStatus(vo));
h.setExternalStatus("ok");
// --- cluster ---
final String clusterUuid = vo.getClusterUuid();
h.setCluster(Ref.of(basePath + ClustersRouteHandler.BASE_ROUTE + "/" + clusterUuid, clusterUuid));
// --- CPU ---
final Cpu cpu = new Cpu();
final Topology topo = new Topology();
// oVirt topology: sockets/cores/threads. We approximate.
// If CloudStack has cpuNumber = total cores, treat as sockets count w/ 1 core, 1 thread.
topo.sockets = vo.getCpuSockets();
topo.cores = vo.getCpus();
topo.threads = 1;
// --- Memory ---
h.setMemory(String.valueOf(vo.getTotalMemory()));
h.setMaxSchedulingMemory(String.valueOf(vo.getTotalMemory()));
// --- OS / versions (optional placeholders) ---
// If you want, you can set conservative defaults to match oVirt shape.
h.setType("rhel");
h.setAutoNumaStatus("unknown");
h.setKdumpStatus("disabled");
h.setNumaSupported("false");
h.setReinstallationRequired("false");
h.setUpdateAvailable("false");
// --- links/actions ---
// Start minimal (empty). Add actions only if Veeam tries to follow them.
h.setActions(null);
h.setLink(Collections.emptyList());
return h;
}
public static List<Host> toHostList(final List<HostJoinVO> vos) {
return vos.stream().map(HostJoinVOToHostConverter::toHost).collect(Collectors.toList());
}
private static String mapStatus(final HostJoinVO vo) {
// CloudStack examples:
// state: Up/Down/Maintenance/Error/Disconnected
// status: Up/Down/Connecting/etc
if (vo.isInMaintenanceStates()) return "maintenance";
if (Status.Up.equals(vo.getStatus()) && ResourceState.Enabled.equals(vo.getResourceState())) return "up";
// Default
return "down";
}
}

View File

@ -0,0 +1,80 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.veeam.api.converter;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.cloudstack.veeam.VeeamControlService;
import org.apache.cloudstack.veeam.api.DataCentersRouteHandler;
import org.apache.cloudstack.veeam.api.NetworksRouteHandler;
import org.apache.cloudstack.veeam.api.dto.Network;
import org.apache.cloudstack.veeam.api.dto.NetworkUsages;
import org.apache.cloudstack.veeam.api.dto.Ref;
import com.cloud.api.query.vo.DataCenterJoinVO;
import com.cloud.network.dao.NetworkVO;
public class NetworkVOToNetworkConverter {
public static Network toNetwork(final NetworkVO vo, final Function<Long, DataCenterJoinVO> dcResolver) {
final Network dto = new Network();
final String networkUuid = vo.getUuid();
dto.setId(networkUuid);
final String basePath = VeeamControlService.ContextPath.value();
dto.setHref(basePath + NetworksRouteHandler.BASE_ROUTE + "/" + networkUuid);
String name = vo.getName() != null ? vo.getName() : vo.getTrafficType().name() + "-" + networkUuid;
dto.setName(name);
dto.setDescription(vo.getDisplayText());
dto.setComment("");
dto.setMtu(String.valueOf(vo.getPrivateMtu() != null ? vo.getPrivateMtu() : 0));
dto.setPortIsolation("false");
dto.setStp("false");
dto.setUsages(new NetworkUsages(List.of("vm")));
// Best-effort mapping for vdsm_name
dto.setVdsmName(dto.getName());
// zone -> oVirt datacenter ref
if (dcResolver != null) {
final DataCenterJoinVO dc = dcResolver.apply(vo.getDataCenterId());
if (dc != null) {
final String dcUuid = dc.getUuid();
if (dcUuid != null && !dcUuid.isEmpty()) {
dto.setDataCenter(Ref.of(basePath + DataCentersRouteHandler.BASE_ROUTE + "/" + dcUuid, dcUuid));
}
}
}
dto.setLink(Collections.emptyList());
return dto;
}
public static List<Network> toNetworkList(final List<? extends NetworkVO> vos,
final Function<Long, DataCenterJoinVO> dcResolver) {
return vos.stream()
.map(vo -> toNetwork(vo, dcResolver))
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,65 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.veeam.api.converter;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.cloudstack.veeam.VeeamControlService;
import org.apache.cloudstack.veeam.api.DataCentersRouteHandler;
import org.apache.cloudstack.veeam.api.NetworksRouteHandler;
import org.apache.cloudstack.veeam.api.dto.Ref;
import org.apache.cloudstack.veeam.api.dto.VnicProfile;
import com.cloud.api.query.vo.DataCenterJoinVO;
import com.cloud.network.dao.NetworkVO;
public class NetworkVOToVnicProfileConverter {
public static VnicProfile toVnicProfile(final NetworkVO vo, final Function<Long, DataCenterJoinVO> dcResolver) {
final VnicProfile vnicProfile = new VnicProfile();
final String networkUuid = vo.getUuid();
vnicProfile.setId(networkUuid);
final String basePath = VeeamControlService.ContextPath.value();
vnicProfile.setHref(basePath + NetworksRouteHandler.BASE_ROUTE + "/" + networkUuid);
vnicProfile.setId(networkUuid);
String name = vo.getName() != null ? vo.getName() : vo.getTrafficType().name() + "-" + networkUuid;
vnicProfile.setName(name);
vnicProfile.setNetwork(Ref.of(basePath + NetworksRouteHandler.BASE_ROUTE + "/" + networkUuid, networkUuid));
vnicProfile.setDescription(vo.getDisplayText());
// zone -> oVirt datacenter ref
if (dcResolver != null) {
final DataCenterJoinVO dc = dcResolver.apply(vo.getDataCenterId());
if (dc != null) {
final String dcUuid = dc.getUuid();
if (dcUuid != null && !dcUuid.isEmpty()) {
vnicProfile.setDataCenter(Ref.of(basePath + DataCentersRouteHandler.BASE_ROUTE + "/" + dcUuid, dcUuid));
}
}
}
return vnicProfile;
}
public static List<VnicProfile> toVnicProfileList(final List<NetworkVO> vos, final Function<Long, DataCenterJoinVO> dcResolver) {
return vos.stream()
.map(vo -> toVnicProfile(vo, dcResolver))
.collect(Collectors.toList());
}
}

View File

@ -46,7 +46,7 @@ public final class Api {
public SpecialObjects specialObjects;
@JacksonXmlProperty(localName = "summary")
public Summary summary;
public ApiSummary summary;
// Keep as String to avoid timezone/date parsing friction; you control formatting.
@JacksonXmlProperty(localName = "time")

View File

@ -21,7 +21,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
@JsonInclude(JsonInclude.Include.NON_NULL)
public final class Summary {
public final class ApiSummary {
@JacksonXmlProperty(localName = "hosts")
public SummaryCount hosts;
@ -35,5 +35,5 @@ public final class Summary {
@JacksonXmlProperty(localName = "vms")
public SummaryCount vms;
public Summary() {}
public ApiSummary() {}
}

View File

@ -0,0 +1,36 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.veeam.api.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Certificate {
@JsonProperty("organization")
private String organization;
@JsonProperty("subject")
private String subject;
public String getOrganization() { return organization; }
public void setOrganization(String organization) { this.organization = organization; }
public String getSubject() { return subject; }
public void setSubject(String subject) { this.subject = subject; }
}

View File

@ -18,9 +18,15 @@
package org.apache.cloudstack.veeam.api.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonInclude(JsonInclude.Include.NON_NULL)
public final class Cpu {
@JsonProperty("name")
private String name;
@JsonProperty("speed")
private Integer speed;
public String architecture;
public Topology topology;
@ -30,4 +36,9 @@ public final class Cpu {
this.architecture = architecture;
this.topology = topology;
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Integer getSpeed() { return speed; }
public void setSpeed(Integer speed) { this.speed = speed; }
}

View File

@ -0,0 +1,51 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.veeam.api.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class HardwareInformation {
@JsonProperty("manufacturer")
private String manufacturer;
@JsonProperty("product_name")
private String productName;
@JsonProperty("serial_number")
private String serialNumber;
@JsonProperty("uuid")
private String uuid;
@JsonProperty("version")
private String version;
public String getManufacturer() { return manufacturer; }
public void setManufacturer(String manufacturer) { this.manufacturer = manufacturer; }
public String getProductName() { return productName; }
public void setProductName(String productName) { this.productName = productName; }
public String getSerialNumber() { return serialNumber; }
public void setSerialNumber(String serialNumber) { this.serialNumber = serialNumber; }
public String getUuid() { return uuid; }
public void setUuid(String uuid) { this.uuid = uuid; }
public String getVersion() { return version; }
public void setVersion(String version) { this.version = version; }
}

View File

@ -0,0 +1,169 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.veeam.api.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Host {
@JsonProperty("address")
private String address;
@JsonProperty("auto_numa_status")
private String autoNumaStatus;
@JsonProperty("certificate")
private Certificate certificate;
@JsonProperty("cpu")
private Cpu cpu;
@JsonProperty("external_status")
private String externalStatus;
@JsonProperty("hardware_information")
private HardwareInformation hardwareInformation;
@JsonProperty("kdump_status")
private String kdumpStatus;
@JsonProperty("libvirt_version")
private Version libvirtVersion;
@JsonProperty("max_scheduling_memory")
private String maxSchedulingMemory;
@JsonProperty("memory")
private String memory;
@JsonProperty("numa_supported")
private String numaSupported;
@JsonProperty("os")
private Os os;
@JsonProperty("port")
private String port;
@JsonProperty("protocol")
private String protocol;
@JsonProperty("reinstallation_required")
private String reinstallationRequired;
@JsonProperty("status")
private String status;
@JsonProperty("summary")
private ApiSummary summary;
@JsonProperty("type")
private String type;
@JsonProperty("update_available")
private String updateAvailable;
@JsonProperty("version")
private Version version;
@JsonProperty("vgpu_placement")
private String vgpuPlacement;
@JsonProperty("cluster")
private Ref cluster;
@JsonProperty("actions")
private Actions actions;
@JsonProperty("name")
private String name;
@JsonProperty("comment")
private String comment;
@JsonProperty("link")
private List<Link> link;
@JsonProperty("href")
private String href;
@JsonProperty("id")
private String id;
// getters/setters (generate via IDE)
public String getAddress() { return address; }
public void setAddress(String address) { this.address = address; }
public String getAutoNumaStatus() { return autoNumaStatus; }
public void setAutoNumaStatus(String autoNumaStatus) { this.autoNumaStatus = autoNumaStatus; }
public Certificate getCertificate() { return certificate; }
public void setCertificate(Certificate certificate) { this.certificate = certificate; }
public Cpu getCpu() { return cpu; }
public void setCpu(Cpu cpu) { this.cpu = cpu; }
public String getExternalStatus() { return externalStatus; }
public void setExternalStatus(String externalStatus) { this.externalStatus = externalStatus; }
public HardwareInformation getHardwareInformation() { return hardwareInformation; }
public void setHardwareInformation(HardwareInformation hardwareInformation) { this.hardwareInformation = hardwareInformation; }
public String getKdumpStatus() { return kdumpStatus; }
public void setKdumpStatus(String kdumpStatus) { this.kdumpStatus = kdumpStatus; }
public Version getLibvirtVersion() { return libvirtVersion; }
public void setLibvirtVersion(Version libvirtVersion) { this.libvirtVersion = libvirtVersion; }
public String getMaxSchedulingMemory() { return maxSchedulingMemory; }
public void setMaxSchedulingMemory(String maxSchedulingMemory) { this.maxSchedulingMemory = maxSchedulingMemory; }
public String getMemory() { return memory; }
public void setMemory(String memory) { this.memory = memory; }
public String getNumaSupported() { return numaSupported; }
public void setNumaSupported(String numaSupported) { this.numaSupported = numaSupported; }
public Os getOs() { return os; }
public void setOs(Os os) { this.os = os; }
public String getPort() { return port; }
public void setPort(String port) { this.port = port; }
public String getProtocol() { return protocol; }
public void setProtocol(String protocol) { this.protocol = protocol; }
public String getReinstallationRequired() { return reinstallationRequired; }
public void setReinstallationRequired(String reinstallationRequired) { this.reinstallationRequired = reinstallationRequired; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public ApiSummary getSummary() { return summary; }
public void setSummary(ApiSummary summary) { this.summary = summary; }
public String getType() { return type; }
public void setType(String type) { this.type = type; }
public String getUpdateAvailable() { return updateAvailable; }
public void setUpdateAvailable(String updateAvailable) { this.updateAvailable = updateAvailable; }
public Version getVersion() { return version; }
public void setVersion(Version version) { this.version = version; }
public String getVgpuPlacement() { return vgpuPlacement; }
public void setVgpuPlacement(String vgpuPlacement) { this.vgpuPlacement = vgpuPlacement; }
public Ref getCluster() { return cluster; }
public void setCluster(Ref cluster) { this.cluster = cluster; }
public Actions getActions() { return actions; }
public void setActions(Actions actions) { this.actions = actions; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getComment() { return comment; }
public void setComment(String comment) { this.comment = comment; }
public List<Link> getLink() { return link; }
public void setLink(List<Link> link) { this.link = link; }
public String getHref() { return href; }
public void setHref(String href) { this.href = href; }
public String getId() { return id; }
public void setId(String id) { this.id = id; }
}

View File

@ -0,0 +1,40 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.veeam.api.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class HostSummary {
@JsonProperty("active")
private String active;
@JsonProperty("migrating")
private String migrating;
@JsonProperty("total")
private String total;
public String getActive() { return active; }
public void setActive(String active) { this.active = active; }
public String getMigrating() { return migrating; }
public void setMigrating(String migrating) { this.migrating = migrating; }
public String getTotal() { return total; }
public void setTotal(String total) { this.total = total; }
}

View File

@ -0,0 +1,33 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.veeam.api.dto;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Hosts {
@JsonProperty("host")
private List<Host> host;
public Hosts() {}
public Hosts(List<Host> host) { this.host = host; }
public List<Host> getHost() { return host; }
public void setHost(List<Host> host) { this.host = host; }
}

View File

@ -0,0 +1,85 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.veeam.api.dto;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Network {
private String mtu; // oVirt prints as string
private String portIsolation; // "false"
private String stp; // "false"
private NetworkUsages usages; // { usage: ["vm"] }
private String vdsmName;
private Ref dataCenter;
private String name;
private String description;
private String comment;
@JsonProperty("link")
private List<Link> link;
private String href;
private String id;
public Network() {}
// ---- getters / setters ----
public String getMtu() { return mtu; }
public void setMtu(final String mtu) { this.mtu = mtu; }
public String getPortIsolation() { return portIsolation; }
public void setPortIsolation(final String portIsolation) { this.portIsolation = portIsolation; }
public String getStp() { return stp; }
public void setStp(final String stp) { this.stp = stp; }
public NetworkUsages getUsages() { return usages; }
public void setUsages(final NetworkUsages usages) { this.usages = usages; }
public String getVdsmName() { return vdsmName; }
public void setVdsmName(final String vdsmName) { this.vdsmName = vdsmName; }
public Ref getDataCenter() { return dataCenter; }
public void setDataCenter(final Ref dataCenter) { this.dataCenter = dataCenter; }
public String getName() { return name; }
public void setName(final String name) { this.name = name; }
public String getDescription() { return description; }
public void setDescription(final String description) { this.description = description; }
public String getComment() { return comment; }
public void setComment(final String comment) { this.comment = comment; }
public List<Link> getLink() { return link; }
public void setLink(final List<Link> link) { this.link = link; }
public String getHref() { return href; }
public void setHref(final String href) { this.href = href; }
public String getId() { return id; }
public void setId(final String id) { this.id = id; }
}

View File

@ -0,0 +1,42 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.veeam.api.dto;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class NetworkUsages {
private List<String> usage;
public NetworkUsages() {
}
public NetworkUsages(final List<String> usage) {
this.usage = usage;
}
public List<String> getUsage() {
return usage;
}
public void setUsage(final List<String> usage) {
this.usage = usage;
}
}

View File

@ -0,0 +1,33 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.veeam.api.dto;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Networks {
@JsonProperty("network")
private List<Network> network;
public Networks() {}
public Networks(List<Network> network) { this.network = network; }
public List<Network> getNetwork() { return network; }
public void setNetwork(List<Network> network) { this.network = network; }
}

View File

@ -0,0 +1,41 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.veeam.api.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class OsVersion {
@JsonProperty("full_version")
private String fullVersion;
@JsonProperty("major")
private String major;
@JsonProperty("minor")
private String minor;
public String getFullVersion() { return fullVersion; }
public void setFullVersion(String fullVersion) { this.fullVersion = fullVersion; }
public String getMajor() { return major; }
public void setMajor(String major) { this.major = major; }
public String getMinor() { return minor; }
public void setMinor(String minor) { this.minor = minor; }
}

View File

@ -0,0 +1,99 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.veeam.api.dto;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude;
/**
* oVirt-like vNIC profile element.
* Every vNIC profile MUST reference exactly one network.
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public class VnicProfile {
private String href;
private String id;
private String name;
private String description;
private Ref network;
private Ref dataCenter;
private List<Link> link;
public VnicProfile() {
}
public String getHref() {
return href;
}
public void setHref(final String href) {
this.href = href;
}
public String getId() {
return id;
}
public void setId(final String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(final String description) {
this.description = description;
}
public Ref getNetwork() {
return network;
}
public void setNetwork(final Ref network) {
this.network = network;
}
public Ref getDataCenter() {
return dataCenter;
}
public void setDataCenter(final Ref dataCenter) {
this.dataCenter = dataCenter;
}
public List<Link> getLink() {
return link;
}
public void setLink(final List<Link> link) {
this.link = link;
}
}

View File

@ -0,0 +1,49 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.veeam.api.dto;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Root container for /ovirt-engine/api/vnicprofiles
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public class VnicProfiles {
@JsonProperty("vnic_profile")
private List<VnicProfile> vnicProfile;
public VnicProfiles() {
}
public VnicProfiles(final List<VnicProfile> vnicProfile) {
this.vnicProfile = vnicProfile;
}
public List<VnicProfile> getVnicProfile() {
return vnicProfile;
}
public void setVnicProfile(final List<VnicProfile> vnicProfile) {
this.vnicProfile = vnicProfile;
}
}

View File

@ -41,7 +41,7 @@ public class BearerOrBasicAuthFilter implements Filter {
// Keep these aligned with SsoService (move to ConfigKeys later)
public static final List<String> REQUIRED_SCOPES = List.of("ovirt-app-admin", "ovirt-app-portal");
public static final String ISSUER = "veeam-control";
private static final String HMAC_SECRET = "change-this-super-secret-key-change-this";
public static final String HMAC_SECRET = "change-this-super-secret-key-change-this";
@Override public void init(FilterConfig filterConfig) {}
@Override public void destroy() {}

View File

@ -37,7 +37,6 @@ import com.cloud.utils.component.ManagerBase;
public class SsoService extends ManagerBase implements RouteHandler {
private static final String BASE_ROUTE = "/sso";
private static final String HMAC_SECRET = "change-this-super-secret-key-change-this"; // >= 32 chars recommended
private static final long DEFAULT_TTL_SECONDS = 3600;
// Replace with your real credential validation (CloudStack account, config, etc.)
@ -104,7 +103,8 @@ public class SsoService extends ManagerBase implements RouteHandler {
final long ttl = DEFAULT_TTL_SECONDS;
final String token;
try {
token = JwtUtil.issueHs256Jwt(BearerOrBasicAuthFilter.ISSUER, username, effectiveScope, ttl, HMAC_SECRET);
token = JwtUtil.issueHs256Jwt(BearerOrBasicAuthFilter.ISSUER, username, effectiveScope, ttl,
BearerOrBasicAuthFilter.HMAC_SECRET);
} catch (Exception e) {
io.getWriter().write(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
Map.of("error", "server_error", "error_description", "Failed to issue token"), outFormat);

View File

@ -32,9 +32,12 @@
</bean>
<bean id="veeamControlApiService" class="org.apache.cloudstack.veeam.api.ApiService" />
<bean id="vmsRouteHandler" class="org.apache.cloudstack.veeam.api.VmsRouteHandler"/>
<bean id="dataCentersRouteHandler" class="org.apache.cloudstack.veeam.api.DataCentersRouteHandler"/>
<bean id="clustersRouteHandler" class="org.apache.cloudstack.veeam.api.ClustersRouteHandler"/>
<bean id="hostsRouteHandler" class="org.apache.cloudstack.veeam.api.HostsRouteHandler"/>
<bean id="networksRouteHandler" class="org.apache.cloudstack.veeam.api.NetworksRouteHandler"/>
<bean id="vnicProfilesRouteHandler" class="org.apache.cloudstack.veeam.api.VnicProfilesRouteHandler"/>
<bean id="vmsRouteHandler" class="org.apache.cloudstack.veeam.api.VmsRouteHandler"/>
<bean id="disksRouteHandler" class="org.apache.cloudstack.veeam.api.DisksRouteHandler"/>
<bean id="veeamControlSsoService" class="org.apache.cloudstack.veeam.sso.SsoService"/>