mirror of
https://github.com/xcat2/confluent.git
synced 2025-03-03 17:51:00 +00:00
Provide internal URL shortening service
Permit users to have very long profile names, and provide a URL shortening service to bridge the gap for fixed-width field limitations in DHCP/PXE.
This commit is contained in:
parent
2f33aa5d83
commit
e3d70f351d
@ -22,6 +22,7 @@
|
||||
|
||||
# option 97 = UUID (wireformat)
|
||||
|
||||
import base64
|
||||
import confluent.config.configmanager as cfm
|
||||
import confluent.collective.manager as collective
|
||||
import confluent.noderange as noderange
|
||||
@ -35,6 +36,7 @@ import eventlet
|
||||
import eventlet.green.socket as socket
|
||||
import eventlet.green.select as select
|
||||
import netifaces
|
||||
import os
|
||||
import struct
|
||||
import time
|
||||
import traceback
|
||||
@ -165,6 +167,18 @@ pxearchs = {
|
||||
}
|
||||
|
||||
|
||||
shorturls = {}
|
||||
def register_shorturl(url):
|
||||
urlid = base64.urlsafe_b64encode(os.urandom(3))
|
||||
while urlid in shorturls:
|
||||
urlid = base64.urlsafe_b64encode(os.urandom(3))
|
||||
urlid = urlid.decode()
|
||||
shorturls[urlid] = url
|
||||
returl = '/'.join(url.split('/')[:3])
|
||||
returl += '/confluent-api/boot/su/' + urlid + '/' + os.path.basename(url)
|
||||
return returl
|
||||
|
||||
|
||||
uuidmap = {}
|
||||
macmap = {}
|
||||
attribwatcher = None
|
||||
@ -369,12 +383,15 @@ def proxydhcp(handler, nodeguess):
|
||||
elif disco['arch'] == 'uefi-aarch64':
|
||||
bootfile = b'confluent/aarch64/ipxe.efi'
|
||||
if len(bootfile) > 127:
|
||||
log.log(
|
||||
{'info': 'Boot offer cannot be made to {0} as the '
|
||||
'profile name "{1}" is {2} characters longer than is supported '
|
||||
'for this boot method.'.format(
|
||||
node, profile, len(bootfile) - 127)})
|
||||
continue
|
||||
if bootfile.startswith(b'http'):
|
||||
bootfile = register_shorturl(bootfile.decode('utf8')).encode('utf8')
|
||||
else:
|
||||
log.log(
|
||||
{'info': 'Boot offer cannot be made to {0} as the '
|
||||
'profile name "{1}" is {2} characters longer than is supported '
|
||||
'for this boot method.'.format(
|
||||
node, profile, len(bootfile) - 127)})
|
||||
continue
|
||||
rpv[:240] = rqv[:240].tobytes()
|
||||
rpv[0:1] = b'\x02'
|
||||
rpv[108:108 + len(bootfile)] = bootfile
|
||||
@ -797,12 +814,15 @@ def reply_dhcp4(node, info, packet, cfg, reqview, httpboot, cfd, profile, sock=N
|
||||
if not isinstance(bootfile, bytes):
|
||||
bootfile = bootfile.encode('utf8')
|
||||
if len(bootfile) > 127:
|
||||
log.log(
|
||||
{'info': 'Boot offer cannot be made to {0} as the '
|
||||
'profile name "{1}" is {2} characters longer than is supported '
|
||||
'for this boot method.'.format(
|
||||
node, profile, len(bootfile) - 127)})
|
||||
return
|
||||
if bootfile.startswith(b'http'):
|
||||
bootfile = register_shorturl(bootfile.decode('utf8')).encode('utf8')
|
||||
else:
|
||||
log.log(
|
||||
{'info': 'Boot offer cannot be made to {0} as the '
|
||||
'profile name "{1}" is {2} characters longer than is supported '
|
||||
'for this boot method.'.format(
|
||||
node, profile, len(bootfile) - 127)})
|
||||
return
|
||||
repview[108:108 + len(bootfile)] = bootfile
|
||||
elif info.get('architecture', None) == 'uefi-aarch64' and packet.get(77, None) == b'iPXE':
|
||||
if not profile:
|
||||
|
@ -30,6 +30,7 @@ import confluent.config.attributes as attribs
|
||||
import confluent.config.configmanager as configmanager
|
||||
import confluent.consoleserver as consoleserver
|
||||
import confluent.discovery.core as disco
|
||||
import confluent.discovery.protocols.pxe as pxe
|
||||
import confluent.forwarder as forwarder
|
||||
import confluent.exceptions as exc
|
||||
import confluent.log as log
|
||||
@ -640,6 +641,8 @@ def resourcehandler(env, start_response):
|
||||
yield '500 - ' + str(e)
|
||||
return
|
||||
|
||||
|
||||
|
||||
def resourcehandler_backend(env, start_response):
|
||||
"""Function to handle new wsgi requests
|
||||
"""
|
||||
@ -648,7 +651,7 @@ def resourcehandler_backend(env, start_response):
|
||||
('Pragma', 'no-cache'),
|
||||
('X-Content-Type-Options', 'nosniff'),
|
||||
('Content-Security-Policy', "default-src 'self'"),
|
||||
('X-XSS-Protection', '1; mode=block'), ('X-Frame-Options', 'deny'),
|
||||
('X-XySS-Protection', '1; mode=block'), ('X-Frame-Options', 'deny'),
|
||||
('Strict-Transport-Security', 'max-age=86400'),
|
||||
('X-Permitted-Cross-Domain-Policies', 'none')]
|
||||
reqbody = None
|
||||
@ -671,6 +674,16 @@ def resourcehandler_backend(env, start_response):
|
||||
request = env['PATH_INFO'].split('/')
|
||||
if not request[0]:
|
||||
request = request[1:]
|
||||
if request[1] == 'su': # shorturl
|
||||
targurl = pxe.shorturls.get(request[2], None)
|
||||
if not targurl:
|
||||
start_response('404 Not Found', headers)
|
||||
yield ''
|
||||
return
|
||||
headers.append(('Location', targurl))
|
||||
start_response('302 Found', headers)
|
||||
yield ''
|
||||
return
|
||||
if len(request) != 4:
|
||||
start_response('400 Bad Request', headers)
|
||||
yield ''
|
||||
|
Loading…
x
Reference in New Issue
Block a user