Commit 0eac79ba authored by Marco Mariani's avatar Marco Mariani

--token support for 'slapos node register'

parent a755b923
...@@ -60,8 +60,11 @@ class RegisterCommand(Command): ...@@ -60,8 +60,11 @@ class RegisterCommand(Command):
'asks it interactively. NOTE: giving password as parameter ' 'asks it interactively. NOTE: giving password as parameter '
'should be avoided for security reasons.') 'should be avoided for security reasons.')
ap.add_argument('--token',
help="SlapOS Master authentication token "
"(use '--token ask' for interactive prompt)")
ap.add_argument('-t', '--create-tap', ap.add_argument('-t', '--create-tap',
default=False,
action='store_true', action='store_true',
help='Will trigger creation of one virtual "tap" interface per ' help='Will trigger creation of one virtual "tap" interface per '
'Partition and attach it to primary interface. Requires ' 'Partition and attach it to primary interface. Requires '
...@@ -70,7 +73,6 @@ class RegisterCommand(Command): ...@@ -70,7 +73,6 @@ class RegisterCommand(Command):
' (default: %(default)s)') ' (default: %(default)s)')
ap.add_argument('-n', '--dry-run', ap.add_argument('-n', '--dry-run',
default=False,
action='store_true', action='store_true',
help='Simulate the execution steps' help='Simulate the execution steps'
' (default: %(default)s)') ' (default: %(default)s)')
......
...@@ -37,45 +37,48 @@ import shutil ...@@ -37,45 +37,48 @@ import shutil
import stat import stat
import sys import sys
import tempfile import tempfile
import urllib2
import subprocess import subprocess
from subprocess import CalledProcessError from subprocess import CalledProcessError
import requests
def authenticate(request, login, password):
auth = '%s:%s' % (login, password)
authheader = 'Basic %s' % auth.encode('base64').rstrip()
request.add_header('Authorization', authheader)
def check_credentials(url, login, password): def check_credentials(url, login, password):
"""Check if logged correctly on SlapOS Master""" """Check if login and password are correct"""
request = urllib2.Request(url) req = requests.get(url, auth=(login, password), verify=False)
authenticate(request, login, password) return 'Logout' in req.text
return 'Logout' in urllib2.urlopen(request).read()
def get_certificates(master_url_web, node_name, login, password, logger): def get_certificates(logger, master_url_web, node_name, token=None, login=None, password=None):
"""Download certificates from SlapOS Master""" """Download certificates from SlapOS Master"""
register_server_url = '/'.join([master_url_web, ("add-a-server/WebSection_registerNewComputer?dialog_id=WebSection_viewServerInformationDialog&dialog_method=WebSection_registerNewComputer&title={}&object_path=/erp5/web_site_module/hosting/add-a-server&update_method=&cancel_url=https%3A//www.vifib.net/add-a-server/WebSection_viewServerInformationDialog&Base_callDialogMethod=&field_your_title=Essai1&dialog_category=None&form_id=view".format(node_name))])
request = urllib2.Request(register_server_url)
authenticate(request, login, password)
try: if token:
req = urllib2.urlopen(request) req = requests.post('/'.join([master_url_web, 'add-a-server/WebSection_registerNewComputer']),
except urllib2.HTTPError as exc: data={'title': node_name},
headers={'X-Access-Token': token},
verify=False)
else:
register_server_url = '/'.join([master_url_web, ("add-a-server/WebSection_registerNewComputer?dialog_id=WebSection_viewServerInformationDialog&dialog_method=WebSection_registerNewComputer&title={}&object_path=/erp5/web_site_module/hosting/add-a-server&update_method=&cancel_url=https%3A//www.vifib.net/add-a-server/WebSection_viewServerInformationDialog&Base_callDialogMethod=&field_your_title=Essai1&dialog_category=None&form_id=view".format(node_name))])
req = requests.get(register_server_url, auth=(login, password), verify=False)
if not req.ok and 'Certificate still active.' in req.text:
# raise a readable exception if the computer name is already used, # raise a readable exception if the computer name is already used,
# instead of an opaque 500 Internal Error. # instead of an opaque 500 Internal Error.
# this will not work with the new API. # this will not work with the new API.
if exc.getcode() == 500: logger.error('The node name "%s" is already in use. Please change the name, or revoke the active certificate if you want to replace the node.' % node_name)
error_body = exc.read() sys.exit(1)
if 'Certificate still active.' in error_body:
logger.error('The node name "%s" is already in use. Please change the name, or revoke the active certificate if you want to replace the node.' % node_name)
sys.exit(1)
raise
return req.read() if req.status_code == 403:
if token:
msg = 'Please check the authentication token or require a new one.'
else:
msg = 'Please check username and password.'
logger.error('Access denied to the SlapOS Master. %s', msg)
sys.exit(1)
else:
req.raise_for_status()
return req.text
def parse_certificates(source): def parse_certificates(source):
...@@ -120,11 +123,10 @@ def get_slapos_conf_example(): ...@@ -120,11 +123,10 @@ def get_slapos_conf_example():
""" """
Get slapos.cfg.example and return its path Get slapos.cfg.example and return its path
""" """
request = urllib2.Request('http://git.erp5.org/gitweb/slapos.core.git/blob_plain/HEAD:/slapos.cfg.example')
req = urllib2.urlopen(request)
_, path = tempfile.mkstemp() _, path = tempfile.mkstemp()
with open(path, 'w') as fout: with open(path, 'wb') as fout:
fout.write(req.read()) req = requests.get('http://git.erp5.org/gitweb/slapos.core.git/blob_plain/HEAD:/slapos.cfg.example')
fout.write(req.content)
return path return path
...@@ -253,15 +255,24 @@ def gen_auth(conf): ...@@ -253,15 +255,24 @@ def gen_auth(conf):
def do_register(conf): def do_register(conf):
"""Register new computer on SlapOS Master and generate slapos.cfg""" """Register new computer on SlapOS Master and generate slapos.cfg"""
for login, password in gen_auth(conf): if conf.token == 'ask':
if check_credentials(conf.master_url_web, login, password): while True:
break conf.token = raw_input('SlapOS Token: ').strip()
conf.logger.warning('Wrong login/password') if conf.token:
break
if conf.token:
certificate_key = get_certificates(conf.logger, conf.master_url_web, conf.node_name, token=conf.token)
else: else:
return 1 for login, password in gen_auth(conf):
if check_credentials(conf.master_url_web, login, password):
break
conf.logger.warning('Wrong login/password')
else:
return 1
certificate_key = get_certificates(conf.logger, conf.master_url_web, conf.node_name, login=login, password=password)
# Get source code of page having certificate and key
certificate_key = get_certificates(conf.master_url_web, conf.node_name, login, password, conf.logger)
# Parse certificate and key and get computer id # Parse certificate and key and get computer id
certificate, key = parse_certificates(certificate_key) certificate, key = parse_certificates(certificate_key)
COMP = get_computer_name(certificate) COMP = get_computer_name(certificate)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment