This is an automated email from the ASF dual-hosted git repository.
dahn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/main by this push:
new f985a67f4d6 Fixes:#7837: Add isolationMethods and vlan to
TrafficTypeResponse (#8151)
f985a67f4d6 is described below
commit f985a67f4d624e9fb1fd2bf5efad7ebcb157e1ee
Author: Madhukar Mishra <[email protected]>
AuthorDate: Wed Nov 12 20:19:52 2025 +0530
Fixes:#7837: Add isolationMethods and vlan to TrafficTypeResponse (#8151)
Co-authored-by: dahn <[email protected]>
Co-authored-by: dahn <[email protected]>
---
.../cloud/network/PhysicalNetworkTrafficType.java | 2 +
.../command/admin/usage/ListTrafficTypesCmd.java | 3 +-
.../api/response/TrafficTypeResponse.java | 24 ++++++
.../main/java/com/cloud/api/ApiResponseHelper.java | 4 +
.../java/com/cloud/api/ApiResponseHelperTest.java | 85 ++++++++++++++++------
.../smoke/test_network_traffic_type_api.py | 73 +++++++++++++++++++
6 files changed, 167 insertions(+), 24 deletions(-)
diff --git
a/api/src/main/java/com/cloud/network/PhysicalNetworkTrafficType.java
b/api/src/main/java/com/cloud/network/PhysicalNetworkTrafficType.java
index 9676badb4e9..d3804cd29da 100644
--- a/api/src/main/java/com/cloud/network/PhysicalNetworkTrafficType.java
+++ b/api/src/main/java/com/cloud/network/PhysicalNetworkTrafficType.java
@@ -41,4 +41,6 @@ public interface PhysicalNetworkTrafficType extends
InternalIdentity, Identity {
String getHypervNetworkLabel();
String getOvm3NetworkLabel();
+
+ String getVlan();
}
diff --git
a/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypesCmd.java
b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypesCmd.java
index d106a736fca..c204c67d465 100644
---
a/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypesCmd.java
+++
b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypesCmd.java
@@ -26,14 +26,13 @@ import org.apache.cloudstack.api.BaseListCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
-import org.apache.cloudstack.api.response.ProviderResponse;
import org.apache.cloudstack.api.response.TrafficTypeResponse;
import com.cloud.network.PhysicalNetworkTrafficType;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
-@APICommand(name = "listTrafficTypes", description = "Lists traffic types of a
given physical network.", responseObject = ProviderResponse.class, since =
"3.0.0",
+@APICommand(name = "listTrafficTypes", description = "Lists traffic types of a
given physical network.", responseObject = TrafficTypeResponse.class, since =
"3.0.0",
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class ListTrafficTypesCmd extends BaseListCmd {
diff --git
a/api/src/main/java/org/apache/cloudstack/api/response/TrafficTypeResponse.java
b/api/src/main/java/org/apache/cloudstack/api/response/TrafficTypeResponse.java
index 9a79b072465..281ed6736ee 100644
---
a/api/src/main/java/org/apache/cloudstack/api/response/TrafficTypeResponse.java
+++
b/api/src/main/java/org/apache/cloudstack/api/response/TrafficTypeResponse.java
@@ -56,6 +56,14 @@ public class TrafficTypeResponse extends BaseResponse {
@Param(description = "The network name label of the physical device
dedicated to this traffic on a HyperV host")
private String hypervNetworkLabel;
+ @SerializedName(ApiConstants.VLAN)
+ @Param(description = "The VLAN id to be used for Management traffic by
VMware host")
+ private String vlan;
+
+ @SerializedName(ApiConstants.ISOLATION_METHODS)
+ @Param(description = "isolation methods for the physical network traffic")
+ private String isolationMethods;
+
@SerializedName(ApiConstants.OVM3_NETWORK_LABEL)
@Param(description = "The network name of the physical device dedicated to
this traffic on an OVM3 host")
private String ovm3NetworkLabel;
@@ -128,4 +136,20 @@ public class TrafficTypeResponse extends BaseResponse {
public void setOvm3Label(String ovm3Label) {
this.ovm3NetworkLabel = ovm3Label;
}
+
+ public String getIsolationMethods() {
+ return isolationMethods;
+ }
+
+ public void setIsolationMethods(String isolationMethods) {
+ this.isolationMethods = isolationMethods;
+ }
+
+ public String getVlan() {
+ return vlan;
+ }
+
+ public void setVlan(String vlan) {
+ this.vlan = vlan;
+ }
}
diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java
b/server/src/main/java/com/cloud/api/ApiResponseHelper.java
index 404cefb68fe..1ebbd4f35b5 100644
--- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java
@@ -3256,6 +3256,9 @@ public class ApiResponseHelper implements
ResponseGenerator {
PhysicalNetwork pnet =
ApiDBUtils.findPhysicalNetworkById(result.getPhysicalNetworkId());
if (pnet != null) {
response.setPhysicalNetworkId(pnet.getUuid());
+ if (!pnet.getIsolationMethods().isEmpty()) {
+ response.setIsolationMethods(String.join(",",
pnet.getIsolationMethods()));
+ }
}
if (result.getTrafficType() != null) {
response.setTrafficType(result.getTrafficType().toString());
@@ -3266,6 +3269,7 @@ public class ApiResponseHelper implements
ResponseGenerator {
response.setVmwareLabel(result.getVmwareNetworkLabel());
response.setHypervLabel(result.getHypervNetworkLabel());
response.setOvm3Label(result.getOvm3NetworkLabel());
+ response.setVlan(result.getVlan());
response.setObjectName("traffictype");
return response;
diff --git a/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java
b/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java
index 223b0740cf2..d4f477383ef 100644
--- a/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java
+++ b/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java
@@ -16,14 +16,6 @@
// under the License.
package com.cloud.api;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -37,9 +29,24 @@ import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.springframework.test.util.ReflectionTestUtils;
+
import org.apache.cloudstack.annotation.dao.AnnotationDao;
+import org.apache.cloudstack.api.ResponseObject;
import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse;
import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse;
+import org.apache.cloudstack.api.response.ConsoleSessionResponse;
import org.apache.cloudstack.api.response.DirectDownloadCertificateResponse;
import org.apache.cloudstack.api.response.GuestOSCategoryResponse;
import org.apache.cloudstack.api.response.IpQuarantineResponse;
@@ -48,26 +55,17 @@ import
org.apache.cloudstack.api.response.ResourceIconResponse;
import org.apache.cloudstack.api.response.TemplateResponse;
import org.apache.cloudstack.api.response.UnmanagedInstanceResponse;
import org.apache.cloudstack.api.response.UsageRecordResponse;
+import org.apache.cloudstack.api.response.TrafficTypeResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.usage.UsageService;
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.MockedStatic;
-import org.mockito.Mockito;
-import org.mockito.Spy;
-import org.mockito.junit.MockitoJUnitRunner;
-import org.springframework.test.util.ReflectionTestUtils;
import com.cloud.capacity.Capacity;
import com.cloud.configuration.Resource;
import com.cloud.domain.DomainVO;
import com.cloud.host.HostVO;
+import com.cloud.network.Networks;
+import com.cloud.network.PhysicalNetworkTrafficType;
import com.cloud.network.PublicIpQuarantine;
import com.cloud.network.as.AutoScaleVmGroup;
import com.cloud.network.as.AutoScaleVmGroupVO;
@@ -78,6 +76,8 @@ import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.LoadBalancerVO;
import com.cloud.network.dao.NetworkServiceMapDao;
import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
import com.cloud.resource.icon.ResourceIconVO;
import com.cloud.server.ResourceIcon;
import com.cloud.server.ResourceIconManager;
@@ -97,8 +97,16 @@ import com.cloud.utils.net.Ip;
import com.cloud.vm.ConsoleSessionVO;
import com.cloud.vm.NicSecondaryIp;
import com.cloud.vm.VMInstanceVO;
-import org.apache.cloudstack.api.ResponseObject;
-import org.apache.cloudstack.api.response.ConsoleSessionResponse;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
@RunWith(MockitoJUnitRunner.class)
public class ApiResponseHelperTest {
@@ -417,6 +425,39 @@ public class ApiResponseHelperTest {
}
}
+ @Test
+ public void testCreateTrafficTypeResponse() {
+ PhysicalNetworkVO pnet = new PhysicalNetworkVO();
+ pnet.addIsolationMethod("VXLAN");
+ pnet.addIsolationMethod("STT");
+
+ try (MockedStatic<ApiDBUtils> ignored =
Mockito.mockStatic(ApiDBUtils.class)) {
+
when(ApiDBUtils.findPhysicalNetworkById(anyLong())).thenReturn(pnet);
+ String xenLabel = "xen";
+ String kvmLabel = "kvm";
+ String vmwareLabel = "vmware";
+ String simulatorLabel = "simulator";
+ String hypervLabel = "hyperv";
+ String ovmLabel = "ovm";
+ String vlan = "vlan";
+ String trafficType = "Public";
+ PhysicalNetworkTrafficType pnetTrafficType = new
PhysicalNetworkTrafficTypeVO(pnet.getId(),
Networks.TrafficType.getTrafficType(trafficType), xenLabel, kvmLabel,
vmwareLabel, simulatorLabel, vlan, hypervLabel, ovmLabel);
+
+ TrafficTypeResponse response =
apiResponseHelper.createTrafficTypeResponse(pnetTrafficType);
+
assertFalse(UUID.fromString(response.getId()).toString().isEmpty());
+ assertEquals(response.getphysicalNetworkId(), pnet.getUuid());
+ assertEquals(response.getTrafficType(), trafficType);
+ assertEquals(response.getXenLabel(), xenLabel);
+ assertEquals(response.getKvmLabel(), kvmLabel);
+ assertEquals(response.getVmwareLabel(), vmwareLabel);
+ assertEquals(response.getHypervLabel(), hypervLabel);
+ assertEquals(response.getOvm3Label(), ovmLabel);
+ assertEquals(response.getVlan(), vlan);
+ assertEquals(response.getIsolationMethods(), "VXLAN,STT");
+
+ }
+ }
+
private UnmanagedInstanceTO getUnmanagedInstaceForTests() {
UnmanagedInstanceTO instance = Mockito.mock(UnmanagedInstanceTO.class);
Mockito.when(instance.getPowerState()).thenReturn(UnmanagedInstanceTO.PowerState.PowerOff);
diff --git a/test/integration/smoke/test_network_traffic_type_api.py
b/test/integration/smoke/test_network_traffic_type_api.py
new file mode 100644
index 00000000000..10e9df47098
--- /dev/null
+++ b/test/integration/smoke/test_network_traffic_type_api.py
@@ -0,0 +1,73 @@
+# 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.
+
+# Import Local Modules
+from marvin.cloudstackTestCase import cloudstackTestCase
+from marvin.lib.base import (
+ TrafficType,
+ PhysicalNetwork,
+ Zone,
+)
+from nose.plugins.attrib import attr
+
+
+class TestTrafficTypeApi(cloudstackTestCase):
+ @classmethod
+ def setUpClass(cls):
+ cls.test_client = super(TestTrafficTypeApi, cls).getClsTestClient()
+ cls.api_client = cls.testClient.getApiClient()
+ cls.services = cls.testClient.getParsedTestDataConfig()
+ cls._cleanup = []
+ cls.services["advanced_sg"]["zone"]["name"] = "TestTrafficTypeApi-zone"
+ cls.zone = Zone.create(cls.api_client,
cls.services["advanced_sg"]["zone"])
+ cls._cleanup.append(cls.zone)
+
+ cls.physical_network = PhysicalNetwork.create(
+ cls.api_client,
+ cls.services["l2-network"],
+ isolationmethods="VLAN",
+ zoneid=cls.zone.id,
+ )
+ cls._cleanup.append(cls.physical_network)
+
+ @classmethod
+ def tearDownClass(cls):
+ super(TestTrafficTypeApi, cls).tearDownClass()
+
+
+ @attr(tags=["advanced"], required_hardware="false")
+ def test_list_api_fields(self):
+ traffic_type = TrafficType.add(
+ self.api_client,
+ physicalnetworkid=self.physical_network.id,
+ kvmnetworklabel="kvm",
+ traffictype="Public",
+ vlan="100",
+ ).traffictype
+
+ traffic_types = TrafficType.list(
+ self.api_client,
+ physicalnetworkid=self.physical_network.id
+ )
+
+ assert len(traffic_types) == 1
+ response = traffic_types[0]
+ self.assertEqual(response.id, traffic_type.id)
+ self.assertEqual(response.kvmnetworklabel, "kvm")
+ self.assertEqual(response.traffictype, "Public")
+ self.assertEqual(response.vlan, "100")
+ self.assertEqual(response.isolationmethods, "VLAN")