Finally get rid of AppCatalogModel mockup class.

Use murano-api calls for all AppCatalog needs.

Change-Id: Ibc50d492a1ced84a52ebb0a25d7ad7cf9655af2c
This commit is contained in:
Timur Sufiev 2014-04-03 20:24:24 +04:00
parent ee20064ffb
commit 5f28195f66
14 changed files with 62 additions and 240 deletions

View File

@ -12,32 +12,10 @@
# License for the specific language governing permissions and limitations
# under the License.
import os
from django.http import HttpResponse
from muranodashboard import catalog
from muranodashboard.catalog import models
from muranodashboard.environments import api
def get_image(request, image_name):
path = os.path.basename(request.path)
if path:
cache = catalog.get_image_cache()
data = cache.get_entry(path)
if data:
response = generate_response(data)
return response
else:
#TODO(gokrokve) emulate download from API
cache.put_cache(path, path)
response = generate_response(models.get_image(path))
return response
else:
return HttpResponse()
def generate_response(data):
response = HttpResponse(content_type='image/png')
for buf in data:
response.write(buf)
response['Cache-Control'] = "max-age=604800, public"
return response
def get_image(request, app_id):
content = api.muranoclient(request).packages.get_logo(app_id)
return HttpResponse(content=content, content_type='image/png')

View File

@ -1,162 +0,0 @@
# Copyright (c) 2014 Mirantis, Inc.
#
# Licensed 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 copy
import json
import logging
import os
import random
import urllib2
import yaml
from django.utils import datastructures
from muranodashboard.image_cache import cache as image_utils
LOG = logging.getLogger(__name__)
class Application(object):
def __init__(self, dct):
self.id = dct.pop('id')
self.update(dct)
def __repr__(self):
return getattr(self, 'name', 'No Name')
def update(self, dct):
for k, v in dct.items():
setattr(self, k, v)
def get_image_name():
folder = '/tmp/test_images/'
if not os.path.exists(folder):
return ''
images = os.listdir(folder)
rnd = random.randrange(0, len(images))
return images[rnd]
def get_image(name):
folder = '/tmp/test_images/'
if not os.path.exists(folder):
return None
data = image_utils.load_from_file(folder + name)
return data
class AppCatalogObjects(object):
def __init__(self, url):
self.app_list = datastructures.SortedDict()
self.url = url
string = self.query(url)
try:
data = json.loads(string)
except:
data = {'packages': []}
for dct in data['packages']:
dct['image'] = get_image_name()
app = Application(dct)
self.app_list[app.id] = app
@staticmethod
def query(url):
request = urllib2.Request(url)
return urllib2.urlopen(request).read()
def all(self, n=20):
return self.app_list.values()[:n]
def get(self, **kwargs):
return self.app_list[kwargs.pop('app_id')]
def filter(self, **kwargs):
def filter_func(_app):
for key, value in kwargs.iteritems():
if not hasattr(_app, key) or getattr(_app, key) != value:
return False
return True
return [app for app in self.app_list.itervalues() if filter_func(app)]
def get_ui(self, **kwargs):
app_id = kwargs.pop('app_id')
url = '{0}/{1}/ui'.format(self.url, app_id)
yaml_desc = None
try:
yaml_desc = yaml.load(self.query(url))
except (OSError, yaml.ScannerError) as e:
LOG.warn("Failed to import service definition from {0},"
" reason: {1!s}".format(url, e))
return yaml_desc
def get_items(self, count):
return self.app_list.values()[:count]
def get_application(self, app_id):
return self.app_list.get(app_id)
def get_info(self, app_id):
dct = {
'overview': 'Nullam quis risus eget urna mollis orare vel eu leo.'
'Cum sociis natoque penatibus et magnis dis parturien'
'montes, nascetur ridiculus mus.' * 7,
'requirements': {
'Database': 'MySQL DB',
'Servlet Container': 'Tomcat'},
'license': '# Licensed 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.',
'version': '1.0.1.2',
'active': 'Yes',
}
LOG.debug('Current storage: {0}'.format(self.app_list))
app = self.app_list.get(app_id)
details = copy.deepcopy(app)
details.update(dct)
return details
perm_objects = AppCatalogObjects(
'http://muranorepositoryapi.apiary-mock.com/v2/catalog/packages')
class AppCatalogModel(object):
objects = perm_objects
last_objects = perm_objects.get_items(4)
class Categories(object):
_categories = ['DataBases', 'WebServers', 'Java Servlet Containers',
'Microsoft Services', 'SAP', 'Message Queues',
'Load Balancers', 'DB Tier', 'BigData', 'KeyValue Storage']
def all(self, count=10):
return self._categories[:count]
class ApplicationImageModel(object):
def get_image(self, application):
return get_image(application.image)

View File

@ -35,5 +35,5 @@ urlpatterns = patterns(
name='add'),
url(r'^details/(?P<application_id>[^/]+)$',
views.AppDetailsView.as_view(), name='application_details'),
url(r'^images/(?P<image_name>[^/]*)', image.get_image, name="images")
url(r'^images/(?P<app_id>[^/]*)', image.get_image, name="images")
)

