Begin refactoring process, messy template usage
diff --git a/gstack/controllers/__init__.py b/gstack/controllers/__init__.py
index 47e309d..13e35e8 100644
--- a/gstack/controllers/__init__.py
+++ b/gstack/controllers/__init__.py
@@ -20,5 +20,12 @@
import os
import glob
-__all__ = [os.path.basename(
- f)[:-3] for f in glob.glob(os.path.dirname(__file__) + '/*.py')]
+__all__ = [os.path.basename(f)[:-3] for f in glob.glob(os.path.dirname(__file__) + '/*.py')]
+
+
+def filter_by_name(data, name):
+ for item in data:
+ if item['name'] == name:
+ return item
+
+ return None
diff --git a/gstack/controllers/disks.py b/gstack/controllers/disks.py
index 0743a48..888507e 100644
--- a/gstack/controllers/disks.py
+++ b/gstack/controllers/disks.py
@@ -21,7 +21,9 @@
from flask import request, url_for
from gstack import app, authentication
from gstack.services import requester
-from gstack.controllers import zones, helper, errors
+from gstack import helpers
+from gstack import controllers
+from gstack.controllers import zones, errors
def _get_disks(authorization, args=None):
@@ -47,7 +49,7 @@
)
if disk_list['listvolumesresponse']:
- response = helper.filter_by_name(
+ response = controllers.filter_by_name(
data=disk_list['listvolumesresponse']['volume'],
name=disk
)
@@ -66,7 +68,7 @@
response['description'] = cloudstack_response['name']
response['sizeGb'] = cloudstack_response['size']
- response['selfLink'] = urllib.unquote_plus(helper.get_root_url() + url_for(
+ response['selfLink'] = urllib.unquote_plus(helpers.get_root_url() + url_for(
'getmachinetype',
projectid=projectid,
machinetype=cloudstack_response['name'],
@@ -88,7 +90,7 @@
zone_list = zones.get_zone_names(authorization=authorization)
disk = None
- filter = helper.get_filter(request.args)
+ filter = helpers.get_filter(request.args)
if 'name' in filter:
disk = filter['name']
@@ -130,14 +132,14 @@
'items': items
}
- return helper.create_response(data=populated_response)
+ return helpers.create_response(data=populated_response)
@app.route('/compute/v1/projects/<projectid>/zones/<zone>/disks', methods=['GET'])
@authentication.required
def listdisks(projectid, authorization, zone):
disk = None
- filter = helper.get_filter(request.args)
+ filter = helpers.get_filter(request.args)
if 'name' in filter:
disk = filter['name']
@@ -150,7 +152,7 @@
args={'keyword': disk}
)
if disk_list['listvolumesresponse']:
- disk = helper.filter_by_name(
+ disk = controllers.filter_by_name(
data=disk_list['listvolumesresponse']['volume'],
name=disk
)
@@ -181,7 +183,7 @@
'items': items
}
- return helper.create_response(data=populated_response)
+ return helpers.create_response(data=populated_response)
@app.route('/compute/v1/projects/<projectid>/zones/<zone>/disks/<disk>', methods=['GET'])
@@ -193,7 +195,7 @@
)
if response:
- return helper.create_response(
+ return helpers.create_response(
data=_cloudstack_volume_to_gce(
cloudstack_response=response,
projectid=projectid,
diff --git a/gstack/controllers/helper.py b/gstack/controllers/helper.py
deleted file mode 100644
index 05830ce..0000000
--- a/gstack/controllers/helper.py
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-import urllib
-from gstack import app
-from flask import jsonify
-
-
-def create_response(data):
- res = jsonify(data)
- res.status_code = 200
-
- return res
-
-
-def get_filter(data):
- filter = {}
-
- if 'filter' in data:
- filter = urllib.unquote_plus(data['filter'])
- filter = dict(filter.split(' eq ') for values in filter)
-
- return filter
-
-
-def filter_by_name(data, name):
- for item in data:
- if item['name'] == name:
- return item
- return None
-
-
-def get_root_url():
- return 'https://' + \
- app.config['GSTACK_BIND_ADDRESS'] + ':' + app.config['GSTACK_PORT']
diff --git a/gstack/controllers/images.py b/gstack/controllers/images.py
index 25c400a..c2e5ec5 100755
--- a/gstack/controllers/images.py
+++ b/gstack/controllers/images.py
@@ -20,7 +20,9 @@
import urllib
from gstack import app, authentication
from gstack.services import requester
-from gstack.controllers import helper, errors
+from gstack import helpers
+from gstack import controllers
+from gstack.controllers import errors
from flask import request, url_for
@@ -50,7 +52,7 @@
)
if image_list['listtemplatesresponse']:
- response = helper.filter_by_name(
+ response = controllers.filter_by_name(
data=image_list['listtemplatesresponse']['template'],
name=image
)
@@ -62,6 +64,7 @@
def _create_populated_image_response(projectid, images=None):
if not images:
images = []
+
populated_response = {
'kind': 'compute#imageList',
'selfLink': request.base_url,
@@ -98,14 +101,14 @@
@authentication.required
def listnocentoscloudimages(authorization):
populated_response = _create_populated_image_response('centos-cloud')
- return helper.create_response(data=populated_response)
+ return helpers.create_response(data=populated_response)
@app.route('/compute/v1/projects/debian-cloud/global/images', methods=['GET'])
@authentication.required
def listnodebiancloudimages(authorization):
populated_response = _create_populated_image_response('debian-cloud')
- return helper.create_response(data=populated_response)
+ return helpers.create_response(data=populated_response)
@app.route('/compute/v1/projects/<projectid>/global/images', methods=['GET'])
@@ -115,15 +118,20 @@
authorization=authorization
)
- images = []
if image_list['listtemplatesresponse']:
for image in image_list['listtemplatesresponse']['template']:
- images.append(_cloudstack_template_to_gce(
- cloudstack_response=image,
- selfLink=request.base_url + '/' + image['name']))
+ image['selflink'] = request.base_url + '/' + image['name']
- populated_response = _create_populated_image_response(projectid, images)
- return helper.create_response(data=populated_response)
+ kwargs = {
+ 'template_name_or_list': 'images.json',
+ 'selflink': request.base_url,
+ 'request_id': 'projects/' + projectid + '/global/images',
+ 'request_kind': 'compute#imageList',
+ 'response': image_list['listtemplatesresponse']
+ }
+ return helpers.successful_response(
+ **kwargs
+ )
@app.route('/compute/v1/projects/<projectid>/global/images/<image>', methods=['GET'])
@@ -135,7 +143,7 @@
)
if response:
- return helper.create_response(
+ return helpers.create_response(
data=_cloudstack_template_to_gce(response)
)
else:
diff --git a/gstack/controllers/index.py b/gstack/controllers/index.py
index 293c6ac..fc1f925 100755
--- a/gstack/controllers/index.py
+++ b/gstack/controllers/index.py
@@ -19,7 +19,7 @@
from gstack import app
-from gstack.controllers import helper
+from gstack import helpers
import json
@@ -28,9 +28,9 @@
with open(app.config['DATA'] + '/v1.json') as template:
discovery_template = json.loads(template.read())
- discovery_template['baseUrl'] = helper.get_root_url() + '/' + app.config['PATH']
+ discovery_template['baseUrl'] = helpers.get_root_url() + '/' + app.config['PATH']
discovery_template['basePath'] = '/' + app.config['PATH']
- discovery_template['rootUrl'] = helper.get_root_url() + '/'
+ discovery_template['rootUrl'] = helpers.get_root_url() + '/'
discovery_template['servicePath'] = app.config['PATH']
- return helper.create_response(data=discovery_template)
+ return helpers.create_response(data=discovery_template)
diff --git a/gstack/controllers/instances.py b/gstack/controllers/instances.py
index 8bb0e14..4c196ae 100755
--- a/gstack/controllers/instances.py
+++ b/gstack/controllers/instances.py
@@ -19,10 +19,12 @@
import json
import urllib
+from gstack import helpers
+from gstack import controllers
from flask import request, url_for
from gstack import app, authentication
from gstack.services import requester
-from gstack.controllers import zones, helper, operations, images, errors, machine_type, networks
+from gstack.controllers import zones, operations, images, errors, machine_type, networks
def _get_virtual_machines(authorization, args=None):
@@ -134,7 +136,7 @@
response['networkInterfaces'].append(networking)
- response['selfLink'] = urllib.unquote_plus(helper.get_root_url() + url_for(
+ response['selfLink'] = urllib.unquote_plus(helpers.get_root_url() + url_for(
'getinstance',
projectid=projectid,
instance=cloudstack_response['name'],
@@ -154,7 +156,7 @@
)
if virtual_machine_list['listvirtualmachinesresponse']:
- response = helper.filter_by_name(
+ response = controllers.filter_by_name(
data=virtual_machine_list['listvirtualmachinesresponse']['virtualmachine'],
name=instance
)
@@ -170,7 +172,7 @@
virtual_machine_list = _get_virtual_machines(authorization=authorization)
instance = None
- filter = helper.get_filter(request.args)
+ filter = helpers.get_filter(request.args)
if 'name' in filter:
instance = filter['name']
@@ -211,14 +213,14 @@
'selfLink': request.base_url,
'items': items
}
- return helper.create_response(data=populated_response)
+ return helpers.create_response(data=populated_response)
@app.route('/compute/v1/projects/<projectid>/zones/<zone>/instances', methods=['GET'])
@authentication.required
def listinstances(authorization, projectid, zone):
instance = None
- filter = helper.get_filter(request.args)
+ filter = helpers.get_filter(request.args)
if 'name' in filter:
instance = filter['name']
@@ -258,7 +260,7 @@
'items': items
}
- return helper.create_response(data=populated_response)
+ return helpers.create_response(data=populated_response)
@app.route('/compute/v1/projects/<projectid>/zones/<zone>/instances/<instance>', methods=['GET'])
@@ -270,7 +272,7 @@
)
if response:
- return helper.create_response(
+ return helpers.create_response(
data=_cloudstack_virtual_machine_to_gce(
cloudstack_response=response,
projectid=projectid,
@@ -325,7 +327,7 @@
authorization=authorization
)
- return helper.create_response(data=populated_response)
+ return helpers.create_response(data=populated_response)
@app.route('/compute/v1/projects/<projectid>/zones/<zone>/instances/<instance>', methods=['DELETE'])
@@ -339,4 +341,4 @@
authorization=authorization
)
- return helper.create_response(data=populated_response)
+ return helpers.create_response(data=populated_response)
diff --git a/gstack/controllers/machine_type.py b/gstack/controllers/machine_type.py
index f55e211..9dfd71b 100755
--- a/gstack/controllers/machine_type.py
+++ b/gstack/controllers/machine_type.py
@@ -20,8 +20,10 @@
import urllib
from gstack import app
from gstack import authentication
+from gstack import helpers
+from gstack import controllers
from gstack.services import requester
-from gstack.controllers import errors, zones, helper
+from gstack.controllers import errors, zones
from flask import request, url_for
@@ -45,7 +47,7 @@
)
if machinetype_list['listserviceofferingsresponse']:
- response = helper.filter_by_name(
+ response = controllers.filter_by_name(
data=machinetype_list['listserviceofferingsresponse'][
'serviceoffering'],
name=machinetype
@@ -65,7 +67,7 @@
response['guestCpus'] = cloudstack_response['cpunumber']
response['memoryMb'] = cloudstack_response['memory']
- response['selfLink'] = urllib.unquote_plus(helper.get_root_url() + url_for(
+ response['selfLink'] = urllib.unquote_plus(helpers.get_root_url() + url_for(
'getmachinetype',
projectid=projectid,
machinetype=cloudstack_response['name'],
@@ -107,14 +109,14 @@
'selfLink': urllib.unquote_plus(request.base_url),
'items': items
}
- return helper.create_response(data=populated_response)
+ return helpers.create_response(data=populated_response)
@app.route('/compute/v1/projects/<projectid>/zones/<zone>/machineTypes', methods=['GET'])
@authentication.required
def listmachinetype(projectid, authorization, zone):
machinetype = None
- filter = helper.get_filter(request.args)
+ filter = helpers.get_filter(request.args)
if 'name' in filter:
machinetype = filter['name']
@@ -127,7 +129,7 @@
args={'keyword': machinetype}
)
if machinetype_list['listserviceofferingsresponse']:
- machinetype = helper.filter_by_name(
+ machinetype = controllers.filter_by_name(
data=machinetype_list['listserviceofferingsresponse'][
'serviceoffering'],
name=machinetype
@@ -159,7 +161,7 @@
'items': items
}
- return helper.create_response(data=populated_response)
+ return helpers.create_response(data=populated_response)
@app.route('/compute/v1/projects/<projectid>/zones/<zone>/machineTypes/<machinetype>', methods=['GET'])
@@ -171,7 +173,7 @@
)
if response:
- return helper.create_response(
+ return helpers.create_response(
data=_cloudstack_machinetype_to_gce(
cloudstack_response=response,
projectid=projectid,
diff --git a/gstack/controllers/networks.py b/gstack/controllers/networks.py
index 03a1799..ae2aef5 100644
--- a/gstack/controllers/networks.py
+++ b/gstack/controllers/networks.py
@@ -19,10 +19,12 @@
import urllib
import json
+from gstack import helpers
+from gstack import controllers
from flask import request, url_for
from gstack import app, authentication
from gstack.services import requester
-from gstack.controllers import helper, errors
+from gstack.controllers import errors
def _get_networks(authorization, args=None):
@@ -48,7 +50,7 @@
)
if securitygroup_list['listsecuritygroupsresponse']:
- response = helper.filter_by_name(
+ response = controllers.filter_by_name(
data=securitygroup_list['listsecuritygroupsresponse']['securitygroup'],
name=securitygroup
)
@@ -138,7 +140,7 @@
projectid,
networks
)
- return helper.create_response(data=populated_response)
+ return helpers.create_response(data=populated_response)
@app.route('/compute/v1/projects/<projectid>/global/networks/<network>', methods=['GET'])
@@ -150,7 +152,7 @@
)
if response:
- return helper.create_response(
+ return helpers.create_response(
data=_cloudstack_network_to_gce(response)
)
else:
@@ -190,7 +192,7 @@
'kind': 'compute#operation',
'operationType': 'insert',
'targetLink': urllib.unquote_plus(
- helper.get_root_url() + url_for(
+ helpers.get_root_url() + url_for(
'getnetwork',
projectid=projectid,
network=data['name']
@@ -200,7 +202,7 @@
'progress': 100
}
- return helper.create_response(data=populated_response)
+ return helpers.create_response(data=populated_response)
@app.route('/compute/v1/projects/<projectid>/global/networks/<network>', methods=['DELETE'])
@@ -224,4 +226,4 @@
'progress': 100
}
- return helper.create_response(data=populated_response)
+ return helpers.create_response(data=populated_response)
diff --git a/gstack/controllers/operations.py b/gstack/controllers/operations.py
index de31b32..9bbdd46 100644
--- a/gstack/controllers/operations.py
+++ b/gstack/controllers/operations.py
@@ -20,7 +20,7 @@
import urllib
from gstack import app, publickey_storage
from gstack import authentication
-from gstack.controllers import helper
+from gstack import helpers
from gstack.services import requester
from flask import url_for
@@ -43,7 +43,7 @@
'operationType': 'delete',
'name': async_result['jobid'],
'startTime': async_result['created'],
- 'selfLink': urllib.unquote_plus(helper.get_root_url() + url_for(
+ 'selfLink': urllib.unquote_plus(helpers.get_root_url() + url_for(
'getoperations',
projectid=projectid,
operationid=async_result['jobid']
@@ -57,14 +57,14 @@
elif async_result['jobstatus'] is 1:
populated_response['status'] = 'DONE'
populated_response['zone'] = urllib.unquote_plus(
- helper.get_root_url() +
+ helpers.get_root_url() +
url_for(
'getzone',
projectid=projectid,
zone=async_result['jobresult']['virtualmachine']['zonename'],
))
populated_response['targetLink'] = urllib.unquote_plus(
- helper.get_root_url() +
+ helpers.get_root_url() +
url_for(
'getinstance',
projectid=projectid,
@@ -112,7 +112,7 @@
'user': async_result['userid'],
'insertTime': async_result['created'],
'startTime': async_result['created'],
- 'selfLink': urllib.unquote_plus(helper.get_root_url() + url_for(
+ 'selfLink': urllib.unquote_plus(helpers.get_root_url() + url_for(
'getoperations',
projectid=projectid,
operationid=async_result['jobid']
@@ -129,14 +129,14 @@
populated_response['status'] = 'DONE'
populated_response['id'] = async_result['jobid']
populated_response['zone'] = urllib.unquote_plus(
- helper.get_root_url() +
+ helpers.get_root_url() +
url_for(
'getzone',
projectid=projectid,
zone=async_result['jobresult']['virtualmachine']['zonename'],
))
populated_response['targetLink'] = urllib.unquote_plus(
- helper.get_root_url() +
+ helpers.get_root_url() +
url_for(
'getinstance',
projectid=projectid,
@@ -182,7 +182,7 @@
@app.route('/compute/v1/projects/<projectid>/global/operations/<operationid>', methods=['GET'])
@authentication.required
def getoperations(authorization, operationid, projectid):
- return helper.create_response(create_response(
+ return helpers.create_response(create_response(
authorization=authorization,
operationid=operationid,
projectid=projectid
diff --git a/gstack/controllers/project.py b/gstack/controllers/project.py
index d6e0776..066724c 100755
--- a/gstack/controllers/project.py
+++ b/gstack/controllers/project.py
@@ -19,8 +19,10 @@
from gstack import app, publickey_storage
from gstack import authentication
+from gstack import helpers
+from gstack import controllers
from gstack.services import requester
-from gstack.controllers import errors, helper
+from gstack.controllers import errors
from flask import jsonify, request, url_for
import json
import urllib
@@ -87,7 +89,7 @@
)
if account_list['listaccountsresponse']:
- response = helper.filter_by_name(
+ response = controllers.filter_by_name(
data=account_list['listaccountsresponse']['account'],
name=projectid
)
@@ -213,7 +215,7 @@
res = jsonify({
"kind": "compute#operation",
'operationType': 'setMetadata',
- 'targetLink': urllib.unquote_plus(helper.get_root_url() + url_for(
+ 'targetLink': urllib.unquote_plus(helpers.get_root_url() + url_for(
'getproject',
projectid=projectid
)),
diff --git a/gstack/controllers/regions.py b/gstack/controllers/regions.py
index 50f3e5d..dc7d071 100755
--- a/gstack/controllers/regions.py
+++ b/gstack/controllers/regions.py
@@ -19,9 +19,10 @@
from gstack import app
+from gstack import helpers
from gstack import authentication
from gstack.services import requester
-from gstack.controllers import errors, helper
+from gstack.controllers import errors
from flask import request, url_for
@@ -65,7 +66,7 @@
'selfLink': request.base_url,
'items': regions
}
- return helper.create_response(data=populated_response)
+ return helpers.create_response(data=populated_response)
@app.route('/compute/v1/projects/<projectid>/regions/<region>', methods=['GET'])
@@ -77,7 +78,7 @@
)
if region == cloudstack_response['listregionsresponse']['region'][0]['name']:
- return helper.create_response(
+ return helpers.create_response(
data=_cloudstack_region_to_gce(
cloudstack_response['listregionsresponse']['region'][0]
)
diff --git a/gstack/controllers/zones.py b/gstack/controllers/zones.py
index 8e433f3..7738333 100755
--- a/gstack/controllers/zones.py
+++ b/gstack/controllers/zones.py
@@ -18,9 +18,11 @@
# under the License.
from flask import request, url_for
+from gstack import helpers
+from gstack import controllers
from gstack import app, authentication
from gstack.services import requester
-from gstack.controllers import helper, errors
+from gstack.controllers import errors
def _get_zones(authorization, args=None):
@@ -46,7 +48,7 @@
)
if zone_list['listzonesresponse']:
- response = helper.filter_by_name(
+ response = controllers.filter_by_name(
data=zone_list['listzonesresponse']['zone'],
name=zone
)
@@ -99,7 +101,7 @@
'items': items
}
- return helper.create_response(data=populated_response)
+ return helpers.create_response(data=populated_response)
@app.route('/compute/v1/projects/<projectid>/zones/<zone>', methods=['GET'])
@@ -111,7 +113,7 @@
)
if response:
- return helper.create_response(
+ return helpers.create_response(
data=_cloudstack_zone_to_gce(response)
)
else:
diff --git a/gstack/helpers.py b/gstack/helpers.py
index d8dddd9..556bf27 100644
--- a/gstack/helpers.py
+++ b/gstack/helpers.py
@@ -18,6 +18,44 @@
# under the License.
import os
+import urllib
+from gstack import app
+from flask import jsonify, render_template, make_response
+
+
+def create_response(data):
+ res = jsonify(data)
+ res.status_code = 200
+
+ return res
+
+
+def successful_response(**kwargs):
+ content = render_template(**kwargs)
+ response = make_response(content)
+ print response
+ response.headers['Content-Type'] = 'application/json'
+ return _create_response(response, '200')
+
+
+def _create_response(response, code):
+ response.status_code = int(code)
+ return response
+
+
+def get_filter(data):
+ filter = {}
+
+ if 'filter' in data:
+ filter = urllib.unquote_plus(data['filter'])
+ filter = dict(filter.split(' eq ') for values in filter)
+
+ return filter
+
+
+def get_root_url():
+ return 'https://' + \
+ app.config['GSTACK_BIND_ADDRESS'] + ':' + app.config['GSTACK_PORT']
def read_file(name):
diff --git a/gstack/templates/images.json b/gstack/templates/images.json
new file mode 100644
index 0000000..d986853
--- /dev/null
+++ b/gstack/templates/images.json
@@ -0,0 +1,13 @@
+{% extends "response.json" %}{% block response_content %}
+ "items":[{% for image in response.template %}
+ {
+ "creationTimestamp":"{{response.template|length}}",
+ "description":"{{image.displaytext}}",
+ "id":"{{image.id}}",
+ "kind":"compute#image",
+ "name":"{{image.name}}",
+ "selfLink":"{{image.selflink}}",
+ "status":"{{image.isready}}"
+ }{% if loop.index < response.template|length %},{% endif %}{% endfor %}
+ ]
+{% endblock %}
diff --git a/gstack/templates/response.json b/gstack/templates/response.json
new file mode 100644
index 0000000..1bc68d1
--- /dev/null
+++ b/gstack/templates/response.json
@@ -0,0 +1,6 @@
+{
+ {% if not error %}"id":"{{request_id}}",
+ "kind":"{{request_kind}}",
+ "selfLink":"{{selflink}}",{% block response_content %}
+ {% endblock %}{% endif %}
+}
diff --git a/setup.py b/setup.py
index 576eb24..e49f8be 100755
--- a/setup.py
+++ b/setup.py
@@ -45,7 +45,8 @@
url="https://github.com/NOPping/gstack",
platforms=("Any"),
license="LICENSE.txt",
- package_data={'': ['LICENSE.txt', 'data/*']},
+ package_data={'': ['LICENSE.txt', 'data/*'],
+ 'ec2stack': ['templates/*.json']},
packages=[
"gstack", "gstack.controllers", "gstack.models",
"gstack.services", "gstack.data", "pyoauth2"],
@@ -56,6 +57,16 @@
"Flask-SQLAlchemy",
"flask",
],
+ classifiers=[
+ 'Development Status :: 3 - Alpha',
+ 'Environment :: Console',
+ 'Intended Audience :: System Administrators',
+ 'License :: OSI Approved :: Apache Software License',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python',
+ 'Topic :: Utilities',
+ 'Programming Language :: Python :: 2.7',
+ ],
zip_safe=False,
entry_points="""
[console_scripts]