This is an automated email from the ASF dual-hosted git repository.

Pearl1594 pushed a commit to branch netris-improvements
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit f73bbdd5909b1bf17ae2a1cb62fe288f3f224b51
Author: Pearl Dsilva <[email protected]>
AuthorDate: Mon Jul 6 09:21:58 2026 -0400

    Hide VPN sections and prevent enabling it when service isn't enabled in the 
vpc offering
    
    * Hide VPN sections and prevent enabling it when service isn't enabled in 
the vpc offering
    
    * update
    
    ---------
    
    Co-authored-by: Pearl Dsilva <[email protected]>
---
 .../network/vpn/RemoteAccessVpnManagerImpl.java    |  6 +++++
 .../cloud/network/vpn/Site2SiteVpnManagerImpl.java |  3 +++
 ui/src/config/section/network.js                   |  1 +
 ui/src/views/network/VpcTab.vue                    |  4 ++--
 ui/src/views/network/VpnDetails.vue                | 28 ++++++++++++++--------
 5 files changed, 30 insertions(+), 12 deletions(-)

diff --git 
a/server/src/main/java/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java 
b/server/src/main/java/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java
index 24c2f2221d9..5e5261f657b 100644
--- a/server/src/main/java/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java
+++ b/server/src/main/java/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java
@@ -69,6 +69,7 @@ import com.cloud.network.rules.RulesManager;
 import com.cloud.network.vpc.Vpc;
 import com.cloud.network.vpc.VpcManager;
 import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
 import com.cloud.projects.Project.ListProjectResourcesCriteria;
 import com.cloud.server.ConfigurationServer;
 import com.cloud.user.Account;
@@ -134,6 +135,8 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase 
implements RemoteAcc
     ConfigurationServer _configServer;
     @Inject
     VpcDao _vpcDao;
+    @Inject
+    VpcOfferingServiceMapDao _vpcOfferingServiceMapDao;
 
     int _userLimit;
     int _pskLength;
@@ -243,6 +246,9 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase 
implements RemoteAcc
                 validateIpAddressForVpnServiceOnNetwork(network, ipAddress);
             } else {
                 Vpc vpc = _vpcDao.findById(vpcId);
+                if 
(!_vpcOfferingServiceMapDao.areServicesSupportedByVpcOffering(vpc.getVpcOfferingId(),
 new Network.Service[]{Network.Service.Vpn})) {
+                    throw new 
InvalidParameterValueException(String.format("Vpn service is not supported for 
VPC: %s (%s) ", vpc.getName(), vpc.getUuid()));
+                }
                 cidr = NetUtils.getCidr(vpc.getCidr());
                 validateIpAddressForVpnServiceOnVpc(vpc, ipAddress);
             }
diff --git 
a/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java 
b/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java
index ad1d1f02682..34e2cf71249 100644
--- a/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java
+++ b/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java
@@ -144,6 +144,9 @@ public class Site2SiteVpnManagerImpl extends ManagerBase 
implements Site2SiteVpn
         if (vpc == null) {
             throw new InvalidParameterValueException("Invalid VPC " + vpcId + 
" for site to site vpn gateway creation!");
         }
+        if 
(!vpcOfferingServiceMapDao.areServicesSupportedByVpcOffering(vpc.getVpcOfferingId(),
 new Network.Service[]{Network.Service.Vpn})) {
+            throw new InvalidParameterValueException(String.format("Vpn 
service is not supported for VPC: %s (%s) ", vpc.getName(), vpc.getUuid()));
+        }
         Site2SiteVpnGatewayVO gws = _vpnGatewayDao.findByVpcId(vpcId);
         if (gws != null) {
             throw new InvalidParameterValueException(String.format("The VPN 
gateway of VPC %s already existed!", vpc));
diff --git a/ui/src/config/section/network.js b/ui/src/config/section/network.js
index acc7424c9f0..a8727811fb6 100644
--- a/ui/src/config/section/network.js
+++ b/ui/src/config/section/network.js
@@ -803,6 +803,7 @@ export default {
       }, {
         name: 'vpn',
         component: shallowRef(defineAsyncComponent(() => 
import('@/views/network/VpnDetails.vue'))),
+        networkServiceFilter: networkService => networkService.filter(x => 
x.name === 'Vpn').length > 0,
         show: (record) => { return record.issourcenat || 
record.virtualmachinetype === 'DomainRouter' || !record.hasrules }
       },
       {
diff --git a/ui/src/views/network/VpcTab.vue b/ui/src/views/network/VpcTab.vue
index 12e21cd8ec9..f8f3c88e78d 100644
--- a/ui/src/views/network/VpcTab.vue
+++ b/ui/src/views/network/VpcTab.vue
@@ -252,7 +252,7 @@
           </a-spin>
         </a-modal>
       </a-tab-pane>
-      <a-tab-pane :tab="$t('label.vpn.gateway')" key="vpngw" 
v-if="'listVpnGateways' in $store.getters.apis">
+      <a-tab-pane :tab="$t('label.vpn.gateway')" key="vpngw" 
v-if="'listVpnGateways' in $store.getters.apis && resource.service && 
resource.service.some(s => s.name === 'Vpn')">
         <a-button
           v-if="vpnGateways.length === 0"
           type="dashed"
@@ -313,7 +313,7 @@
           </a-spin>
         </a-modal>
       </a-tab-pane>
-      <a-tab-pane :tab="$t('label.vpn.connection')" key="vpnc" 
v-if="'listVpnConnections' in $store.getters.apis">
+      <a-tab-pane :tab="$t('label.vpn.connection')" key="vpnc" 
v-if="'listVpnConnections' in $store.getters.apis && resource.service && 
resource.service.some(s => s.name === 'Vpn')">
         <a-button
           type="dashed"
           style="width: 100%"
diff --git a/ui/src/views/network/VpnDetails.vue 
b/ui/src/views/network/VpnDetails.vue
index 2a75bb3c22e..3dd6c92c7f8 100644
--- a/ui/src/views/network/VpnDetails.vue
+++ b/ui/src/views/network/VpnDetails.vue
@@ -216,16 +216,24 @@ export default {
         this.$notifyError(error)
       })
       if (this.resource.vpcid) {
-        this.vpnGatewayEnabled = true
-        getAPI('listVpnGateways', {
-          vpcid: this.resource.vpcid,
-          listAll: true
-        }).then(response => {
-          const vpnGateways = response.listvpngatewaysresponse.vpngateway || []
-          for (const vpnGateway of vpnGateways) {
-            if (vpnGateway.publicip === this.resource.ipaddress) {
-              this.vpnGateway = vpnGateway
-            }
+        getAPI('listVPCs', { id: this.resource.vpcid, listAll: true 
}).then(vpcResponse => {
+          const vpc = vpcResponse.listvpcsresponse?.vpc?.[0]
+          if (vpc?.service?.some(s => s.name === 'Vpn')) {
+            this.vpnGatewayEnabled = true
+            getAPI('listVpnGateways', {
+              vpcid: this.resource.vpcid,
+              listAll: true
+            }).then(response => {
+              const vpnGateways = response.listvpngatewaysresponse.vpngateway 
|| []
+              for (const vpnGateway of vpnGateways) {
+                if (vpnGateway.publicip === this.resource.ipaddress) {
+                  this.vpnGateway = vpnGateway
+                }
+              }
+            }).catch(error => {
+              console.log(error)
+              this.$notifyError(error)
+            })
           }
         }).catch(error => {
           console.log(error)

Reply via email to