Skip to content

Commit 98265e6

Browse files
committed
Added python script for generating JSON configurations for libvirt leases.
1 parent cb2ad73 commit 98265e6

File tree

4 files changed

+1212
-0
lines changed

4 files changed

+1212
-0
lines changed

libvirt/tunnel/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,15 @@ profile:
4343
cluster_id: {cluster_id}
4444
environment: "{env_name}"
4545
```
46+
47+
## Generate leases network json
48+
49+
To generate the ```libvirt-${arch}.json``` files for your profiles:
50+
1. Ensure that each of the ```profile_${HOSTNAME}.yaml``` have a valid profile.
51+
2. Execute the ```generate-leases-network-json.py``` script to update the ```libvirt-${arch}.json``` files with information about the hostname, subnet, IP addresses*, and MAC addresses*.
52+
* These are only used in UPI based deployments.
53+
3. Got to `https://vault.ci.openshift.org`, login with your SSO credentials, and select `kv`. You should see `libvirt-${arch}` entries. If not, reach out on `#forum-ocp-multi-arch-ci` in Red Hat internal slack to be given access.
54+
4. Select an architecture, and click on the corresponding `libvirt-${arch}` entry. Then, select `leases` followed by `Create a new version +`.
55+
5. Copy the contents of the generated ```libvirt-${arch}.json``` in its entity, click on the eye icon in the value (i.e. second column) of the row whose first column value is `leases`, and replace the contents of that text box with the contents of your clipboard.
56+
6. Finally, scroll to the bottom of the page and hit save. Then, hit save again.
57+
7. To verify that you entered the data correctly, you may need to reload the vault page before displaying the entries since it takes a second to propagate.
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#!/usr/bin/python3
2+
3+
import json
4+
import logging
5+
import os
6+
import random
7+
import re
8+
import yaml
9+
10+
BOOSTRAP_OFFSET = 10
11+
CONTROL_PLANE_OFFSET = 11
12+
COMPUTE_OFFSET = 51
13+
14+
# Setting random to 0 for partial determinism
15+
# If running on the same input, the generated mac addresses should be the same
16+
# for all users
17+
random.seed(0)
18+
19+
20+
def build_network(networks, filename):
21+
with open(filename, "r") as stream:
22+
try:
23+
profile = yaml.safe_load(stream)
24+
logging.debug(profile)
25+
except yaml.YAMLError as exc:
26+
logging.error(str.format("Failed to parse: {0}", filename))
27+
logging.exception(exc)
28+
return
29+
30+
# Sanitize input
31+
try:
32+
arch = profile['profile']['arch']
33+
except AttributeError as exc:
34+
logging.error("Couldn't find arch for profile: {0}", profile)
35+
logging.exception(exc)
36+
try:
37+
# The profile's cluster_id variable is really a 0 indexed host identifier
38+
host_id = profile['profile']['cluster_id']
39+
except AttributeError as exc:
40+
logging.error(str.format(
41+
"Couldn't find cluster_id for profile: {0}", profile))
42+
logging.exception(exc)
43+
try:
44+
cluster_capacity = profile['profile']['cluster_capacity']
45+
except AttributeError as exc:
46+
logging.error(str.format(
47+
"Couldn't find cluster_capacity for profile: {0}", profile))
48+
logging.exception(exc)
49+
50+
# Initialize arch-based dictionary
51+
if arch not in networks:
52+
networks[arch] = {}
53+
54+
if cluster_capacity <= 1:
55+
logging.warning(str.format(
56+
"Profile {0} sets cluster capacity to 0. No leases will be created.", filename))
57+
return
58+
59+
for cluster_id in range(cluster_capacity):
60+
lease = str.format(
61+
"libvirt-{0}-{1}-{2}", arch, host_id, cluster_id)
62+
logging.debug(str.format("Setting network for lease: {0}", lease))
63+
networks[arch][lease] = {
64+
'hostname': filename.split("_")[1].split(".")[0],
65+
'subnet': 126 if cluster_id == 0 else cluster_id,
66+
'control-plane': [],
67+
'compute': [],
68+
'bootstrap': []
69+
}
70+
# Bootstrap Network
71+
networks[arch][lease]['bootstrap'].append({
72+
'ip': str.format("192.168.{0}.{1}", networks[arch][lease]['subnet'], BOOSTRAP_OFFSET),
73+
'mac': str.format("02:00:00:{0:02x}:{1:02x}:{2:02x}", random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
74+
})
75+
76+
# Control Plane
77+
for i in range(3):
78+
networks[arch][lease]['control-plane'].append({
79+
'ip': str.format("192.168.{0}.{1}", networks[arch][lease]['subnet'], CONTROL_PLANE_OFFSET + i),
80+
'mac': str.format("02:00:00:{0:02x}:{1:02x}:{2:02x}", random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
81+
})
82+
83+
# Compute Nodes
84+
for i in range(2):
85+
networks[arch][lease]['compute'].append({
86+
'ip': str.format("192.168.{0}.{1}", networks[arch][lease]['subnet'], COMPUTE_OFFSET + i),
87+
'mac': str.format("02:00:00:{0:02x}:{1:02x}:{2:02x}", random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
88+
})
89+
90+
91+
networks = {}
92+
directory = os.fsencode(os.getcwd())
93+
94+
for file in os.listdir(directory):
95+
filename = os.fsdecode(file)
96+
if re.match("profile_.*\.y[a]?ml", filename):
97+
print(str.format("Profile found: {0}", os.path.join(
98+
os.fsdecode(directory), filename)))
99+
build_network(networks, filename)
100+
101+
else:
102+
logging.info(str.format("Skipping file: {0}", os.path.join(
103+
os.fsdecode(directory), filename)))
104+
continue
105+
106+
for arch in networks:
107+
with open(str.format("libvirt-{0}.json", arch), "w") as lease_file:
108+
json.dump(networks[arch], lease_file, indent=2)

0 commit comments

Comments
 (0)