From ccaece37140048b7cdf2fe6a14bd1db54938f17d Mon Sep 17 00:00:00 2001 From: Sachin Ramesh <104337442+sachinrameshn@users.noreply.github.com> Date: Thu, 31 Oct 2024 21:47:11 +0530 Subject: [PATCH] feat(dedicated): add vrack orderable in ipv4 (#12779) ref: MANAGER-14886 Signed-off-by: Sachin Ramesh --- .../ip/agoraOrder/ip-ip-agoraOrder.service.js | 9 ++ .../ip/agoraOrder/ipv4/ipv4.constant.js | 24 ++++ .../ip/agoraOrder/ipv4/ipv4.controller.js | 136 ++++++++++++++---- .../components/ip/agoraOrder/ipv4/ipv4.html | 11 +- .../ip/agoraOrder/ipv4/ipv4.service.js | 21 ++- 5 files changed, 167 insertions(+), 34 deletions(-) diff --git a/packages/manager/apps/dedicated/client/app/components/ip/agoraOrder/ip-ip-agoraOrder.service.js b/packages/manager/apps/dedicated/client/app/components/ip/agoraOrder/ip-ip-agoraOrder.service.js index 01434d5e0fe3..8a10b9a8b6db 100644 --- a/packages/manager/apps/dedicated/client/app/components/ip/agoraOrder/ip-ip-agoraOrder.service.js +++ b/packages/manager/apps/dedicated/client/app/components/ip/agoraOrder/ip-ip-agoraOrder.service.js @@ -40,6 +40,7 @@ export default class IpAgoraOrder { planCode, productId = 'ip', pricingMode = 'default', + productRegionName, quantity = 1, serviceName, datacenter, @@ -76,6 +77,14 @@ export default class IpAgoraOrder { }); } + if (productRegionName) { + const [region] = productRegionName?.split('-') || []; + productToOrder.configuration.push({ + label: 'region', + value: region?.trim()?.toLowerCase(), + }); + } + if (destination) { productToOrder.configuration.push({ label: 'destination', diff --git a/packages/manager/apps/dedicated/client/app/components/ip/agoraOrder/ipv4/ipv4.constant.js b/packages/manager/apps/dedicated/client/app/components/ip/agoraOrder/ipv4/ipv4.constant.js index 59eaded98642..7918a1ae79a8 100644 --- a/packages/manager/apps/dedicated/client/app/components/ip/agoraOrder/ipv4/ipv4.constant.js +++ b/packages/manager/apps/dedicated/client/app/components/ip/agoraOrder/ipv4/ipv4.constant.js @@ -26,6 +26,10 @@ export const PRODUCT_TYPES = { apiTypeName: 'parking', typeName: 'parking', }, + vrack: { + apiTypeName: 'VRACK', + typeName: 'VRACK', + }, }; export const IP_AGORA = { @@ -123,6 +127,25 @@ export const IP_LOCATION_GROUPS_BASED_ON_DATACENTER = [ { labels: ['USA'], countries: ['us'], datacenter: ['HIL', 'VIN'] }, ]; +/* To be replaced once we have region list coming from API for the Vrack, as of now consider IPV6 regions */ +export const REGION_TO_DATACENTER = { + 'eu-west-rbx': 'RBX', + 'eu-west-gra': 'GRA', + 'eu-west-sbg': 'SBG', + 'eu-west-par': 'PAR', + 'labeu-west-1-preprod': 'CR2', + 'eu-west-lim': 'LIM', + 'eu-central-waw': 'WAW', + 'eu-west-eri': 'ERI', + 'ca-east-bhs': 'BHS', + 'ca-east-tor': 'YYZ', + 'ap-southeast-sgp': 'SGP', + 'ap-southeast-syd': 'SYD', + 'ap-south-mum': 'YNM', + 'us-east-vin': 'VIN', + 'us-west-hil': 'HIL', +}; + export default { FETCH_PRICE_MAX_TRIES, IP_LOCATION_GROUPS, @@ -137,4 +160,5 @@ export default { DATACENTER_TO_COUNTRY, DATACENTER_TO_REGION, IP_LOCATION_GROUPS_BASED_ON_DATACENTER, + REGION_TO_DATACENTER, }; diff --git a/packages/manager/apps/dedicated/client/app/components/ip/agoraOrder/ipv4/ipv4.controller.js b/packages/manager/apps/dedicated/client/app/components/ip/agoraOrder/ipv4/ipv4.controller.js index 502c2ab5dca8..06ef3c678751 100644 --- a/packages/manager/apps/dedicated/client/app/components/ip/agoraOrder/ipv4/ipv4.controller.js +++ b/packages/manager/apps/dedicated/client/app/components/ip/agoraOrder/ipv4/ipv4.controller.js @@ -29,6 +29,7 @@ import { DATACENTER_TO_COUNTRY, DATACENTER_TO_REGION, IP_LOCATION_GROUPS_BASED_ON_DATACENTER, + REGION_TO_DATACENTER, } from './ipv4.constant'; export default class AgoraIpV4OrderController { @@ -72,8 +73,8 @@ export default class AgoraIpV4OrderController { $onInit() { this.catalogByLocation = []; - this.isParkingIp = false; - this.parkingIpOffers = []; + this.isParkingIpOrVrack = false; + this.IpOffers = []; this.model = { params: {}, selectedService: null, @@ -116,6 +117,7 @@ export default class AgoraIpV4OrderController { .all({ user: this.User.getUser(), services: this.Ipv4AgoraOrder.getServices(), + vrack: this.Ipv4AgoraOrder.getVracks(), // toDo }) .then((results) => { results.services.push({ @@ -124,7 +126,8 @@ export default class AgoraIpV4OrderController { type: 'parking', }); this.user = results.user; - this.services = results.services.map((service) => ({ + this.services = [...results.services, ...results.vrack]; + this.services = this.services.map((service) => ({ ...service, translatedType: service.type === 'parking' @@ -311,21 +314,65 @@ export default class AgoraIpV4OrderController { this.trackStep(3); } + /* To be replaced once we have region list coming from API for the Vrack, as of now consider IPV6 regions */ + getIpv6RegionsWithPlan(IpOffers) { + this.IP_REGION = 'ip_region'; + return IpOffers.map((plan) => { + const { + details: { + product: { configurations }, + }, + } = plan; + const regionConfig = configurations.find( + (config) => config.name === this.IP_REGION, + ); + + return regionConfig.values.map((regionId) => ({ + regionId, + plan: plan.planCode, + })); + }).flat(); + } + + static getMacroRegion(region) { + const localZonePattern = /^lz/i; + const devZonePattern = /^1-/i; + + let macro; + const local = region + .split('-') + ?.slice(2) + ?.join('-'); + + if (devZonePattern.test(local)) { + macro = [local]; + } else { + const nbOfSlice = localZonePattern.test(local) ? 3 : 2; + macro = /[\D]{2,3}/.exec( + region + .split('-') + ?.slice(nbOfSlice) + ?.join('-'), + ); + } + + return (macro && macro[0]) || ''; + } + onIpServiceSelection() { - this.isParkingIp = - this.model?.selectedService?.type === PRODUCT_TYPES.parking.typeName; - if (this.isParkingIp) { + this.isParkingIpOrVrack = + this.model?.selectedService?.type === PRODUCT_TYPES.parking.typeName || + this.model?.selectedService?.type === PRODUCT_TYPES.vrack.typeName; + this.IpOffers = this.ipCatalog.filter((plan) => + /^ip-v4|^ip-failover/.test(plan.planCode), + ); + if (this.model?.selectedService?.type === PRODUCT_TYPES.parking.typeName) { this.loading.region = true; - this.parkingIpOffers = this.ipCatalog.filter((plan) => - /^ip-v4|^ip-failover/.test(plan.planCode), - ); - const DATACENTERS = this.parkingIpOffers - .map((ipOffer) => { - return ipOffer.details.product.configurations.find( - (config) => config.name === 'datacenter', - )?.values; - }) - .flat(); + const DATACENTERS = this.IpOffers.map((ipOffer) => { + return ipOffer.details.product.configurations.find( + (config) => config.name === 'datacenter', + )?.values; + }).flat(); const uniqueDatacenters = [...new Set(DATACENTERS)]; this.catalogByLocation = uniqueDatacenters.map((datacenter) => { const flag = @@ -342,6 +389,30 @@ export default class AgoraIpV4OrderController { this.loading.region = false; return null; } + + if (this.model?.selectedService?.type === PRODUCT_TYPES.vrack.typeName) { + this.loading.region = true; + this.Ipv6Offers = this.ipCatalog.filter( + (plan) => plan.planCode.match(/^ip-v6.*/) != null, + ); + /* To be replaced once we have region list coming from API for the Vrack, as of now consider IPV6 regions */ + this.ipv6RegionsWithPlan = this.getIpv6RegionsWithPlan(this.Ipv6Offers); + this.catalogByLocation = this.ipv6RegionsWithPlan.map(({ regionId }) => { + const datacenter = REGION_TO_DATACENTER[regionId]; + const flag = + datacenter === 'ERI' ? 'gb' : DATACENTER_TO_COUNTRY[datacenter]; + return { + datacenter, + regionName: regionId, + location: this.$translate.instant( + `ip_agora_ipv6_location_${regionId}`, + ), + icon: `oui-flag oui-flag_${flag}`, + }; + }); + this.loading.region = false; + return null; + } return this.manageLoadIpOffers(); } @@ -406,7 +477,7 @@ export default class AgoraIpV4OrderController { ipOffersPromise = this.loadPrivateCloudIpOffers( get(this.model, 'selectedService.serviceName'), ); - } else if (this.isParkingIp) { + } else if (this.isParkingIpOrVrack) { // Country for Single IP selection in parking const country = [ DATACENTER_TO_COUNTRY[this.model.selectedRegion.datacenter], @@ -414,14 +485,13 @@ export default class AgoraIpV4OrderController { // Multiple countries are available for block IP selection in parking and vrack const countries = AgoraIpV4OrderController.getCountriesFromDatacenter( this.model.selectedRegion.datacenter, - this.parkingIpOffers, + this.IpOffers, ).map((value) => value.toLowerCase()); - const ipOfferDetails = this.parkingIpOffers.map( - this.createOfferDto.bind(this), - ); + const ipOfferDetails = this.IpOffers.map(this.createOfferDto.bind(this)); const ipOffersByDatacenter = AgoraIpV4OrderController.getRegionFromDatacenter( this.model.selectedRegion.datacenter, ); + blockIpOfferDetails = this.filterOffer( ipOfferDetails, 'productShortName', @@ -555,7 +625,7 @@ export default class AgoraIpV4OrderController { this.model.params.selectedCountry = head( get(this.model, 'params.selectedOffer.countries'), ); - } else if (this.isParkingIp) { + } else if (this.isParkingIpOrVrack) { const code = DATACENTER_TO_COUNTRY[this.model.selectedRegion.datacenter]; this.model.params.selectedCountry = { code: code.toUpperCase(), @@ -614,17 +684,26 @@ export default class AgoraIpV4OrderController { serviceName: get(this.model, 'selectedService.serviceName'), ...commonProductProps, }); - } else if (this.isParkingIp) { + } else if ( + this.model?.selectedService?.type === PRODUCT_TYPES.parking.typeName + ) { const { datacenter } = this.model.selectedRegion; productToOrder = this.IpAgoraOrder.constructor.createProductToOrder({ - organisation: get( - this.model.params, - 'selectedOrganisation.organisationId', - ), + organisation: this.model.params.selectedOrganisation.organisationId, ...commonProductProps, country: params.selectedCountry?.code, datacenter, }); + } else if ( + this.model?.selectedService?.type === PRODUCT_TYPES.vrack.typeName + ) { + const { datacenter } = this.model.selectedRegion; + productToOrder = this.IpAgoraOrder.constructor.createProductToOrder({ + organisation: this.model.params.selectedOrganisation.organisationId, + ...commonProductProps, + productRegionName: this.model.params.selectedOffer.productRegion, + datacenter, + }); } else { productToOrder = this.IpAgoraOrder.constructor.createProductToOrder({ organisation: get( @@ -697,7 +776,8 @@ export default class AgoraIpV4OrderController { PRODUCT_TYPES.privateCloud.typeName || this.model.selectedService?.type === PRODUCT_TYPES.dedicatedServer.typeName || - this.model.selectedService?.type === PRODUCT_TYPES.parking.typeName + this.model.selectedService?.type === PRODUCT_TYPES.parking.typeName || + this.model.selectedService?.type === PRODUCT_TYPES.vrack.typeName ); } diff --git a/packages/manager/apps/dedicated/client/app/components/ip/agoraOrder/ipv4/ipv4.html b/packages/manager/apps/dedicated/client/app/components/ip/agoraOrder/ipv4/ipv4.html index 3c6abbddede8..7922c14cacc1 100644 --- a/packages/manager/apps/dedicated/client/app/components/ip/agoraOrder/ipv4/ipv4.html +++ b/packages/manager/apps/dedicated/client/app/components/ip/agoraOrder/ipv4/ipv4.html @@ -58,10 +58,11 @@ > - + + + data.map((vrack) => { + const serviceName = vrack.iam.urn.split(':').pop(); + const displayName = vrack.name || serviceName; + return { + displayName, + serviceName, + type: PRODUCT_TYPES.vrack.apiTypeName, + }; + }), + ); + } + getServices() { return this.$q .all([