All api calls implemented

This commit is contained in:
efedorova 2013-10-10 18:14:56 +04:00
parent e1b704c61d
commit 31472fb11b
4 changed files with 111 additions and 168 deletions

View File

@ -1,83 +0,0 @@
name: Demo Service
type: demoService
description: >-
<strong> Demo Service </strong>
shows how Murano is working.
unitTemplates:
- {}
forms:
- serviceConfiguration:
fields:
- name: configuration
type: string
hidden: true
initial: standalone
- name: name
type: string
label: Service Name
description: >-
To identify your service in logs please specify a service name
- name: dcInstances
type: instance
label: Instance Count
description: >-
Murano can provision more then one instance of the service at a time.
For a demo scenario only 2 instances are allowed.
attributeNames: units
minValue: 1
maxValue: 2
initial: 2
<<<<<<< HEAD
helpText: Enter 1 and 2 value
- name: unitNamingPattern
type: string
label: Hostname template
description: >-
For your convenience all instance hostnames can be named
in the same way. Enter a name and use # character for incrementation.
For example, host# turns into host1, host2, etc. Please follow Windows
hostname restrictions.
required: false
regexpValidator: '^(([a-zA-Z0-9#][a-zA-Z0-9-#]*[a-zA-Z0-9#])\.)*([A-Za-z0-9#]|[A-Za-z0-9#][A-Za-z0-9-#]*[A-Za-z0-9#])$'
helpText: Optional field for a machine hostname template
# temporaryHack
widgetMedia:
js: [muranodashboard/js/support_placeholder.js]
css: {all: [muranodashboard/css/support_placeholder.css]}
validators:
# if unitNamingPattern is given and dcInstances > 1, then '#' should occur in unitNamingPattern
- expr: {YAQL: not $.serviceConfiguration.unitNamingPattern.bool() or ('#' in $.serviceConfiguration.unitNamingPattern)}
message: Incrementation symbol "#" is required in the Hostname template
- instanceConfiguration:
fields:
- name: title
type: string
required: false
hidden: true
attributeNames: false
descriptionTitle: Instance Configuration
description: Specify some instance parameters on which service would be created.
- name: flavor
type: flavor
label: Instance flavor
description: >-
Select registered in Openstack flavor. Consider that service performance
depends on this parameter.
required: false
- name: osImage
type: image
label: Instance image
description: >-
Select valid image for a service. Image should already be prepared and
registered in glance.
- name: availabilityZone
type: azone
label: Availability zone
description: Select availability zone where service would be installed.
required: false
=======
helpText: Enter 1 and 2 value
>>>>>>> 0dffd2a... Add new service for demo

View File

@ -12,27 +12,34 @@
# License for the specific language governing permissions and limitations
# under the License.
import os
#---mappings to possible data types in service manifests---
UI_FORMS = u"ui_forms"
WORKFLOWS = u"workflows"
HEAT_TEMPLATES = u"heat_templates"
AGENT_TEMPLATES = u"agent_templates"
SCRIPTS = u"scripts"
MANIFESTS = u"manifests"
DATA_TYPES = [UI_FORMS, WORKFLOWS, HEAT_TEMPLATES, AGENT_TEMPLATES, SCRIPTS]
DATA_TYPES = [UI_FORMS, WORKFLOWS, HEAT_TEMPLATES, AGENT_TEMPLATES, SCRIPTS, MANIFESTS]
#---main directory - parent for manifests files and data types directories
ROOT_DIRECTORY = os.path.join(os.path.dirname(__file__),
u'Services')
#---directory names of data types
UI_FORMS_ROOT_DIR = u"ui_forms"
WORKFLOWS_ROOT_DIR = u"workflows"
HEAT_TEMPLATES_ROOT_DIR = u"heat_templates"
AGENT_TEMPLATES_ROOT_DIR = u"agent_templates"
SCRIPTS_ROOT_DIR = u"scripts"
#root directory should contain manifests files
ROOT_DIRECTORY = os.path.join(os.path.dirname(__file__),
u'Services')
DIRECTORIES_BY_TYPE = {UI_FORMS: UI_FORMS_ROOT_DIR,
WORKFLOWS: WORKFLOWS_ROOT_DIR,
HEAT_TEMPLATES: HEAT_TEMPLATES_ROOT_DIR,
AGENT_TEMPLATES_ROOT_DIR: AGENT_TEMPLATES_ROOT_DIR,
SCRIPTS: SCRIPTS_ROOT_DIR
SCRIPTS: SCRIPTS_ROOT_DIR,
MANIFESTS: ROOT_DIRECTORY
}

View File