View File

@ -13,8 +13,6 @@
# under the License.
import logging
from django.views.generic import list
from django.template import defaultfilters as filters
from django.utils import datastructures
from horizon import tabs
from django import shortcuts
@ -24,7 +22,6 @@ from django.contrib.auth.decorators import login_required
from django.utils.http import is_safe_url
from muranodashboard.catalog import tabs as catalog_tabs
from muranodashboard.catalog import models
from muranodashboard.environments import api
LOG = logging.getLogger(__name__)
@ -77,30 +74,24 @@ def switch(request, environment_id, redirect_field_name=REDIRECT_FIELD_NAME):
class IndexView(list.ListView):
apps = models.AppCatalogModel()
categories = models.Categories()
paginate_by = 6
def get_queryset(self):
return self.apps.objects.all()
return api.muranoclient(self.request).packages.list()
def get_template_names(self):
return ['catalog/index.html']
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
context['latest_list'] = self.apps.last_objects
categories = datastructures.SortedDict(
((filters.slugify(category), category) for category in
self.categories.all()))
context['latest_list'] = []
current_category = self.kwargs.get('category')
current_category_name = categories.get(current_category)
if current_category_name is None and categories:
current_category_name = categories.values()[0]
categories = api.muranoclient(self.request).packages.categories()
if not categories:
categories = ['-']
current_category = self.kwargs.get('category', categories[0])
context['categories'] = categories
context['current_category'] = current_category
context['current_category_name'] = current_category_name
context.update(get_environments_context(self.request))
@ -111,13 +102,12 @@ class AppDetailsView(tabs.TabView):
tab_group_class = catalog_tabs.ApplicationTabs
template_name = 'catalog/app_details.html'
app_model = models.AppCatalogModel.objects
app = None
def get_data(self, **kwargs):
LOG.debug(('AppDetailsView get_data: {0}'.format(kwargs)))
app_id = kwargs.get('application_id')
self.app = self.app_model.get_info(app_id)
self.app = api.muranoclient(self.request).packages.get(app_id)
return self.app
def get_context_data(self, **kwargs):

View File

@ -25,7 +25,6 @@ import yaql
import yaml
from yaml.scanner import ScannerError
from django.utils.translation import ugettext_lazy as _
from muranodashboard.catalog import models
from muranodashboard.environments.consts import CACHE_REFRESH_SECONDS_INTERVAL
from muranodashboard.dynamic_ui import version
@ -190,13 +189,15 @@ def iterate_over_services(request):
def import_app(request, app_id):
from muranodashboard.environments import api
if not request.session.get('apps'):
request.session['apps'] = {}
services = request.session['apps']
app = services.get(app_id)
if not app:
ui_desc = models.AppCatalogModel().objects.get_ui(app_id=app_id)
ui_desc = api.muranoclient(request).packages.get_ui(app_id)
service = dict((decamelize(k), v) for (k, v) in ui_desc.iteritems())
services[app_id] = Service(**service)
app = services[app_id]
@ -218,7 +219,8 @@ def service_type_from_id(service_id):
def get_service_name(request, app_id):
app = models.AppCatalogModel().objects.get(app_id=app_id)
from muranodashboard.environments import api
app = api.muranoclient(request).packages.get(app_id)
return app.name

View File

@ -25,7 +25,6 @@ from consts import STATUS_ID_READY, STATUS_ID_NEW
from .network import get_network_params
from muranodashboard.environments import format
from muranodashboard.catalog import models
log = logging.getLogger(__name__)
@ -260,7 +259,7 @@ def services_list(request, environment_id):
def app_id_by_fqn(request, fqn):
apps = models.AppCatalogModel().objects.filter(fqn=fqn)
apps = muranoclient(request).packages.filter(fqn=fqn)
return apps[0].id if apps else None

View File

