コード例 #1
0
 def post(self, *args, **kwargs):
     """Create a Dns"""
     username = kwargs['token']['username']
     resp_data = {'user': username}
     txn_id = request.headers.get('X-REQUEST-ID', 'noId')
     body = kwargs['body']
     machine_name = body['name']
     image = body['image']
     static_ip = body['static-ip']
     default_gateway = body.get('default-gateway', '192.168.1.1')
     netmask = body.get('netmask', '255.255.255.0')
     dns = body.get('dns', ['192.168.1.1'])
     network = '{}_{}'.format(username, body['network'])
     bad_network_config = network_config_ok(static_ip, default_gateway,
                                            netmask)
     if bad_network_config:
         resp_data['error'] = bad_network_config
         resp = Response(ujson.dumps(resp_data))
         resp.status_code = 400
     else:
         task = current_app.celery_app.send_task('dns.create', [
             username, machine_name, image, network, static_ip,
             default_gateway, netmask, dns, txn_id
         ])
         resp_data['content'] = {'task-id': task.id}
         resp = Response(ujson.dumps(resp_data))
         resp.status_code = 202
         resp.headers.add(
             'Link',
             '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL,
                                                    self.route_base,
                                                    task.id))
     return resp
コード例 #2
0
 def post(self, *args, **kwargs):
     """Create a WinServer"""
     username = kwargs['token']['username']
     txn_id = request.headers.get('X-REQUEST-ID', 'noId')
     resp_data = {'user': username}
     body = kwargs['body']
     machine_name = body['name']
     image = body['image']
     network = '{}_{}'.format(username, body['network'])
     ip_config, error = _get_ip_config(body.get('ip-config', {}))
     if error:
         resp_data['error'] = error
         resp = Response(ujson.dumps(resp_data))
         resp.status_code = 400
     else:
         task = current_app.celery_app.send_task(
             'winserver.create',
             [username, machine_name, image, network, ip_config, txn_id])
         resp_data['content'] = {'task-id': task.id}
         resp = Response(ujson.dumps(resp_data))
         resp.status_code = 202
         resp.headers.add(
             'Link',
             '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL,
                                                    self.route_base,
                                                    task.id))
     return resp
コード例 #3
0
ファイル: portmap.py プロジェクト: willnx/vlab_ipam_api
 def get(self, *args, **kwargs):
     """Display the Port Map rules defined on the NAT firewall"""
     username = kwargs['token']['username']
     resp_data = {'user': username, 'content': {}}
     status_code = 200
     name = request.args.get('name', None)
     addr = request.args.get('target_addr', None)
     component = request.args.get('component', None)
     conn_port = request.args.get('conn_port', 0)
     target_port = request.args.get('target_port', 0)
     conn_port, target_port, error = cast_port_values(
         conn_port, target_port)
     if error:
         resp_data['error'] = error
         resp = Response(ujson.dumps(resp_data))
         resp.status_code = 400
         return resp
     try:
         with Database() as db:
             resp_data['content']['ports'] = db.lookup_port(
                 name=name,
                 addr=addr,
                 component=component,
                 conn_port=conn_port,
                 target_port=target_port)
     except Exception as doh:
         logger.exception(doh)
         resp_data['error'] = '%s' % doh
         status_code = 500
     else:
         resp_data['content']['gateway_ip'] = get_ip()
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = status_code
     return resp
コード例 #4
0
    def get(self):
        """End point for health checks"""
        resp = {'redis': {}, 'auth_api': {}, 'ldap': {}}
        status = 200
        redis_stime = time()
        try:
            r = StrictRedis(host=const.AUTH_REDIS_HOSTNAME,
                            port=const.AUTH_REDIS_PORT)
            r.config_get('*')
        except RedisError as doh:
            resp['redis']['msg'] = '%s' % doh
            status = 500
        else:
            resp['redis']['msg'] = 'OK'
        resp['redis']['latency'] = time() - redis_stime

        ldap_stime = time()
        try:
            server = ldap3.Server(const.AUTH_LDAP_URL, get_info=None)
            conn = ldap3.Connection(server, auto_bind=True)
        except LDAPException as derp:
            resp['ldap']['msg'] = '%s' % derp
            status = 500
        else:
            resp['ldap']['msg'] = 'OK'
            conn.unbind()
        resp['ldap']['latency'] = time() - ldap_stime

        resp['auth_api']['version'] = pkg_resources.get_distribution(
            'vlab-auth-service').version
        response = Response(ujson.dumps(resp))
        response.status_code = status
        response.headers['Content-Type'] = 'application/json'
        return response
