1 from uuid import uuid4

2

3 import pytest

4 import yaml

5 from jwcrypto.jwk import JWK

6 from syrupy.filters import paths

7

8 from meshadmin.common.utils import create_keys, get_nebula_cert_binary_path, print_ca

9 from meshadmin.server.networks.models import Rule

10 from meshadmin.server.networks.services import (

11 create_group,

12 create_template,

13 enrollment,

14 generate_config_yaml,

15 generate_enrollment_token,

16)

17

18

19@pytest.fixture()

20 def full_network(test_network):

21 test_net = test_network(name="testnet", cidr="100.100.64.0/24")

22

23 lighthouse_template = create_template(

24 "lighthouses", test_net.name, is_lighthouse=True, is_relay=True, use_relay=False

25 )

26 token = generate_enrollment_token(lighthouse_template)

27

28 # enroll a lighthouses

29 for i in range(1, 5):

30 kid = str(uuid4())

31 auth_key = JWK.generate(kty="RSA", kid=kid, size=2048)

32 public_auth_key = auth_key.export_public()

33 private_net_key, public_net_key = create_keys()

34

35 preferred_hostname = str(uuid4())

36 public_ip = f"127.0.0.{i}"

37

38 enrollment(

39 enrollment_key=token,

40 public_net_key=public_net_key,

41 public_auth_key=public_auth_key,

42 preferred_hostname=preferred_hostname,

43 public_ip=public_ip,

44 enroll_on_existence=False,

45 )

46

47 for i in range(1, 7):

48 create_group(test_net.pk, f"group {i}")

49

50 return test_net

51

52

53 def test_nebula_bin_selection():

54 nebula_cert_path = get_nebula_cert_binary_path()

55 assert nebula_cert_path.exists()

56

57

58 def test_lighthouse_template(test_network, snapshot):

59 test_net = test_network(name="testnet", cidr="100.100.64.0/24")

60 lighthouse_template = create_template(

61 "lighthouses", test_net.name, is_lighthouse=True, is_relay=True, use_relay=False

62 )

63 token = generate_enrollment_token(lighthouse_template)

64

65 assert lighthouse_template.enrollment_key is not None

66

67 # enroll a lighthouse

68 kid = str(uuid4())

69 auth_key = JWK.generate(kty="RSA", kid=kid, size=2048)

70 public_auth_key = auth_key.export_public()

71 private_net_key, public_net_key = create_keys()

72 preferred_hostname = str(uuid4())

73 public_ip = "127.0.0.1"

74

75 host = enrollment(

76 enrollment_key=token,

77 public_net_key=public_net_key,

78 public_auth_key=public_auth_key,

79 preferred_hostname=preferred_hostname,

80 public_ip=public_ip,

81 enroll_on_existence=False,

82 )

83

84 assert host.network == test_net

85 assert host.public_key == public_net_key

86 assert host.public_auth_kid == auth_key.thumbprint()

87 assert host.groups.count() == 0

88

89 config_yaml = generate_config_yaml(host.id)

90 config_dict = yaml.safe_load(config_yaml)

91

92 assert config_dict == snapshot(exclude=paths("pki.ca", "pki.cert"))

93

94

95 def test_host_template(db, full_network, snapshot):

96 group1 = create_group(full_network.pk, "group1")

97 group2 = create_group(full_network.pk, "group2")

98 security_group = create_group(

99 full_network.pk, "test_security_group", "Test security group"

100 )

101 Rule.objects.create(

102 security_group=security_group,

103 direction=Rule.Direction.INBOUND,

104 port="80",

105 proto="tcp",

106 group=group1,

107 )

108

109 host_template = create_template(

110 "hosts",

111 full_network.name,

112 is_lighthouse=False,

113 is_relay=False,

114 use_relay=True,

115 groups=[group1.name, group2.name, security_group.name],

116 )

117 token = generate_enrollment_token(host_template)

118

119 # enroll the client host

120 kid = str(uuid4())

121 auth_key = JWK.generate(kty="RSA", kid=kid, size=2048)

122 public_auth_key = auth_key.export_public()

123 private_net_key, public_net_key = create_keys()

124 preferred_hostname = str(uuid4())

125 public_ip = "127.0.0.1"

126

127 host1 = enrollment(

128 enrollment_key=token,

129 public_net_key=public_net_key,

130 public_auth_key=public_auth_key,

131 preferred_hostname=preferred_hostname,

132 public_ip=public_ip,

133 enroll_on_existence=False,

134 )

135

136 assert host1.hostcert_set.first() is None

137

138 config_yaml = generate_config_yaml(host1.id)

139

140 config_dict = yaml.safe_load(config_yaml)

141 host_cert = config_dict["pki"]["cert"]

142 assert host_cert

143

144 host_cert_json = print_ca(host_cert)

145 print(host_cert_json)

146 assert sorted(host_cert_json["details"]["groups"]) == sorted(

147 ["group1", "group2", "test_security_group"]

148 )

149 assert host_cert_json["details"]["name"] == str(host1.name)

150

151 assert "firewall" in config_dict

152 assert len(config_dict["firewall"]["inbound"]) == 1

153 assert config_dict["firewall"]["inbound"][0]["port"] == "80"

154

155 assert config_dict == snapshot(exclude=paths("pki.ca", "pki.cert"))