@ -16,51 +16,12 @@ import os
import yaml
import logging as log
from manifest import Manifest
from consts import DIRECTORIES_BY_TYPE, DATA_TYPES
class ManifestParser(object):
def __init__(self,
manifest_directory,
ui_forms_directory="ui_forms",
workflows_directory="workflows",
heat_templates_directory="heat_templates",
agent_templates_directory="agent_templates",
scripts_directory="scripts"
):
"""
manifest_directory -- absolute path to the directory with manifests
ui_forms_directory -- absolute or relative path to ui forms definitions
workflows_directory -- absolute or relative path to workflow
definitions
heat_templates_directory -- absolute or relative path to heat templates
agent_templates_directory --absolute or relative path to agent
templates
scripts_directory -- absolute or relative path to scripts
"""
if not os.path.isabs(ui_forms_directory):
ui_forms_directory = os.path.join(manifest_directory,
ui_forms_directory)
if not os.path.isabs(workflows_directory):
workflows_directory = os.path.join(manifest_directory,
workflows_directory)
if not os.path.isabs(heat_templates_directory):
heat_templates_directory = os.path.join(manifest_directory,
heat_templates_directory)
if not os.path.isabs(agent_templates_directory):
agent_templates_directory = os.path.join(manifest_directory,
agent_templates_directory)
if not os.path.isabs(scripts_directory):
scripts_directory = os.path.join(manifest_directory,
scripts_directory)
def __init__(self, manifest_directory):
self.manifest_directory = manifest_directory
self.directory_mapping = {"ui_forms": ui_forms_directory,
"workflows": workflows_directory,
"heat_templates":
heat_templates_directory,
"agent_templates": agent_templates_directory,
"scripts": scripts_directory
}
def parse(self):
manifests = []
@ -84,16 +45,16 @@ class ManifestParser(object):
for key, value in service_manifest_data.iteritems():
valid_file_info = True
directory_location = self.directory_mapping.get(key)
if directory_location:
if key in DATA_TYPES:
root_directory = DIRECTORIES_BY_TYPE.get(key)
if not isinstance(value, list):
log.error("{0} section should represent a file"
" listing in manifest {1}"
"".format(directory_location, file))
"".format(root_directory, file))
valid_file_info = False
continue
for i, filename in enumerate(value):
absolute_path = os.path.join(directory_location,
absolute_path = os.path.join(root_directory,
filename)
service_manifest_data[key][i] = absolute_path

130
test.py
View File

@ -13,7 +13,8 @@
# under the License.
from flask import Flask, make_response, send_from_directory, send_file, \
jsonify, request
jsonify, request, abort
from werkzeug import secure_filename
import os
from parser import ManifestParser
from archiver import Archiver
@ -27,10 +28,6 @@ def get_ui_data():
manifests = parser.parse()
archive_name = Archiver().create(manifests, "ui_forms")
# resp = make_response()
# resp.mimetype = 'application/z-gzip'
# resp.headers["Content-Disposition"] = "attachment; " \
# "filename={0}".format(location)
return send_from_directory(os.path.dirname(__file__), archive_name)
@ -48,41 +45,102 @@ def get_conductor_data():
@app.route('/admin/<data_type>', methods=['GET', 'POST'])
def get_data_type_locations(data_type):
if request.method == 'GET':
parser = ManifestParser(app.config["ROOT_DIRECTORY"])
manifests = parser.parse()
locations = []
if data_type not in app.config['DATA_TYPES']:
#return 404
pass
for manifest in manifests:
if hasattr(manifest, data_type):
for file_path in getattr(manifest, data_type):
locations.append(file_path)
if request.method == 'POST':
return jsonify(data_type=locations)
@app.route('/admin/<data_type>/<path>', methods=['GET', 'POST'])
def get_data_type_locations_by_path_or_get_file(data_type, path):
locations = []
####### validation ########
if data_type not in app.config['DATA_TYPES']:
abort(404)
result_path = os.path.join(app.config["ROOT_DIRECTORY"],
app.config["DIRECTORIES_BY_TYPE"][data_type],
app.config["DIRECTORIES_BY_TYPE"][
data_type])
####### end validation ########
if request.method == 'GET':
locations = []
for path, subdirs, files in os.walk(result_path):
for name in files:
locations.append(os.path.join(path, name))
result = {data_type: locations}
return jsonify(result)
if request.method == 'POST':
file_to_upload = request.files.get('file')
if file_to_upload:
filename = secure_filename(file_to_upload.filename)
file_to_upload.save(os.path.join(result_path, filename))
return jsonify(result="success")
else:
abort(503)
@app.route('/admin/<data_type>/<path:path>', methods=['GET', 'POST'])
def get_data_type_locations_by_path_or_get_file(data_type, path):
####### validation ########
if data_type not in app.config['DATA_TYPES']:
abort(404)
result_path = os.path.join(app.config["ROOT_DIRECTORY"],
app.config["DIRECTORIES_BY_TYPE"][
data_type],
path)
if not os.path.exists(result_path):
#throw 404
pass
#return file content or directory content
if os.path.isfile(result_path):
return send_file(result_path)
else:
for file in os.listdir(result_path):
locations.append(os.path.join(path, file))
return jsonify(data_type=locations)
abort(404)
####### end validation ########
if request.method == 'GET':
locations = []
#return file content or directory content
if os.path.isfile(result_path):
return send_file(result_path)
else:
for file in os.listdir(result_path):
locations.append(os.path.join(path, file))
result = {data_type: locations}
return jsonify(result)
if request.method == 'POST':
file_to_upload = request.files.get('file')
if file_to_upload:
filename = secure_filename(file_to_upload.filename)
file_to_upload.save(os.path.join(result_path, filename))
return jsonify(result="success")
else:
abort(403)
@app.route('/admin/<data_type>/<path:path>', methods=['PUT', 'DELETE'])
def create_dirs(data_type, path):
if data_type not in app.config['DATA_TYPES']:
abort(404)
result_path = os.path.join(app.config["ROOT_DIRECTORY"],
app.config["DIRECTORIES_BY_TYPE"][
data_type],
path)
if request.method == 'PUT':
resp = make_response()
if os.path.exists(result_path):
return resp
if data_type == app.config['MANIFESTS']:
abort(403)
try:
os.makedirs(result_path)
except Exception as e:
abort(403)
return resp
if request.method == 'DELETE':
if not os.path.exists(result_path):
abort(404)
if os.path.isfile(result_path):
try:
os.remove(result_path)
except Exception as e:
abort(404)
else:
try:
os.rmdir(result_path)
except Exception as e:
abort(403)
resp = make_response()
return resp
if __name__ == '__main__':
app.run(debug=True)
app.run(debug=True)
#by default server running on localhost:5000