diff --git a/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java
index bcf2c6176efe..f46b946d50c1 100644
--- a/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java
@@ -1079,6 +1079,11 @@ private void applyResolvedValuesToCommand(CloneVPCOfferingCmd cmd, VpcOfferingVO
ConfigurationManagerImpl.setField(cmd, "specifyAsNumber", sourceOffering.isSpecifyAsNumber());
}
+ Boolean conserveModeFieldValue = getRawFieldValue(cmd, "conserveMode", Boolean.class);
+ if (conserveModeFieldValue == null) {
+ ConfigurationManagerImpl.setField(cmd, "conserveMode", sourceOffering.isConserveMode());
+ }
+
if (cmd.getInternetProtocol() == null) {
String internetProtocol = vpcOfferingDetailsDao.getDetail(sourceOffering.getId(), ApiConstants.INTERNET_PROTOCOL);
if (internetProtocol != null) {
diff --git a/ui/src/views/offering/CloneNetworkOffering.vue b/ui/src/views/offering/CloneNetworkOffering.vue
index 0cd5e733b24f..4b4343a823d5 100644
--- a/ui/src/views/offering/CloneNetworkOffering.vue
+++ b/ui/src/views/offering/CloneNetworkOffering.vue
@@ -1228,12 +1228,7 @@ export default {
},
handleSupportedServiceChange (service, checked, provider) {
if (checked) {
- const correctProvider = this.serviceProviderMap[service]
- if (correctProvider && provider !== correctProvider) {
- this.selectedServiceProviderMap[service] = correctProvider
- } else {
- this.selectedServiceProviderMap[service] = provider
- }
+ this.selectedServiceProviderMap[service] = provider
} else {
delete this.selectedServiceProviderMap[service]
}
@@ -1294,6 +1289,10 @@ export default {
params.guestiptype = values.guestiptype
}
+ if (values.forvpc === true) {
+ params.forvpc = true
+ }
+
// Use composable for service capability params
if (this.selectedServiceProviderMap != null) {
buildServiceCapabilityParams(params, values, this.selectedServiceProviderMap, this.registeredServicePackages)
diff --git a/ui/src/views/offering/CloneVpcOffering.vue b/ui/src/views/offering/CloneVpcOffering.vue
index 6adbfafad611..67ea30856397 100644
--- a/ui/src/views/offering/CloneVpcOffering.vue
+++ b/ui/src/views/offering/CloneVpcOffering.vue
@@ -212,6 +212,12 @@
+
+
+
+
+
+
{ isPublic = val }" />
@@ -308,7 +314,6 @@ export default {
return {
selectedDomains: [],
selectedZones: [],
- isConserveMode: true,
internetProtocolValue: 'ipv4',
domains: [],
domainLoading: false,
@@ -405,7 +410,7 @@ export default {
this.fetchZoneData()
this.fetchIpv6NetworkOfferingConfiguration()
this.fetchRoutedNetworkConfiguration()
- this.fetchSupportedServiceData()
+ this.fetchSupportedServiceData(true)
},
isAdmin () {
return isAdmin()
@@ -455,7 +460,7 @@ export default {
this.zoneLoading = false
})
},
- fetchSupportedServiceData () {
+ fetchSupportedServiceData (isInitialLoad = false) {
this.supportedServiceLoading = true
getAPI('listSupportedNetworkServices', {}).then(json => {
const networkServices = json.listsupportednetworkservicesresponse.networkservice || []
@@ -491,7 +496,11 @@ export default {
this.supportedServiceLoading = false
this.$nextTick(() => {
- this.populateFormFromResource()
+ if (isInitialLoad) {
+ this.populateFormFromResource()
+ } else {
+ this.syncServiceSelectionsForCurrentMode()
+ }
})
})
},
@@ -656,6 +665,45 @@ export default {
this.form.nsxsupportlb = Boolean(this.serviceProviderMap.Lb)
}
},
+ syncServiceSelectionsForCurrentMode () {
+ const updatedServices = this.supportedServices.map(svc => {
+ const serviceCopy = { ...svc, provider: [...svc.provider] }
+ const providerName = this.selectedServiceProviderMap[serviceCopy.name]
+
+ if (providerName) {
+ const providerIndex = serviceCopy.provider.findIndex(p => p.name === providerName)
+ if (providerIndex > 0) {
+ const targetProvider = serviceCopy.provider[providerIndex]
+ serviceCopy.provider.splice(providerIndex, 1)
+ serviceCopy.provider.unshift(targetProvider)
+ }
+ serviceCopy.defaultChecked = true
+ serviceCopy.selectedProvider = providerName
+ } else {
+ serviceCopy.defaultChecked = false
+ serviceCopy.selectedProvider = null
+ }
+ return serviceCopy
+ })
+ this.supportedServices = updatedServices
+
+ const availableNames = new Set(updatedServices.map(svc => svc.name))
+ Object.keys(this.selectedServiceProviderMap).forEach(name => {
+ if (!availableNames.has(name)) {
+ delete this.selectedServiceProviderMap[name]
+ }
+ })
+
+ this.connectivityServiceChecked = Boolean(this.selectedServiceProviderMap.Connectivity)
+ this.sourceNatServiceChecked = Boolean(this.selectedServiceProviderMap.SourceNat)
+
+ this.$nextTick(() => {
+ this.servicesReady = true
+ this.$nextTick(() => {
+ this.checkVpcVirtualRouterForServices()
+ })
+ })
+ },
async handleProviderChange (value) {
this.provider = value
if (this.provider === 'NSX') {
@@ -682,12 +730,7 @@ export default {
},
handleSupportedServiceChange (service, checked, provider) {
if (checked) {
- const correctProvider = this.serviceProviderMap[service]
- if (correctProvider && provider !== correctProvider) {
- this.selectedServiceProviderMap[service] = correctProvider
- } else {
- this.selectedServiceProviderMap[service] = provider
- }
+ this.selectedServiceProviderMap[service] = provider
} else {
delete this.selectedServiceProviderMap[service]
}
@@ -818,6 +861,10 @@ export default {
params.enable = values.enable
}
+ if (values.conservemode !== undefined) {
+ params.conservemode = values.conservemode
+ }
+
this.loading = true
postAPI('cloneVPCOffering', params).then(json => {
this.$message.success(`${this.$t('message.success.clone.vpc.offering')} ${values.name}`)