Skip to content

Commit c5f2af2

Browse files
marie-jjleveugle
authored andcommitted
feat(pci): add private networks
1 parent f5cd48f commit c5f2af2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1562
-2
lines changed

packages/manager/apps/public-cloud/src/sidebar/sidebar.constant.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export const MENU = [
4949
subitems: [
5050
{
5151
options: {
52-
state: 'pci.projects.project2',
52+
state: 'pci.projects.project.privateNetwork',
5353
},
5454
translation: 'cloud_sidebar_private_network',
5555
},

packages/manager/modules/pci/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@
2323
"d3": "~3.5.13",
2424
"flag-icon-css": "~0.8.5",
2525
"jsplumb": "^2.9.2",
26+
"ipaddr.js": "^1.9.0",
2627
"jsurl": "^0.1.5",
2728
"lodash": "^4.17.11",
2829
"moment": "^2.19",
2930
"urijs": "^1.19.1",
30-
"xterm": "^3.12.2"
31+
"xterm": "^3.12.2",
32+
"validator": "^10.11.0"
3133
},
3234
"devDependencies": {
3335
"@ovh-ux/component-rollup-config": "5.0.1"

packages/manager/modules/pci/src/projects/project/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import instances from './instances';
1212
import kubernetes from './kubernetes';
1313
import legacy from './legacy';
1414
import sshKeys from './ssh-keys';
15+
import privateNetworks from './private-networks';
1516
import storages from './storages';
1617
import routing from './project.routing';
1718

@@ -24,6 +25,7 @@ angular
2425
instances,
2526
kubernetes,
2627
legacy,
28+
privateNetworks,
2729
'oui',
2830
'ovhManagerCore',
2931
'ovh-api-services',
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import controller from './add.controller';
2+
import template from './add.html';
3+
4+
export default {
5+
bindings: {
6+
goBack: '<',
7+
projectId: '<',
8+
messageContainer: '<',
9+
},
10+
controller,
11+
template,
12+
};
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
export const DEFAULT_CIDR = 16;
2+
3+
export const DEFAULT_IP = '10.{vlanId}.0.0';
4+
5+
export const DEFAULT_VLAN_ID = 0;
6+
7+
export const NETWORK_ACTIVE_STATUS = 'ACTIVE';
8+
9+
export const VLAN_ID = {
10+
MIN: 2,
11+
MAX: 4000,
12+
};
13+
14+
export default {
15+
DEFAULT_CIDR,
16+
DEFAULT_IP,
17+
NETWORK_ACTIVE_STATUS,
18+
VLAN_ID,
19+
};
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
import find from 'lodash/find';
2+
import get from 'lodash/get';
3+
import partition from 'lodash/partition';
4+
import set from 'lodash/set';
5+
import some from 'lodash/some';
6+
import sortBy from 'lodash/sortBy';
7+
import zipWith from 'lodash/zipWith';
8+
9+
import {
10+
DEFAULT_VLAN_ID, DEFAULT_CIDR, VLAN_ID,
11+
} from './add.constants';
12+
import IP from './ip';
13+
14+
const CONTAINER_NAME = 'pci.projects.project.privateNetwork.add';
15+
16+
export default class NetworkAddCtrl {
17+
/* @ngInject */
18+
constructor(
19+
$translate,
20+
CucCloudMessage,
21+
CucRegionService,
22+
OvhApiCloudProjectRegion,
23+
PciPrivateNetworks,
24+
PciPrivateNetworksAdd,
25+
) {
26+
this.$translate = $translate;
27+
this.CucCloudMessage = CucCloudMessage;
28+
this.CucRegionService = CucRegionService;
29+
this.OvhApiCloudProjectRegion = OvhApiCloudProjectRegion;
30+
this.PciPrivateNetworks = PciPrivateNetworks;
31+
this.PciPrivateNetworksAdd = PciPrivateNetworksAdd;
32+
}
33+
34+
$onInit() {
35+
this.loaders = {
36+
isInitiating: true,
37+
isSubmitting: false,
38+
};
39+
this.configuration = {
40+
address: null,
41+
cidr: DEFAULT_CIDR,
42+
dhcp: true,
43+
vlanId: DEFAULT_VLAN_ID,
44+
};
45+
this.subnets = [];
46+
this.name = null;
47+
48+
this.configureVlanId = false;
49+
this.VLAN_ID = {
50+
...VLAN_ID,
51+
NEXT_AVAILABLE: DEFAULT_VLAN_ID,
52+
};
53+
54+
this.regenerateNetworkAddress(DEFAULT_VLAN_ID);
55+
56+
return this.$translate.refresh()
57+
.then(() => this.loadMessages())
58+
.then(() => this.getVlanIdConfiguration())
59+
.then(() => this.getSubnets())
60+
.catch((error) => {
61+
this.CucCloudMessage.error(
62+
this.$translate.instant(
63+
'pci_projects_project_network_private_create_init_error',
64+
{ message: get(error, 'data.message', '') },
65+
),
66+
);
67+
})
68+
.finally(() => {
69+
this.loaders.isInitiating = false;
70+
});
71+
}
72+
73+
regenerateNetworkAddress(vlanId) {
74+
this.configuration.address = this.PciPrivateNetworksAdd
75+
.constructor.generateNetworkAddress(vlanId);
76+
this.subnets = this.mapSubnetsIpBlocks(this.subnets);
77+
}
78+
79+
getVlanIdConfiguration() {
80+
return this.PciPrivateNetworks.getPrivateNetworks(this.projectId)
81+
.then((networks) => {
82+
this.configureVlanId = some(networks, ({ vlanId }) => vlanId === DEFAULT_VLAN_ID);
83+
this.mandatoryVlanId = this.configureVlanId;
84+
if (this.configureVlanId) {
85+
const nextVlanId = get(
86+
find(networks, ({ vlanId }) => vlanId !== DEFAULT_VLAN_ID
87+
&& !find(networks, ({ vlanId: nextId }) => nextId === vlanId + 1)),
88+
'vlanId',
89+
0,
90+
) + 1;
91+
92+
this.VLAN_ID = {
93+
MIN: Math.max(VLAN_ID.MIN, nextVlanId),
94+
MAX: VLAN_ID.MAX,
95+
NEXT_AVAILABLE: nextVlanId,
96+
};
97+
this.configuration.vlanId = this.VLAN_ID.MIN;
98+
this.regenerateNetworkAddress(this.configuration.vlanId);
99+
}
100+
});
101+
}
102+
103+
setVlanId(manually) {
104+
if (manually) {
105+
this.configuration.vlanId = this.VLAN_ID.MIN;
106+
} else {
107+
this.configuration.vlanId = this.VLAN_ID.NEXT_AVAILABLE;
108+
}
109+
}
110+
111+
getIpBlocks(regions) {
112+
return IP.splitSubnetIpAddresses(
113+
this.configuration.address,
114+
this.configuration.cidr,
115+
regions.length,
116+
).ipBlocks;
117+
}
118+
119+
mapSubnetsIpBlocks(subnets) {
120+
const ipBlocks = this.getIpBlocks(subnets);
121+
return zipWith(sortBy(subnets, 'region'), ipBlocks, (subnet, ipBlock) => ({
122+
...subnet,
123+
...ipBlock,
124+
}));
125+
}
126+
127+
getSubnets() {
128+
return this.OvhApiCloudProjectRegion.v6().query({
129+
serviceName: this.projectId,
130+
}).$promise
131+
.then(regions => regions.map(region => ({
132+
region,
133+
displayedRegion: this.CucRegionService.getTranslatedMicroRegion(region),
134+
selected: true,
135+
gateway: false,
136+
})))
137+
.then((subnets) => {
138+
this.subnets = this.mapSubnetsIpBlocks(subnets);
139+
});
140+
}
141+
142+
selectRegion(selected, subnet) {
143+
set(subnet, 'selected', selected);
144+
const [selectedSubnets, unSelectedSubnets] = partition(this.subnets, 'selected');
145+
const subnets = this.mapSubnetsIpBlocks(selectedSubnets).concat(unSelectedSubnets);
146+
this.subnets = subnets;
147+
}
148+
149+
loadMessages() {
150+
this.CucCloudMessage.unSubscribe(CONTAINER_NAME);
151+
this.messageHandler = this.CucCloudMessage.subscribe(
152+
CONTAINER_NAME,
153+
{
154+
onMessage: () => this.refreshMessages(),
155+
},
156+
);
157+
}
158+
159+
refreshMessages() {
160+
this.messages = this.messageHandler.getMessages();
161+
}
162+
163+
createNetwork() {
164+
this.loaders.isSubmitting = true;
165+
166+
const selectedSubnets = this.subnets.filter(({ selected }) => selected);
167+
const privateNetwork = {
168+
name: this.name,
169+
vlanId: this.configuration.vlanId,
170+
regions: selectedSubnets.map(({ region }) => region),
171+
};
172+
const subnets = selectedSubnets.map(subnet => ({
173+
dhcp: this.configuration.dhcp,
174+
end: subnet.end,
175+
network: `${this.configuration.address}/${this.configuration.cidr}`,
176+
noGateway: !subnet.gateway,
177+
region: subnet.region,
178+
start: subnet.start,
179+
}));
180+
181+
return this.PciPrivateNetworksAdd.create(this.projectId, privateNetwork, subnets)
182+
.then(() => this.goBack())
183+
.then(() => {
184+
this.CucCloudMessage.success(
185+
this.$translate.instant(
186+
'pci_projects_project_network_private_create_success',
187+
),
188+
this.messageContainer,
189+
);
190+
this.goBack();
191+
})
192+
.catch(error => this.CucCloudMessage.error(
193+
this.$translate.instant(
194+
'pci_projects_project_network_private_create_error',
195+
{ message: get(error, 'data.message', '') },
196+
),
197+
))
198+
.finally(() => {
199+
this.loaders.isSubmitting = false;
200+
});
201+
}
202+
}

0 commit comments

Comments
 (0)