コード例 #5
0
 def post(self, *args, **kwargs):
     """Create a Superna"""
     username = kwargs['token']['username']
     resp_data = {'user': username}
     txn_id = request.headers.get('X-REQUEST-ID', 'noId')
     body = kwargs['body']
     machine_name = body['name']
     image = body['image']
     ip_config = {
         'default-gateway': '192.168.1.1',
         'netmask': '255.255.255.0',
         'dns': ['192.168.1.1.'],
         'domain': "vlab.local"
     }
     ip_config.update(body['ip-config'])
     network = '{}_{}'.format(username, body['network'])
     task = current_app.celery_app.send_task(
         'superna.create',
         [username, machine_name, image, network, ip_config, txn_id])
     resp_data['content'] = {'task-id': task.id}
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = 202
     resp.headers.add(
         'Link',
         '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL,
                                                self.route_base, task.id))
     return resp
コード例 #6
0
ファイル: portmap.py プロジェクト: willnx/vlab_ipam_api
    def post(self, *args, **kwargs):
        """Create a Port Map rule in the NAT firewall"""
        username = kwargs['token']['username']
        resp_data = {'user': username, 'content': {}}
        target_addr = kwargs['body']['target_addr']
        target_port = kwargs['body']['target_port']
        target_name = kwargs['body']['target_name']
        target_component = kwargs['body']['target_component']
        status_code = 200
        try:
            db = Database()
        except Exception as doh:
            status_code = 500
            resp_data['error'] = '%s' % doh
            logger.exception(doh)
        else:
            try:
                conn_port = db.add_port(target_addr, target_port, target_name,
                                        target_component)
                current_app.firewall.map_port(conn_port, target_port,
                                              target_addr)
            except Exception as doh:
                db.delete_port(conn_port)
                resp_data['error'] = '%s' % doh
                logger.exception(doh)
                status_code = 500
            else:
                resp_data['content']['conn_port'] = conn_port
            finally:
                db.close()

        resp = Response(ujson.dumps(resp_data))
        resp.status_code = status_code
        return resp
コード例 #7
0
        def inner(*args, **kwargs):
            if kwargs.get('token', None) is None:
                try:
                    fresh_token = get_token_from_header()
                    kwargs['token'] = fresh_token
                except ExpiredSignatureError:
                    data = {'error': 'No Valid Session Found'}
                    resp = Response(ujson.dumps(data))
                    resp.headers.add(
                        'Link', '<{0}{1}>; rel=authorization'.format(
                            const.VLAB_URL, '/api/1/auth'))
                    resp.status_code = 401
                    return resp

            if verify is True and kwargs.get('verified', False) is False:
                resp = requests.get('{}{}'.format(const.VLAB_URL,
                                                  '/api/1/auth'),
                                    params={'token': kwargs['token']})
                if not resp.ok:
                    return resp.content, resp.status
                else:
                    kwargs['verified'] = True

            if acl_in_token(kwargs['token'],
                            username=username,
                            memberOf=memberOf,
                            version=version):
                resp = {
                    'error':
                    'user {} does not have access'.format(
                        kwargs['token']['username'])
                }
                return ujson.dumps(resp), 403
            else:
                return func(*args, **kwargs)
コード例 #8
0
ファイル: portmap.py プロジェクト: willnx/vlab_ipam_api
 def delete(self, *args, **kwargs):
     """Destroy a Port Map rule in the NAT firewall"""
     username = kwargs['token']['username']
     resp_data = {'user': username, 'content': {}}
     conn_port = kwargs['body']['conn_port']
     status_code = 200
     try:
         with Database() as db:
             target_port, target_addr = db.port_info(conn_port)
             # The ``with`` statement locks the firewall object
             # Only locking here because deleting requires multiple updates
             with current_app.firewall:
                 nat_id = current_app.firewall.find_rule(
                     target_port,
                     target_addr,
                     table='nat',
                     conn_port=conn_port)
                 filter_id = current_app.firewall.find_rule(target_port,
                                                            target_addr,
                                                            table='filter')
                 record_error, status_code = records_valid(
                     nat_id, filter_id, target_port, target_addr)
                 if not record_error:
                     error, status_code = remove_port_map(
                         nat_id, filter_id, target_port, target_addr,
                         conn_port, db)
     except Exception as doh:
         logger.exception(doh)
         resp_data['error'] = '%s' % doh
         status_code = 500
     else:
         resp_data['error'] = error
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = status_code
     return resp
コード例 #9
0
ファイル: healthcheck.py プロジェクト: willnx/vlab_vlan
 def get(self):
     """End point for health checks"""
     resp = {}
     resp['version'] = pkg_resources.get_distribution('vlab-vlan').version
     response = Response(ujson.dumps(resp))
     response.status_code = 200
     response.headers['Content-Type'] = 'application/json'
     return response
コード例 #10
0
ファイル: esrs.py プロジェクト: willnx/vlab_esrs
 def get(self, *args, **kwargs):
     """Display the ESRS instances you own"""
     username = kwargs['token']['username']
     txn_id = request.headers.get('X-REQUEST-ID', 'noId')
     resp_data = {'user' : username}
     task = current_app.celery_app.send_task('esrs.show', [username, txn_id])
     resp_data['content'] = {'task-id': task.id}
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = 202
     resp.headers.add('Link', '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL, self.route_base, task.id))
     return resp
コード例 #11
0
 def post(self, *args, **kwargs):
     """Create a user's folder"""
     username = kwargs['token']['username']
     txn_id = request.headers.get('X-REQUEST-ID', 'noId')
     resp_data = {"user" : username}
     task = current_app.celery_app.send_task('inventory.create', [username, txn_id])
     resp_data['content'] = {'task-id': task.id}
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = 202
     resp.headers.add('Link', '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL, self.route_base, task.id))
     return resp
コード例 #12
0
ファイル: esrs.py プロジェクト: willnx/vlab_esrs
 def image(self, *args, **kwargs):
     """Show available versions of ESRS that can be deployed"""
     username = kwargs['token']['username']
     txn_id = request.headers.get('X-REQUEST-ID', 'noId')
     resp_data = {'user' : username}
     task = current_app.celery_app.send_task('esrs.image', [txn_id])
     resp_data['content'] = {'task-id': task.id}
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = 202
     resp.headers.add('Link', '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL, self.route_base, task.id))
     return resp
コード例 #13
0
ファイル: cee.py プロジェクト: willnx/vlab_cee
 def delete(self, *args, **kwargs):
     """Destroy a CEE instance"""
     username = kwargs['token']['username']
     txn_id = request.headers.get('X-REQUEST-ID', 'noId')
     resp_data = {'user' : username}
     machine_name = kwargs['body']['name']
     task = current_app.celery_app.send_task('cee.delete', [username, machine_name, txn_id])
     resp_data['content'] = {'task-id': task.id}
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = 202
     resp.headers.add('Link', '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL, self.route_base, task.id))
     return resp
コード例 #14
0
ファイル: gateway_view.py プロジェクト: willnx/vlab_gateway
 def post(self, *args, **kwargs):
     """Create a new gateway"""
     username = kwargs['token']['username']
     resp_data = {'user' : username}
     wan = kwargs['body']['wan']
     lan = '{}_{}'.format(username, kwargs['body']['lan'])
     txn_id = request.headers.get('X-REQUEST-ID', 'noId')
     task = current_app.celery_app.send_task('gateway.create', [username, wan, lan, txn_id])
     resp_data['content'] = {'task-id': task.id}
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = 202
     resp.headers.add('Link', '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL, self.route_base, task.id))
     return resp
コード例 #15
0
ファイル: snapshot.py プロジェクト: willnx/vlab_snapshot
 def put(self, *args, **kwargs):
     """Apply a snapshot to a VM"""
     username = kwargs['token']['username']
     txn_id = request.headers.get('X-REQUEST-ID', 'noId')
     resp_data = {'user' : username}
     snap_id = kwargs['body']['id']
     machine_name = kwargs['body']['name']
     task = current_app.celery_app.send_task('snapshot.apply', [username, snap_id, machine_name, txn_id])
     resp_data['content'] = {'task-id': task.id}
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = 202
     resp.headers.add('Link', '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL, self.route_base, task.id))
     return resp
コード例 #16
0
 def delete(self, *args, **kwargs):
     """Delete a gateway"""
     username = kwargs['token']['username']
     resp_data = {'user': username}
     task = current_app.celery_app.send_task('jumpbox.delete', [username])
     resp_data['content'] = {'task-id': task.id}
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = 202
     resp.headers.add(
         'Link',
         '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL,
                                                self.route_base, task.id))
     return resp
コード例 #17
0
ファイル: snapshot.py プロジェクト: willnx/vlab_snapshot
 def post(self, *args, **kwargs):
     """Create a Snapshot"""
     username = kwargs['token']['username']
     resp_data = {'user' : username}
     txn_id = request.headers.get('X-REQUEST-ID', 'noId')
     body = kwargs['body']
     machine_name = body['name']
     shift = body.get('shift', False)
     task = current_app.celery_app.send_task('snapshot.create', [username, machine_name, shift, txn_id])
     resp_data['content'] = {'task-id': task.id}
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = 202
     resp.headers.add('Link', '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL, self.route_base, task.id))
     return resp
コード例 #18
0
ファイル: cee.py プロジェクト: willnx/vlab_cee
 def post(self, *args, **kwargs):
     """Create a new CEE instance"""
     username = kwargs['token']['username']
     txn_id = request.headers.get('X-REQUEST-ID', 'noId')
     resp_data = {'user' : username}
     body = kwargs['body']
     machine_name = body['name']
     image = body['image']
     network = '{}_{}'.format(username, body['network'])
     task = current_app.celery_app.send_task('cee.create', [username, machine_name, image, network, txn_id])
     resp_data['content'] = {'task-id': task.id}
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = 202
     resp.headers.add('Link', '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL, self.route_base, task.id))
     return resp
コード例 #19
0
ファイル: vlan.py プロジェクト: willnx/vlab_vlan
 def delete(self, *args, **kwargs):
     """Delete a lvan"""
     username = kwargs['token']['username']
     vlan_name = '{}_{}'.format(username, kwargs['body']['vlan-name'])
     txn_id = request.headers.get('X-REQUEST-ID', 'noId')
     resp_data, task_id = _dispatch_modify(username=username,
                                           the_task='vlan.delete',
                                           vlan_name=vlan_name,
                                           txn_id=txn_id)
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = 202
     resp.headers.add(
         'Link',
         '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL,
                                                self.route_base, task_id))
     return resp
コード例 #20
0
 def post(self, *args, **kwargs):
     """Change the power state of a given virtual machine"""
     username = kwargs['token']['username']
     resp_data = {"user": username}
     machine = kwargs['body']['machine']
     power = kwargs['body']['power']
     txn_id = request.headers.get('X-REQUEST-ID', 'noId')
     task = current_app.celery_app.send_task(
         'power.modify', [username, power, machine, txn_id])
     resp_data['content'] = {'task-id': task.id}
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = 202
     resp.headers.add(
         'Link',
         '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL,
                                                self.route_base, task.id))
     return resp
コード例 #21
0
 def modify_network(self, *args, **kwargs):
     """Change the network a virtual machine is connected to"""
     username = kwargs['token']['username']
     machine_name = kwargs['body']['name']
     new_network = '{}_{}'.format(username, kwargs['body']['new_network'])
     txn_id = request.headers.get('X-REQUEST-ID', 'noId')
     resp_data = {'user': username}
     task = current_app.celery_app.send_task(
         '{}.modify_network'.format(self.RESOURCE.lower()),
         [username, machine_name, new_network, txn_id])
     resp_data['content'] = {'task-id': task.id}
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = 202
     resp.headers.add(
         'Link',
         '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL,
                                                self.route_base, task.id))
     return resp
コード例 #22
0
 def put(self, *args, **kwargs):
     """Modify a template"""
     username = kwargs['token']['username']
     txn_id = request.headers.get('X-REQUEST-ID', 'noId')
     resp_data = {'user': username}
     template = kwargs['body']['template']
     summary = kwargs['body'].get('summary', '')
     owner = kwargs['body'].get('owner', '')
     task = current_app.celery_app.send_task(
         'deployment.modify_template',
         [username, template, summary, owner, txn_id])
     resp_data['content'] = {'task-id': task.id}
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = 202
     resp.headers.add(
         'Link',
         '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL,
                                                self.route_base, task.id))
     return resp
コード例 #23
0
 def get(self, *args, **kwargs):
     """Obtain quota information"""
     username = kwargs['token']['username']
     with Database() as db:
         exceeded_on, last_notified = db.user_info(username)
     resp_data = {
         'content': {
             'exceeded_on': exceeded_on,
             'last_notified': last_notified,
             'grace_period': const.QUOTA_GRACE_PERIOD,
             'soft-limit': const.VLAB_QUOTA_LIMIT,
         }
     }
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = 200
     resp.headers.add(
         'Link',
         '<{0}/api/1/inf/inventory>; rel=inventory'.format(const.VLAB_URL))
     return resp
コード例 #24
0
 def post(self, *args, **kwargs):
     """Create a new vOneFS node"""
     username = kwargs['token']['username']
     txn_id = request.headers.get('X-REQUEST-ID', 'noId')
     resp_data = {'user' : username}
     body = kwargs['body']
     machine_name = body['name']
     image = body['image']
     front_end = '{}_{}'.format(username, body['frontend'])
     back_end = '{}_{}'.format(username, body['backend'])
     ram = body.get('ram', 4)
     cpu_count = body.get('cpu-count', 2)
     task = current_app.celery_app.send_task('onefs.create', [username, machine_name, image, front_end, back_end, ram, cpu_count, txn_id])
     resp_data['content'] = {'task-id': task.id}
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = 202
     resp.headers.add('Link', '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL, self.route_base, task.id))
     resp.headers.add('Link', '<{0}{1}/config>; rel=config>'.format(const.VLAB_URL, self.route_base))
     return resp
コード例 #25
0
 def delete(self, *args, **kwargs):
     """Destroy a Deployment"""
     user_token = request.headers.get('X-Auth')
     username = kwargs['token']['username']
     txn_id = request.headers.get('X-REQUEST-ID', 'noId')
     resp_data = {'user': username}
     template = kwargs['body']['template']
     client_ip = kwargs['token']['client_ip']
     task = current_app.celery_app.send_task(
         'deployment.delete',
         [username, user_token, template, client_ip, txn_id])
     resp_data['content'] = {'task-id': task.id}
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = 202
     resp.headers.add(
         'Link',
         '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL,
                                                self.route_base, task.id))
     return resp
コード例 #26
0
ファイル: healthcheck.py プロジェクト: willnx/vlab_ipam_api
 def get(self):
     """End point for health checks"""
     resp = {}
     status = 200
     resp['version'] = pkg_resources.get_distribution('vlab-ipam-api').version
     fwall = firewall.FireWall()
     try:
         with Database() as db:
             resp['database'] = list(db.execute("select * from ipam;"))
         resp['firewall'] = {}
         resp['firewall']['nat'] = fwall.show(table='nat', format='raw')
         resp['firewall']['filter'] = fwall.show(table='filter', format='raw')
     except Exception as doh:
         resp['error'] = '%s' % doh
         status = 500
     response = Response(ujson.dumps(resp))
     response.status_code = status
     response.headers['Content-Type'] = 'application/json'
     return response
コード例 #27
0
ファイル: addr.py プロジェクト: willnx/vlab_ipam_api
 def get(self, *args, **kwargs):
     """Display the Port Map rules defined on the NAT firewall"""
     username = kwargs['token']['username']
     resp_data = {'user': username, 'content': {}}
     status_code = 200
     name = request.args.get('name', None)
     addr = request.args.get('addr', '')
     component = request.args.get('component', None)
     if args_valid(name=name, addr=addr, component=component):
         with Database() as db:
             resp_data['content'] = db.lookup_addr(name=name,
                                                   addr=addr,
                                                   component=component)
     else:
         resp_data[
             'error'] = 'Params are mutually exclusive. Supplied: name={}, addr={}, component={}'.format(
                 name, addr, component)
         status_code = 400
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = status_code
     return resp
コード例 #28
0
 def post(self, *args, **kwargs):
     """Create a template"""
     username = kwargs['token']['username']
     machines = kwargs['body']['machines']
     portmaps = kwargs['body']['portmaps']
     summary = kwargs['body']['summary']
     template = kwargs['body']['name']
     resp_data = {'user': username}
     txn_id = request.headers.get('X-REQUEST-ID', 'noId')
     body = kwargs['body']
     task = current_app.celery_app.send_task(
         'deployment.create_template',
         [username, template, machines, portmaps, summary, txn_id])
     resp_data['content'] = {'task-id': task.id}
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = 202
     resp.headers.add(
         'Link',
         '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL,
                                                self.route_base, task.id))
     return resp
コード例 #29
0
 def images(self, *args, **kwargs):
     """Show available versions of Deployment that can be deployed"""
     username = kwargs['token']['username']
     verbose = request.args.get('verbose', '')
     if verbose:
         if verbose.lower().startswith('t') or verbose.startswith('1'):
             verbose = True
     else:
         verbose = False
     txn_id = request.headers.get('X-REQUEST-ID', 'noId')
     resp_data = {'user': username}
     task = current_app.celery_app.send_task('deployment.images',
                                             [verbose, txn_id])
     resp_data['content'] = {'task-id': task.id}
     resp = Response(ujson.dumps(resp_data))
     resp.status_code = 202
     resp.headers.add(
         'Link',
         '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL,
                                                self.route_base, task.id))
     return resp
コード例 #30
0
    def config(self, *args, **kwargs):
        """Set the configuration of a OneFS node"""
        status_code = 202
        username = kwargs['token']['username']
        txn_id = request.headers.get('X-REQUEST-ID', 'noId')
        resp_data = {'user' : username}
        # Aligning these just makes it easier to read
        cluster_name    = kwargs['body']['cluster_name']
        name            = kwargs['body']['name']
        version         = kwargs['body'].get('version', None)
        int_netmask     = kwargs['body'].get('int_netmask', None)
        int_ip_low      = kwargs['body'].get('int_ip_low', None)
        int_ip_high     = kwargs['body'].get('int_ip_high', None)
        ext_netmask     = kwargs['body'].get('ext_netmask', None)
        ext_ip_low      = kwargs['body'].get('ext_ip_low', None)
        ext_ip_high     = kwargs['body'].get('ext_ip_high', None)
        gateway         = kwargs['body'].get('gateway', None)
        encoding        = kwargs['body'].get('encoding', None)
        sc_zonename     = kwargs['body'].get('sc_zonename', None)
        smartconnect_ip = kwargs['body'].get('smartconnect_ip', None)
        join_cluster    = kwargs['body'].get('join', False)
        compliance      = kwargs['body'].get('compliance', False)
        dns_servers     = ','.join(kwargs['body'].get('dns_servers', []))
        # Ensure supplied values wont generate an error in the OneFS config wizard
        error = supplied_config_values_are_valid(int_netmask=int_netmask,
                                                 int_ip_low=int_ip_low,
                                                 int_ip_high=int_ip_high,
                                                 ext_netmask=ext_netmask,
                                                 ext_ip_low=ext_ip_low,
                                                 ext_ip_high=ext_ip_high,
                                                 gateway=gateway,
                                                 cluster_name=cluster_name,
                                                 sc_zonename=sc_zonename,
                                                 smartconnect_ip=smartconnect_ip,
                                                 dns_servers=dns_servers,
                                                 join_cluster=join_cluster)
        if error:
            resp_data['error'] = error
            status_code = 400
            link = None
        else:
            task = current_app.celery_app.send_task('onefs.config', kwargs={'cluster_name' : cluster_name,
                                                                            'name' : name,
                                                                            'username' : username,
                                                                            'version' : version,
                                                                            'int_netmask' : int_netmask,
                                                                            'int_ip_low' : int_ip_low,
                                                                            'int_ip_high' : int_ip_high,
                                                                            'ext_netmask' : ext_netmask,
                                                                            'ext_ip_low' : ext_ip_low,
                                                                            'ext_ip_high' : ext_ip_high,
                                                                            'gateway' : gateway,
                                                                            'dns_servers' : dns_servers,
                                                                            'encoding' : encoding,
                                                                            'sc_zonename' : sc_zonename,
                                                                            'smartconnect_ip' : smartconnect_ip,
                                                                            'join_cluster' : join_cluster,
                                                                            'compliance' : compliance,
                                                                            'txn_id' : txn_id})

            resp_data['content'] = {'task-id': task.id}
            link = '<{0}{1}/task/{2}>; rel=status'.format(const.VLAB_URL, self.route_base, task.id)
        resp = Response(ujson.dumps(resp_data))
        resp.status_code = status_code
        if link:
            resp.headers.add('Link', link)
        return resp