功能:新增云管API与Web控制台并完成现场接入

This commit is contained in:
songyiming committed 2026-11-09 17:54:52 +08:00
1 parent 18a9ce995d
commit 3fb7b4da8c
79 files changed
+17367 -3

No files matched your search

+43
View File
@@ -0,0 +1,43 @@
"""Generate private local configuration and a CA for the device HTTPS channel."""
import argparse
import datetime
import ipaddress
import json
import pathlib
import secrets
import os
from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509.oid import NameOID
p = argparse.ArgumentParser()
p.add_argument('--ip', required=True)
p.add_argument('--pve-hostname', required=True, help='DNS name present in the PVE certificate')
p.add_argument('--pve-ip', required=True)
args = p.parse_args()
ip = ipaddress.ip_address(args.ip)
root = pathlib.Path(__file__).resolve().parent.parent
target = root / '.local/live'
target.mkdir(parents=True, exist_ok=True)
if (target / '.env').exists():
raise RuntimeError('Existing configuration retained; edit it deliberately instead of regenerating secrets')
access = json.loads((target / 'pve-access.json').read_text())
access['PVE_URL']=f'https://{args.pve_hostname}:8006'
now = datetime.datetime.now(datetime.timezone.utc)
key = rsa.generate_private_key(public_exponent=65537, key_size=3072)
name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, 'VDI local device CA')])
ca = x509.CertificateBuilder().subject_name(name).issuer_name(name).public_key(key.public_key()).serial_number(x509.random_serial_number()).not_valid_before(now-datetime.timedelta(minutes=5)).not_valid_after(now+datetime.timedelta(days=3650)).add_extension(x509.BasicConstraints(ca=True,path_length=0),critical=True).add_extension(x509.KeyUsage(True,False,False,False,False,True,True,False,False),critical=True).sign(key,hashes.SHA256())
server_key = rsa.generate_private_key(public_exponent=65537, key_size=3072)
server = x509.CertificateBuilder().subject_name(x509.Name([x509.NameAttribute(NameOID.COMMON_NAME,str(ip))])).issuer_name(name).public_key(server_key.public_key()).serial_number(x509.random_serial_number()).not_valid_before(now-datetime.timedelta(minutes=5)).not_valid_after(now+datetime.timedelta(days=365)).add_extension(x509.BasicConstraints(ca=False,path_length=None),critical=True).add_extension(x509.SubjectAlternativeName([x509.IPAddress(ip),x509.DNSName('localhost')]),critical=False).add_extension(x509.ExtendedKeyUsage([x509.oid.ExtendedKeyUsageOID.SERVER_AUTH]),critical=False).sign(key,hashes.SHA256())
tls = target / 'tls'; tls.mkdir(exist_ok=True)
def save_private(path, data):
path.write_bytes(data); os.chmod(path, 0o600)
for name, obj in [('ca',key),('server',server_key)]:
save_private(tls/f'{name}-key.pem', obj.private_bytes(serialization.Encoding.PEM,serialization.PrivateFormat.PKCS8,serialization.NoEncryption()))
(tls/'ca.pem').write_bytes(ca.public_bytes(serialization.Encoding.PEM))
(tls/'server.pem').write_bytes(server.public_bytes(serialization.Encoding.PEM)+ca.public_bytes(serialization.Encoding.PEM))
env = dict(VDI_DB_PASSWORD=secrets.token_hex(24),VDI_JWT_SECRET=secrets.token_hex(48),VDI_ADMIN_USERNAME='admin',VDI_ADMIN_PASSWORD=secrets.token_urlsafe(24),VDI_LIVE_BIND_IP=str(ip),PVE_HOSTNAME=args.pve_hostname,PVE_HOST_IP=str(ipaddress.ip_address(args.pve_ip)),**access)
save_private(target/'.env', ''.join(f'{k}={v}\n' for k,v in env.items()).encode())
save_private(target/'admin-login.txt', f'Console: http://127.0.0.1:5182\nUsername: {env["VDI_ADMIN_USERNAME"]}\nPassword: {env["VDI_ADMIN_PASSWORD"]}\nDevice HTTPS: https://{ip}:8443\n'.encode())
print('Private environment, admin login, CA and HTTPS certificate generated in .local/live')