@ -40,7 +40,6 @@ from muranoclient.common.exceptions import HTTPUnauthorized, \
from django.utils.decorators import classonlymethod
from muranodashboard.dynamic_ui.services import get_service_name
from muranodashboard.dynamic_ui.services import get_service_field_descriptions
from muranodashboard.catalog import models
from muranodashboard.dynamic_ui import helpers
from muranodashboard import utils
@ -154,10 +153,10 @@ class Wizard(hz_views.ModalFormMixin, LazyWizard):
def get_context_data(self, form, **kwargs):
context = super(Wizard, self).get_context_data(form=form, **kwargs)
app_id = self.kwargs.get('app_id')
app = models.AppCatalogModel().objects.get(app_id=app_id)
app = api.muranoclient(self.request).packages.get(app_id)
context['field_descriptions'] = get_service_field_descriptions(
self.request, app_id, self.steps.index)
context.update({'type': app.fqn,
context.update({'type': app.fully_qualified_name,
'service_name': app.name,
'app_id': app_id,
'environment_id': self.kwargs.get('environment_id'),

View File

@ -4,7 +4,11 @@
<div class="status row-fluid detail app_overview">
<p>
{{ application.license }}
{% if application.license %}
{{ application.license }}
{% else %}
{% trans 'No license' %}
{% endif %}
</p>
</div>

View File

@ -4,7 +4,11 @@
<div class="status row-fluid detail app_requirements">
<p>
{{ application.requirements }}
{% if application.requirements %}
{{ application.requirements }}
{% else %}
{% trans 'No requirements' %}
{% endif %}
</p>
</div>

View File

@ -4,7 +4,7 @@
<div class="status row-fluid detail app_overview">
<p>
{{ application.overview }}
{{ application.description }}
</p>
</div>

View File

@ -13,18 +13,22 @@
{% with class='btn btn-small btn-add ajax-modal pull-right' %}
{% include 'catalog/add_app.html' %}
{% endwith %}
<h3>{{ app.title }}</h3>
<h3>{{ app.name }}</h3>
{{ tab_group.render }}
<div class="well app-meta">
<div class="app-icon pull-left">
<img src="{% url 'horizon:murano:catalog:images' app.image %}" width="70px" height="70px"/>
<img src="{% url 'horizon:murano:catalog:images' app.id %}" width="70px" height="70px"/>
</div>
<div class="">
<ul>
<li><strong>Fully Qualified Service Name:</strong> {{ app.fqdn }}</li>
<li><strong>Fully Qualified Service Name:</strong> {{ app.fully_qualified_name }}</li>
<li><strong>Author:</strong> {{ app.author }}</li>
<li><strong>Active:</strong> {{ app.active }}</li>
<li><strong>Version:</strong> {{ app.version }}</li>
<li><strong>Active:</strong> {{ app.enabled }}</li>
<li><strong>Public:</strong> {{ app.is_public }}</li>
<li><strong>Type:</strong> {{ app.type }}</li>
<li><strong>Tags:</strong> {% for tag in app.tags %} {{ tag }} {% endfor %}</li>
<li><strong>Categories:</strong> {% for category in app.categories %} {{ category }} {% endfor %}</li>
</ul>
</div>

View File

@ -4,18 +4,18 @@
<div class="well app">
<div class="app-description">
<div class="app-icon pull-left">
<img src="{% url 'horizon:murano:catalog:images' app.image %}"/>
<img src="{% url 'horizon:murano:catalog:images' app.id %}"/>
</div>
<div class="app-summary">
<h4>{{ app.title }}</h4>
<p>{{ app.description|truncatechars:110 }}</p>
<h4>{{ app.name }}</h4>
<p>{{ app.description|truncatechars:95 }}</p>
</div>
</div>
<div class="app-actions">
{% with class='btn btn-small btn-add ajax-modal' %}
{% include 'catalog/add_app.html' %}
{% endwith %}
<a href="{% url 'horizon:murano:catalog:application_details' app.id %}" class="btn-link pull-right">More info &raquo;</a>
</div>
</div>
<div class="app-actions">
{% with class='btn btn-small btn-add ajax-modal' %}
{% include 'catalog/add_app.html' %}
{% endwith %}
<a href="{% url 'horizon:murano:catalog:application_details' app.id %}" class="btn-link pull-right">More info &raquo;</a>
</div>
</div>
</div>

View File

@ -4,19 +4,23 @@
<div style="clear:both;"></div>
<div class="columns">
{% if categories|slice:"1:" %}
<div class="colleft">
<ul>
{% for slug, category in categories.items|firsthalf %}
<li><a href="#{{ slug }}">{{ category }}</a></li>
{% for category in categories|firsthalf %}
<li><a href="{% url 'horizon:murano:catalog:index' category page_obj.number %}">{{ category }}</a></li>
{% endfor %}
</ul>
</div>
<div class="colright">
<ul>
{% for slug, category in categories.items|lasthalf %}
<li><a href="#{{ slug }}">{{ category }}</a></li>
{% for category in categories|lasthalf %}
<li><a href="{% url 'horizon:murano:catalog:index' category page_obj.number %}">{{ category }}</a></li>
{% endfor %}
</ul>
</div>
{% else %}
<a href="{% url 'horizon:murano:catalog:index' categories.0 page_obj.number %}">{{ categories.0 }}</a>
{% endif %}
</div>

View File

@ -48,12 +48,12 @@
</div>
<h3>App Category: <div class="header dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
{{ current_category_name }}<b class="caret"></b></a>
{{ current_category }}<b class="caret"></b></a>
<ul class="dropdown-menu">
{% for cat_slug, cat_name in categories.items %}
{% for category in categories %}
<li><a tabindex="-1" href="
{% url 'horizon:murano:catalog:index' cat_slug page_obj.number %}">
{{ cat_name }}</a></li>
{% url 'horizon:murano:catalog:index' category page_obj.number %}">
{{ category }}</a></li>
{% endfor %}
</ul>
</div>