From 1e0c123d5b96021b82157b5e7bd27d60a0fdd5df Mon Sep 17 00:00:00 2001 From: Jordan OMara Date: Tue, 15 Jul 2014 12:16:11 -0400 Subject: [PATCH] moving code to overrides --- tuskar_sat_ui/__init__.py | 2 - tuskar_sat_ui/api/__init__.py | 24 - tuskar_sat_ui/api/__init__.pyc | Bin 370 -> 0 bytes tuskar_sat_ui/api/node.py | 557 ------------------ tuskar_sat_ui/api/node.pyc | Bin 18185 -> 0 bytes tuskar_sat_ui/infrastructure/__init__.py | 0 tuskar_sat_ui/infrastructure/__init__.pyc | Bin 150 -> 0 bytes .../infrastructure/nodes/__init__.py | 0 .../infrastructure/nodes/__init__.pyc | Bin 156 -> 0 bytes tuskar_sat_ui/infrastructure/nodes/views.py | 177 ------ tuskar_sat_ui/infrastructure/nodes/views.pyc | Bin 6466 -> 0 bytes .../test/test_data/node_data.py | 219 ------- .../overrides/infrastructure/__init__.py | 1 + .../overrides/infrastructure/node_views.py | 3 + .../infrastructure/templates}/_scripts.html | 0 .../templates/nodes/details.html | 0 .../js/angular/horizon.base64.js | 0 .../js/angular/horizon.node_errata.js | 0 tuskar_ui/forms.pyc | Bin 2934 -> 0 bytes 19 files changed, 4 insertions(+), 979 deletions(-) delete mode 100644 tuskar_sat_ui/api/__init__.py delete mode 100644 tuskar_sat_ui/api/__init__.pyc delete mode 100644 tuskar_sat_ui/api/node.py delete mode 100644 tuskar_sat_ui/api/node.pyc delete mode 100644 tuskar_sat_ui/infrastructure/__init__.py delete mode 100644 tuskar_sat_ui/infrastructure/__init__.pyc delete mode 100644 tuskar_sat_ui/infrastructure/nodes/__init__.py delete mode 100644 tuskar_sat_ui/infrastructure/nodes/__init__.pyc delete mode 100644 tuskar_sat_ui/infrastructure/nodes/views.py delete mode 100644 tuskar_sat_ui/infrastructure/nodes/views.pyc delete mode 100644 tuskar_sat_ui/infrastructure/test/test_data/node_data.py create mode 100644 tuskar_sat_ui/overrides/infrastructure/__init__.py create mode 100644 tuskar_sat_ui/overrides/infrastructure/node_views.py rename tuskar_sat_ui/{infrastructure/templates/infrastructure => overrides/infrastructure/templates}/_scripts.html (100%) rename tuskar_sat_ui/{infrastructure/nodes => overrides/infrastructure}/templates/nodes/details.html (100%) rename tuskar_sat_ui/{infrastructure => overrides}/static/infrastructure/js/angular/horizon.base64.js (100%) rename tuskar_sat_ui/{infrastructure => overrides}/static/infrastructure/js/angular/horizon.node_errata.js (100%) delete mode 100644 tuskar_ui/forms.pyc diff --git a/tuskar_sat_ui/__init__.py b/tuskar_sat_ui/__init__.py index de236eb..e69de29 100644 --- a/tuskar_sat_ui/__init__.py +++ b/tuskar_sat_ui/__init__.py @@ -1,2 +0,0 @@ -from tuskar_sat_ui.infrastructure import nodes -from tuskar_sat_ui.api import node diff --git a/tuskar_sat_ui/api/__init__.py b/tuskar_sat_ui/api/__init__.py deleted file mode 100644 index a63c736..0000000 --- a/tuskar_sat_ui/api/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -# 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. - -from tuskar_ui.api import flavor -from tuskar_ui.api import heat -from tuskar_ui.api import node -from tuskar_ui.api import tuskar - - -__all__ = [ - "flavor", - "heat", - "node", - "tuskar", -] diff --git a/tuskar_sat_ui/api/__init__.pyc b/tuskar_sat_ui/api/__init__.pyc deleted file mode 100644 index 1ba8e4acb014363c7e0809a136277a2b1d0d5d96..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 370 zcmZvWK~BRk5JktaX-lOdxJ5S98F0$$UuUL)H7qH2LDEg<_~&at03f8pRvn&}v=o4siqK26`iMNJN9sw@)nQs=C+ z$x=)_`mH(n|Ga4l7qbb0xyDGd3=cqkh@I0Pu`|8V)}8f~ct85fglvs$&FqgpF>g;_ YX@!T6U9@9xPx%+a4dhmoR#N2t1AlKs00000 diff --git a/tuskar_sat_ui/api/node.py b/tuskar_sat_ui/api/node.py deleted file mode 100644 index 3c74fe3..0000000 --- a/tuskar_sat_ui/api/node.py +++ /dev/null @@ -1,557 +0,0 @@ -# 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 logging - -from django.utils.translation import ugettext_lazy as _ -from horizon.utils import memoized -#from ironicclient.v1 import client as ironicclient -from novaclient.v1_1.contrib import baremetal -from openstack_dashboard.api import base -from openstack_dashboard.api import glance -from openstack_dashboard.api import nova -from openstack_dashboard.test.test_data import utils as test_utils - -from tuskar_ui.cached_property import cached_property # noqa -from tuskar_ui.handle_errors import handle_errors # noqa -from tuskar_ui.test.test_data import heat_data -from tuskar_ui.test.test_data import node_data -from tuskar_ui import utils - - -TEST_DATA = test_utils.TestDataContainer() -node_data.data(TEST_DATA) -heat_data.data(TEST_DATA) - -LOG = logging.getLogger(__name__) - - -def baremetalclient(request): - nc = nova.novaclient(request) - return baremetal.BareMetalNodeManager(nc) - - -# FIXME(lsmola) This should be done in Horizon, they don't have caching -@memoized.memoized -def image_get(request, image_id): - """Returns an Image object with metadata - - Returns an Image object populated with metadata for image - with supplied identifier. - - :param image_id: list of objects to be put into a dict - :type object_list: list - - :return: object - :rtype: glanceclient.v1.images.Image - """ - image = glance.image_get(request, image_id) - return image - - -class IronicNode(base.APIResourceWrapper): - _attrs = ('id', 'uuid', 'instance_uuid', 'driver', 'driver_info', - 'properties', 'power_state') - - @classmethod - def create(cls, request, ipmi_address, cpu, ram, local_disk, - mac_addresses, ipmi_username=None, ipmi_password=None): - """Create a Node in Ironic - - :param request: request object - :type request: django.http.HttpRequest - - :param ipmi_address: IPMI address - :type ipmi_address: str - - :param cpu: number of cores - :type cpu: int - - :param ram: RAM in GB - :type ram: int - - :param local_disk: local disk in TB - :type local_disk: int - - :param mac_addresses: list of mac addresses - :type mac_addresses: list of str - - :param ipmi_username: IPMI username - :type ipmi_username: str - - :param ipmi_password: IPMI password - :type ipmi_password: str - - :return: the created Node object - :rtype: tuskar_ui.api.node.IronicNode - """ - #node = ironicclient(request).node.create( - # driver='pxe_ipmitool', - # driver_info={'ipmi_address': ipmi_address, - # 'ipmi_username': ipmi_username, - # 'password': ipmi_password}, - # properties={'cpu': cpu, - # 'ram': ram, - # 'local_disk': local_disk}) - #for mac_address in mac_addresses: - # ironicclient(request).port.create( - # node_uuid=node.uuid, - # address=mac_address - # ) - node = TEST_DATA.ironicclient_nodes.first() - return cls(node) - - @classmethod - def get(cls, request, uuid): - """Return the IronicNode that matches the ID - - :param request: request object - :type request: django.http.HttpRequest - - :param uuid: ID of IronicNode to be retrieved - :type uuid: str - - :return: matching IronicNode, or None if no IronicNode matches the ID - :rtype: tuskar_ui.api.node.IronicNode - """ - #node = ironicclient(request).nodes.get(uuid) - #return cls(node) - for node in IronicNode.list(request): - if node.uuid == uuid: - return node - - @classmethod - def get_by_instance_uuid(cls, request, instance_uuid): - """Return the IronicNode associated with the instance ID - - :param request: request object - :type request: django.http.HttpRequest - - :param instance_uuid: ID of Instance that is deployed on the IronicNode - to be retrieved - :type instance_uuid: str - - :return: matching IronicNode - :rtype: tuskar_ui.api.node.IronicNode - - :raises: ironicclient.exc.HTTPNotFound if there is no IronicNode with - the matching instance UUID - """ - #node = ironicclient(request).nodes.get_by_instance_uuid(instance_uuid) - #return cls(node) - for node in IronicNode.list(request): - if node.instance_uuid == instance_uuid: - return node - - @classmethod - @handle_errors(_("Unable to retrieve nodes"), []) - def list(cls, request, associated=None): - """Return a list of IronicNodes - - :param request: request object - :type request: django.http.HttpRequest - - :param associated: should we also retrieve all IronicNodes, only those - associated with an Instance, or only those not - associated with an Instance? - :type associated: bool - - :return: list of IronicNodes, or an empty list if there are none - :rtype: list of tuskar_ui.api.node.IronicNode - """ - #nodes = ironicclient(request).nodes.list( - # associated=associated) - nodes = TEST_DATA.ironicclient_nodes.list() - if associated is not None: - if associated: - nodes = [node for node in nodes - if node.instance_uuid is not None] - else: - nodes = [node for node in nodes - if node.instance_uuid is None] - - return [cls(node) for node in nodes] - - @classmethod - def delete(cls, request, uuid): - """Remove the IronicNode matching the ID if it - exists; otherwise, does nothing. - - :param request: request object - :type request: django.http.HttpRequest - - :param uuid: ID of IronicNode to be removed - :type uuid: str - """ - #ironicclient(request).nodes.delete(uuid) - return - - @cached_property - def addresses(self): - """Return a list of port addresses associated with this IronicNode - - :return: list of port addresses associated with this IronicNode, or - an empty list if no addresses are associated with - this IronicNode - :rtype: list of str - """ - ports = self.list_ports() - return [port.address for port in ports] - - -class BareMetalNode(base.APIResourceWrapper): - _attrs = ('id', 'uuid', 'instance_uuid', 'memory_mb', 'cpus', 'local_gb', - 'task_state', 'pm_user', 'pm_address', 'interfaces') - - @classmethod - def create(cls, request, ipmi_address, cpu, ram, local_disk, - mac_addresses, ipmi_username=None, ipmi_password=None): - """Create a Nova BareMetalNode - - :param request: request object - :type request: django.http.HttpRequest - - :param ipmi_address: IPMI address - :type ipmi_address: str - - :param cpu: number of cores - :type cpu: int - - :param ram: RAM in GB - :type ram: int - - :param local_disk: local disk in TB - :type local_disk: int - - :param mac_addresses: list of mac addresses - :type mac_addresses: list of str - - :param ipmi_username: IPMI username - :type ipmi_username: str - - :param ipmi_password: IPMI password - :type ipmi_password: str - - :return: the created BareMetalNode object - :rtype: tuskar_ui.api.node.BareMetalNode - """ - #node = baremetalclient(request).create( - # 'undercloud', - # cpu, - # ram, - # local_disk, - # mac_addresses, - # pm_address=ipmi_address, - # pm_user=ipmi_username, - # pm_password=ipmi_password) - node = TEST_DATA.baremetalclient_nodes.first() - return cls(node) - - @classmethod - def get(cls, request, uuid): - """Return the BareMetalNode that matches the ID - - :param request: request object - :type request: django.http.HttpRequest - - :param uuid: ID of BareMetalNode to be retrieved - :type uuid: str - - :return: matching BareMetalNode, or None if no BareMetalNode matches - the ID - :rtype: tuskar_ui.api.node.BareMetalNode - """ - #node = baremetalclient(request).get(uuid) - #return cls(node) - for node in BareMetalNode.list(request): - if node.uuid == uuid: - return node - - @classmethod - def get_by_instance_uuid(cls, request, instance_uuid): - """Return the BareMetalNode associated with the instance ID - - :param request: request object - :type request: django.http.HttpRequest - - :param instance_uuid: ID of Instance that is deployed on the - BareMetalNode to be retrieved - :type instance_uuid: str - - :return: matching BareMetalNode - :rtype: tuskar_ui.api.node.BareMetalNode - - :raises: ironicclient.exc.HTTPNotFound if there is no BareMetalNode - with the matching instance UUID - """ - #nodes = baremetalclient(request).list() - #node = next((n for n in nodes if instance_uuid == n.instance_uuid), - # None) - #return cls(node) - for node in BareMetalNode.list(request): - if node.instance_uuid == instance_uuid: - return node - - @classmethod - def list(cls, request, associated=None): - """Return a list of BareMetalNodes - - :param request: request object - :type request: django.http.HttpRequest - - :param associated: should we also retrieve all BareMetalNodes, only - those associated with an Instance, or only those not - associated with an Instance? - :type associated: bool - - :return: list of BareMetalNodes, or an empty list if there are none - :rtype: list of tuskar_ui.api.node.BareMetalNode - """ - #nodes = baremetalclient(request).list() - nodes = TEST_DATA.baremetalclient_nodes.list() - if associated is not None: - if associated: - nodes = [node for node in nodes - if node.instance_uuid is not None] - else: - nodes = [node for node in nodes - if node.instance_uuid is None] - return [cls(node) for node in nodes] - - @classmethod - def delete(cls, request, uuid): - """Remove the BareMetalNode if it exists; otherwise, do nothing. - - :param request: request object - :type request: django.http.HttpRequest - - :param uuid: ID of BareMetalNode to be removed - :type uuid: str - """ - #baremetalclient(request).delete(uuid) - return - - @cached_property - def power_state(self): - """Return a power state of this BareMetalNode - - :return: power state of this node - :rtype: str - """ - task_state_dict = { - 'initializing': 'initializing', - 'active': 'on', - 'reboot': 'rebooting', - 'building': 'building', - 'deploying': 'deploying', - 'prepared': 'prepared', - 'deleting': 'deleting', - 'deploy failed': 'deploy failed', - 'deploy complete': 'deploy complete', - 'deleted': 'deleted', - 'error': 'error', - } - return task_state_dict.get(self.task_state, 'off') - - @cached_property - def properties(self): - """Return properties of this BareMetalNode - - :return: return memory, cpus and local_disk properties - of this BareMetalNode, ram and local_disk properties - are in bytes - :rtype: dict of str - """ - return { - 'ram': self.memory_mb * 1024.0 * 1024.0, - 'cpu': self.cpus, - 'local_disk': self.local_gb * 1024.0 * 1024.0 * 1024.0 - } - - @cached_property - def driver_info(self): - """Return driver_info for this BareMetalNode - - :return: return pm_address property of this BareMetalNode - :rtype: dict of str - """ - try: - ip_address = (self.instance._apiresource.addresses['ctlplane'][0] - ['addr']) - except Exception: - LOG.error("Couldn't obtain IP address") - ip_address = None - - return { - 'ipmi_username': self.pm_user, - 'ipmi_address': self.pm_address, - 'ip_address': ip_address - } - - @cached_property - def addresses(self): - """Return a list of port addresses associated with this BareMetalNode - - :return: list of port addresses associated with this BareMetalNode, or - an empty list if no addresses are associated with - this BareMetalNode - :rtype: list of str - """ - return [interface["address"] for interface in - self.interfaces] - - -class NodeClient(object): - def __init__(self, request): - ironic_enabled = base.is_service_enabled(request, 'baremetal') - - if ironic_enabled: - self.node_class = IronicNode - else: - self.node_class = BareMetalNode - - -class Node(base.APIResourceWrapper): - _attrs = ('id', 'uuid', 'instance_uuid', 'driver', 'driver_info', - 'properties', 'power_state', 'addresses') - - def __init__(self, apiresource, request=None, **kwargs): - """Initialize a Node - - :param apiresource: apiresource we want to wrap - :type apiresource: novaclient.v1_1.contrib.baremetal.BareMetalNode - - :param request: request - :type request: django.core.handlers.wsgi.WSGIRequest - - :param instance: instance relation we want to cache - :type instance: openstack_dashboard.api.nova.Server - - :return: Node object - :rtype: tusar_ui.api.node.Node - """ - super(Node, self).__init__(apiresource) - self._request = request - if 'instance' in kwargs: - self._instance = kwargs['instance'] - - @classmethod - def create(cls, request, ipmi_address, cpu, ram, local_disk, - mac_addresses, ipmi_username=None, ipmi_password=None): - return cls(NodeClient(request).node_class.create( - request, ipmi_address, cpu, ram, local_disk, - mac_addresses, ipmi_username=ipmi_username, - ipmi_password=ipmi_password)) - - @classmethod - @handle_errors(_("Unable to retrieve node")) - def get(cls, request, uuid): - node = NodeClient(request).node_class.get(request, uuid) - if node.instance_uuid is not None: - #server = nova.server_get(request, node.instance_uuid) - server = TEST_DATA.novaclient_servers.first() - return cls(node, instance=server, request=request) - - return cls(node) - - @classmethod - @handle_errors(_("Unable to retrieve node")) - def get_by_instance_uuid(cls, request, instance_uuid): - node = NodeClient(request).node_class.get_by_instance_uuid( - request, instance_uuid) - #server = nova.server_get(request, instance_uuid) - server = TEST_DATA.novaclient_servers.first() - return cls(node, instance=server, request=request) - - @classmethod - @handle_errors(_("Unable to retrieve nodes"), []) - def list(cls, request, associated=None): - nodes = NodeClient(request).node_class.list( - request, associated=associated) - - if associated is None or associated: - #servers = nova.server_list(request)[0] - servers = TEST_DATA.novaclient_servers.list() - servers_dict = utils.list_to_dict(servers) - nodes_with_instance = [] - for n in nodes: - server = servers_dict.get(n.instance_uuid, None) - nodes_with_instance.append(cls(n, instance=server, - request=request)) - return nodes_with_instance - else: - return [cls(node, request=request) for node in nodes] - - @classmethod - def delete(cls, request, uuid): - NodeClient(request).node_class.delete(request, uuid) - - @cached_property - def instance(self): - """Return the Nova Instance associated with this Node - - :return: Nova Instance associated with this Node; or - None if there is no Instance associated with this - Node, or no matching Instance is found - :rtype: Instance - """ - if hasattr(self, '_instance'): - return self._instance - - if self.instance_uuid: - #server = nova.server_get(self._request, self.instance_uuid) - server = TEST_DATA.novaclient_servers.first() - return server - - return None - - @cached_property - def image_name(self): - """Return image name of associated instance - - Returns image name of instance associated with node - - :return: Image name of instance - :rtype: string - """ - if self.instance is None: - return - return image_get(self._request, self.instance.image['id']).name - - @cached_property - def instance_status(self): - return getattr(getattr(self, 'instance', None), - 'status', None) - - -def filter_nodes(nodes, healthy=None): - """Filters the list of Nodes and returns the filtered list. - - :param nodes: list of tuskar_ui.api.node.Node objects to filter - :type nodes: list - :param healthy: retrieve all Nodes (healthy=None), - only the healthly ones (healthy=True), - or only those in an error state (healthy=False) - :type healthy: None or bool - :return: list of filtered tuskar_ui.api.node.Node objects - :rtype: list - """ - error_states = ('deploy failed', 'error',) - - if healthy is not None: - if healthy: - nodes = [node for node in nodes - if node.power_state not in error_states] - else: - nodes = [node for node in nodes - if node.power_state in error_states] - return nodes diff --git a/tuskar_sat_ui/api/node.pyc b/tuskar_sat_ui/api/node.pyc deleted file mode 100644 index 53e2a23e7a9c3963ed078a7e6b3b3d3b3dd2fc1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18185 zcmeHP%WoV-gNuK;(J}c?9p7)_lm5stCcvL#y2fm3x@NkL>DA0; z-8d|(o9=|^O`6R~%}?w%}+^w&TP(Uep>SLW^-QiGp4&> zdW&ZBl;&qmw_$oqW^+mNbEbRR^p?%$vgYSa_l)VSn9UW686H( z@9M1yxs`^Rn?i1<>-Rf(o~8Zxj<2PY$PKfon`*X!Y{&2HhCzFf#Dg%&@)xr|yM90D zhV3v(;v}!nx9^62)(-qEZ;`k9aS+O_4hK`qKUeXcK8s6+g>cM$ne7LT$!cb=Ztgpr z{0-?xYmL41*tu*D7xuT)jlzEBv9W9gmn#_b`y6x&FMHqb`#WK>CZ*FTO~Tv5FwM|3 zp6;ySYUGl>hSbH~xEEgBi+g_JUkt)K7qek{%THb%MtQ1@ls||ravaUUe#U9BldK(i z3Aa-A(l`yL!`G0z_>p0rL&6S|L#vqwHFLj~4={ZW6XS*1FzKhR-*>O~(0w=F+6z0G zdpF82Dv_380g@Vo>#mZd&Smq?>rLrx+LVcqin5j-XE-BCNqHL_vBo*}NRJu0LGMRFMq-i7 zF&EogLPHnu(bZjCc7z14CviXOkk&dVlONLA6@1d)!zF|$0aKqcn>7>GDM9!*Z9c1s zOqrCMGa>@O^;43aEwag| zTnn-!DPAaj6$z#EJq*>D2eaht`?Kt^a&!7GsC+enm%J>J`jRw7_?FT^;rs=wS{e$$u!|rO<^U$F6<6Y92u0*9{~FRN}3gNtT%1xV>aYKi#~o;L+wZ+9DDm?Q=@(BV-i`Vz8|GjF;!XE4DWTC-@9?+gI1iq z9S{4kNVhr61WS^R5j!nc+nOCMSI;s{F(~)L4Eu0HijbVwK7PhLm@xMz%-%#%V~yG0u9@3wl(x6;9#wV5BpXH54OZ=AFnO!X z(ke0&H0RjZ@4~1P>HMFiboQ+YQ3}NLXC{zK-iE^8jfY)0LohVEX=R4}Znq*sQ;64o zcOOI-r|KaUWHa_%Hm&{@J+*v&MM9UYU=7tH8f&4*KBT4ZTB6N$MOk;<-HPLGWhOx~ za2ZRJtuo)zA#^b84YGY*5X)C^mC?a|IabTah3)rvrcP^(1nND*3mti3Ezuv;Rmx*h z!|D&QTFL>51tjEt5_~7G|6}wcrQ2hc8_t3=43oBdX{x!;{s9fFf9&}~;h8t66-GzL+;07`55KzD_w0Q1RbK$>Wm*x?c2uJo1 zJEWk@mMV5mlxLSsO#$3G4r(G!X4nn0@GsC%N~vKMI$RCDjGwFcq%P(duOTv>W#3{(3FwS+ zAuPDu*#w=C8OQo}u!->w7i}M4Tq^ORP~k7S7G&!-hmvMQDe{-Ar$R1B!|t~5qSoOp zrjBdl5gf1s{ae0=Et}Z|XN}zu5{Lr1N#acp02AI*tTqNoq#RKRNl0-8l4z}+Lb-rJ z?KWM`c3Y%QyWNX}Appy^cq?r`%iwvj?M@f-4}fhq4!mDN-g}vs^Sr#m%M30V>9no3 zLz6c-0Pk0DDJMx%PlPCXG`zo!Pf8nP3P|--tzKJhHqJDjsyoZh@-vN7;=PTaoE_Aa zA5O>>eA1udk|R%N3gl_U1o)d9MVp z9|z`ytU}_zoE9W|x+qCBny}$Ot$?F?5HO}sQwMYse(}5@!gS$ugD9abRo+)oA~03ODtI3EJeQZR@$v#MU+3jTUcSK#wRtHapG-JX9RD*usy)u1FiLQ* zv>#~SjZ6_N!7m50G}fyV0GCEu6lbA=FO3uy5R;{s!oE;DxpcCvF>;9aFw&xJDR;}) zNhzd~FBEbTjZQ0HUGSw7$D7VUYgF*2ks*(pcrtedIPj&1oa}#-<yWviA(tPVMp>Mpnp z-})S_VD%X|vbCR8<2(vClB>h1kL!M1 zKainCJ+3jy*31$Zn{%v8ApMC<2$9%-K3`ERp|0I3gu^OUa~14;v;U%*0GZyJGs#=V zaU5Vy4EdB@EeB!(b^4C^D5nbu5Qq~}0b~dy3Zw%i%ElU*DgAw1astp0Dv6ttkh{l{ z2ssIq09LW$`$tewvHDh09JWHj&7G_}K&WRJp^Lh&PmD}h=_JXVICf)j=v1VzFj0w>Ut}TwH@q zh9xdN*Vi$t++~<6wl|+gv-v8Q2I=E$4m?UB6gzI8yR9#FuVJ*?2S~2ybyX;MuVF5g z+b=UkMJ;?U^k5O$<1R8W_aAeSxrUSif=WGlFCitjT9jFyrnnVhQlQMTwNPrNlpueO zGV88`MVTdQ$CS3jJn()M^*w47@7H+wCNGEWC~ywMxY2C{>MW1a%_9Y$+^z!s&40v4 zINt6mywX@{tk#{zYGbi+uF+_$2%ooLgj|)F>JFZeA55}tE1X6GQk4O%hS)x0T7l%V z_+X^7D0oqw%0@QQIeC$hs9>}!XHH4rg!Q8r~Oqrokb7>oqgLfiCs)iCN z5y)PNbeVQjTQ+Yzj#QNo->(sL+y>G>lj6~1lAegZHpF|Bwc9@>3C`dZ##ydSISVy? zeMtd7L{a%dNj;fV`v?vFgl{85O;J}F!_~6u#9my%C;cZ}@^zB!A8zCz#u!^K6Fk+x zEdCH?tU<`w`#~HswtS%0B+U3zEO4Kc)Q&+!Y&akZM$i7O0ss-2xl!&YB!CRj@UGktwH4%;T+*1%7&2;vftpeP~Bws z(=!G*T>vtazB!1Q$%znUum`40@&*$W|16kb@Cyuw4O!guudoW&3o9J{u7rzLjC|b; zs;I+tw~}EP%3Z&oG1lj9;t#AjSHyXgY82tb_J{+b;oGk_J5Z!awAI{#u_oYrb5uf? zjUB!tRhAzfFwLOlrk?0X(&pWCCu-i@c<1_&;nR883qrYyXtgB7$ph&7>M%PzJ2L+2 z;t8As7=(Pfa|?$<(%r4tPl7zO_Kx4&0NaPvU~4s$)*l(8>n9^2x?~mG1#bhipx}Zy zEI0)bCf>)m>5*TR!}Co%QCl{EOM}Hky3M0zWnER;(BZmu*H3oRlIfp}-`SBrv(g1& zk+X+RCH0!c$>Vu%zJ#<=i2Kz?zs8ZzqaG9FC#*3!AThba72up4UyyA%bffGi9;uZ zT1Z2T!Q5CVM9h8PfCBcW%-*yFnut15*2mOwx+o%Q8<=9;t;`xJNS1t!a@Q+o?L4zY zr&Q(3ei{S6OI8+D7AC1~rcJWyXo!u#SK_-<>EQqqsvO54W|#hsQ_2VdQ-8*3)Edq? z4Ta+C?Zmx_%tIy)Har3e;UayCkes7tN~owM9H#Tb)+_V#3bULQufvOMD2~m6%-%~Z z#UfR-=aVrKU-%CtL4lkw`bP&{a;`}HLQ#K%#KDOnPf>?DBr51TP}Gb;Cy`EmLemCQ z1udhqh4loDX~^V*Nvg;PQ|8_klGU}3*UbZzq4o^9bPwp1XwV19;;}h$xaD4WuS%4l zM(6f#nVYDxf##&4r^}NzMLmZe%%7MIG`S(-tEE6`Nx_t4l@%hnmBg#d#6=W0PhyC& zSkM{`j^S!40yTgj55{+gEhsB6krH$&P3386Dm#N#Xvw8*?xt9ID*-osp@S0xb^n#b zKoi^48(@WHkV8Wv1kXBWom0+486#Ln9a(=;>B05q;@9NdX>mZ24^(E7z@NdpUZu% z7R(SE<9cAPLhudIuU5gXmsM;{a6mV@F|_3JD3t;V6Mn90zxDgCL$?Otb{m z4bx?ggp_1z%Z`{gj{&Q2@)h_@sZJ^ws6r-sZX9PvrMMEPDS(U(4{fcT#?#{nimc}k zS@2C>Xd+5DruXYiiNz&mg=j7cM+H=b7JAGMa4ChZq@K)}ppWpUWI-1R#Znel5TiL& zcb=QWXGY>QPd6qIv$@!zOy)#dwoH(LUgn{1IN1|of%chBuIBiooY_ztRji9!(3cvN;qUyV>3bz%Eo^Mgm26{W{A|g^x#}(imCAV%jsLj)2DAK_F*cGNWsA^IziY)Y#c00DUD=A zE!9oJSp-egvE}BusyAH(vD2i!2Hd76VT4JeI(j_;`!od(#kEOW|sK{vAnDyWi9U(@O{wQm6le4zOFwJ`Qqg}Q!3syf z5uVs~)Swi3rsG9dM;V2Uz^EcTX z6@|w|5 From: %(first_date)s, to: ' - '%(last_date)s' - ) % (dict(average=average, unit=unit, first_date=first_date, - last_date=last_date) - ) - - ret = { - 'series': series, - 'settings': { - 'renderer': 'StaticAxes', - 'yMin': 0, - 'yMax': 100, - 'higlight_last_point': True, - 'auto_size': False, - 'auto_resize': False, - 'axes_x': False, - 'axes_y': False, - 'bar_chart_settings': { - 'orientation': 'vertical', - 'used_label_placement': 'left', - 'width': 30, - 'color_scale_domain': [0, 80, 80, 100], - 'color_scale_range': [ - '#0000FF', - '#0000FF', - '#FF0000', - '#FF0000' - ], - 'average_color_scale_domain': [0, 100], - 'average_color_scale_range': ['#0000FF', '#0000FF'] - } - }, - 'stats': { - 'average': average, - 'used': used, - 'tooltip_average': tooltip_average, - } - } - - return http.HttpResponse(json.dumps(ret), mimetype='application/json') diff --git a/tuskar_sat_ui/infrastructure/nodes/views.pyc b/tuskar_sat_ui/infrastructure/nodes/views.pyc deleted file mode 100644 index ac974aa4da1411a98c90a30a51939838e9886ad2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6466 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