Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / register.py @ ff5edb80

History | View | Annotate | Download (7 kB)

1 ff5edb80 Giorgos Korfiatis
# Copyright 2013-2014 GRNET S.A. All rights reserved.
2 b1ea24f3 Giorgos Korfiatis
#
3 b1ea24f3 Giorgos Korfiatis
# Redistribution and use in source and binary forms, with or
4 b1ea24f3 Giorgos Korfiatis
# without modification, are permitted provided that the following
5 b1ea24f3 Giorgos Korfiatis
# conditions are met:
6 b1ea24f3 Giorgos Korfiatis
#
7 b1ea24f3 Giorgos Korfiatis
#   1. Redistributions of source code must retain the above
8 b1ea24f3 Giorgos Korfiatis
#      copyright notice, this list of conditions and the following
9 b1ea24f3 Giorgos Korfiatis
#      disclaimer.
10 b1ea24f3 Giorgos Korfiatis
#
11 b1ea24f3 Giorgos Korfiatis
#   2. Redistributions in binary form must reproduce the above
12 b1ea24f3 Giorgos Korfiatis
#      copyright notice, this list of conditions and the following
13 b1ea24f3 Giorgos Korfiatis
#      disclaimer in the documentation and/or other materials
14 b1ea24f3 Giorgos Korfiatis
#      provided with the distribution.
15 b1ea24f3 Giorgos Korfiatis
#
16 b1ea24f3 Giorgos Korfiatis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 b1ea24f3 Giorgos Korfiatis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 b1ea24f3 Giorgos Korfiatis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 b1ea24f3 Giorgos Korfiatis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 b1ea24f3 Giorgos Korfiatis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 b1ea24f3 Giorgos Korfiatis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 b1ea24f3 Giorgos Korfiatis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 b1ea24f3 Giorgos Korfiatis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 b1ea24f3 Giorgos Korfiatis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 b1ea24f3 Giorgos Korfiatis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 b1ea24f3 Giorgos Korfiatis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 b1ea24f3 Giorgos Korfiatis
# POSSIBILITY OF SUCH DAMAGE.
28 b1ea24f3 Giorgos Korfiatis
#
29 b1ea24f3 Giorgos Korfiatis
# The views and conclusions contained in the software and
30 b1ea24f3 Giorgos Korfiatis
# documentation are those of the authors and should not be
31 b1ea24f3 Giorgos Korfiatis
# interpreted as representing official policies, either expressed
32 b1ea24f3 Giorgos Korfiatis
# or implied, of GRNET S.A.
33 b1ea24f3 Giorgos Korfiatis
34 2e46be99 Giorgos Korfiatis
from synnefo.util import units
35 bd1f667b Giorgos Korfiatis
from astakos.im.models import Resource, Service, Endpoint, EndpointData
36 30edd93d Giorgos Korfiatis
from astakos.im import quotas
37 9747707e Giorgos Korfiatis
import logging
38 b1ea24f3 Giorgos Korfiatis
39 9747707e Giorgos Korfiatis
logger = logging.getLogger(__name__)
40 b1ea24f3 Giorgos Korfiatis
41 c94dcec3 Giorgos Korfiatis
main_fields = ['desc', 'unit']
42 c94dcec3 Giorgos Korfiatis
config_fields = ['ui_visible', 'api_visible']
43 9747707e Giorgos Korfiatis
44 b1ea24f3 Giorgos Korfiatis
45 38807757 Giorgos Korfiatis
class RegisterException(Exception):
46 3a527b3a Giorgos Korfiatis
    pass
47 3a527b3a Giorgos Korfiatis
48 3a527b3a Giorgos Korfiatis
49 ccc5048f Giorgos Korfiatis
def different_component(service, resource):
50 ccc5048f Giorgos Korfiatis
    try:
51 ccc5048f Giorgos Korfiatis
        registered_for = Service.objects.get(name=resource.service_origin)
52 ccc5048f Giorgos Korfiatis
        return registered_for.component != service.component
53 ccc5048f Giorgos Korfiatis
    except Service.DoesNotExist:
54 ccc5048f Giorgos Korfiatis
        return False
55 ccc5048f Giorgos Korfiatis
56 ccc5048f Giorgos Korfiatis
57 bd1f667b Giorgos Korfiatis
def add_resource(resource_dict):
58 3a527b3a Giorgos Korfiatis
    name = resource_dict.get('name')
59 bd1f667b Giorgos Korfiatis
    service_type = resource_dict.get('service_type')
60 0e08e08e Giorgos Korfiatis
    service_origin = resource_dict.get('service_origin')
61 0e08e08e Giorgos Korfiatis
    if not name or not service_type or not service_origin:
62 38807757 Giorgos Korfiatis
        raise RegisterException("Malformed resource dict.")
63 3a527b3a Giorgos Korfiatis
64 9747707e Giorgos Korfiatis
    try:
65 ccc5048f Giorgos Korfiatis
        service = Service.objects.get(name=service_origin)
66 0e08e08e Giorgos Korfiatis
    except Service.DoesNotExist:
67 0e08e08e Giorgos Korfiatis
        m = "There is no service %s." % service_origin
68 38807757 Giorgos Korfiatis
        raise RegisterException(m)
69 0e08e08e Giorgos Korfiatis
70 0e08e08e Giorgos Korfiatis
    try:
71 c7e03d20 Giorgos Korfiatis
        r = Resource.objects.select_for_update().get(name=name)
72 3a527b3a Giorgos Korfiatis
        exists = True
73 ccc5048f Giorgos Korfiatis
        if r.service_type != service_type and \
74 ccc5048f Giorgos Korfiatis
                different_component(service, r):
75 bd1f667b Giorgos Korfiatis
            m = ("There already exists a resource named %s with service "
76 bd1f667b Giorgos Korfiatis
                 "type %s." % (name, r.service_type))
77 38807757 Giorgos Korfiatis
            raise RegisterException(m)
78 ccc5048f Giorgos Korfiatis
        if r.service_origin != service_origin and \
79 ccc5048f Giorgos Korfiatis
                different_component(service, r):
80 0e08e08e Giorgos Korfiatis
            m = ("There already exists a resource named %s registered for "
81 0e08e08e Giorgos Korfiatis
                 "service %s." % (name, r.service_origin))
82 38807757 Giorgos Korfiatis
            raise RegisterException(m)
83 ccc5048f Giorgos Korfiatis
        r.service_origin = service_origin
84 ccc5048f Giorgos Korfiatis
        r.service_type = service_type
85 9747707e Giorgos Korfiatis
    except Resource.DoesNotExist:
86 bd1f667b Giorgos Korfiatis
        r = Resource(name=name,
87 2e46be99 Giorgos Korfiatis
                     uplimit=units.PRACTICALLY_INFINITE,
88 5e3c112a Giorgos Korfiatis
                     project_default=units.PRACTICALLY_INFINITE,
89 0e08e08e Giorgos Korfiatis
                     service_type=service_type,
90 0e08e08e Giorgos Korfiatis
                     service_origin=service_origin)
91 3a527b3a Giorgos Korfiatis
        exists = False
92 c94dcec3 Giorgos Korfiatis
        for field in config_fields:
93 c94dcec3 Giorgos Korfiatis
            value = resource_dict.get(field)
94 c94dcec3 Giorgos Korfiatis
            if value is not None:
95 c94dcec3 Giorgos Korfiatis
                setattr(r, field, value)
96 b1ea24f3 Giorgos Korfiatis
97 c94dcec3 Giorgos Korfiatis
    for field in main_fields:
98 3a527b3a Giorgos Korfiatis
        value = resource_dict.get(field)
99 3a527b3a Giorgos Korfiatis
        if value is not None:
100 3a527b3a Giorgos Korfiatis
            setattr(r, field, value)
101 b1ea24f3 Giorgos Korfiatis
102 2dc27ac1 Giorgos Korfiatis
    if r.ui_visible and not r.api_visible:
103 2dc27ac1 Giorgos Korfiatis
        m = "Flag 'ui_visible' should entail 'api_visible'."
104 2dc27ac1 Giorgos Korfiatis
        raise RegisterException(m)
105 2dc27ac1 Giorgos Korfiatis
106 9747707e Giorgos Korfiatis
    r.save()
107 3a527b3a Giorgos Korfiatis
    if not exists:
108 2e46be99 Giorgos Korfiatis
        quotas.qh_sync_new_resource(r)
109 b1ea24f3 Giorgos Korfiatis
110 3a527b3a Giorgos Korfiatis
    if exists:
111 3a527b3a Giorgos Korfiatis
        logger.info("Updated resource %s." % (name))
112 9747707e Giorgos Korfiatis
    else:
113 3a527b3a Giorgos Korfiatis
        logger.info("Added resource %s." % (name))
114 73c02f75 Giorgos Korfiatis
    return r, exists
115 720955ff Giorgos Korfiatis
116 720955ff Giorgos Korfiatis
117 bf644f91 Giorgos Korfiatis
def update_base_default(resource, base_default):
118 bf644f91 Giorgos Korfiatis
    old_base_default = resource.uplimit
119 bf644f91 Giorgos Korfiatis
    if base_default == old_base_default:
120 bf644f91 Giorgos Korfiatis
        logger.info("Resource %s has base default %s; no need to update."
121 bf644f91 Giorgos Korfiatis
                    % (resource.name, base_default))
122 bf644f91 Giorgos Korfiatis
    else:
123 bf644f91 Giorgos Korfiatis
        resource.uplimit = base_default
124 bf644f91 Giorgos Korfiatis
        resource.save()
125 bf644f91 Giorgos Korfiatis
        logger.info("Updated resource %s with base default %s."
126 bf644f91 Giorgos Korfiatis
                    % (resource.name, base_default))
127 08043775 Giorgos Korfiatis
128 08043775 Giorgos Korfiatis
129 ba8c50e5 Giorgos Korfiatis
def update_project_default(resource, project_default):
130 ba8c50e5 Giorgos Korfiatis
    old_project_default = resource.project_default
131 ba8c50e5 Giorgos Korfiatis
    if project_default == old_project_default:
132 ba8c50e5 Giorgos Korfiatis
        logger.info("Resource %s has project default %s; no need to update."
133 ba8c50e5 Giorgos Korfiatis
                    % (resource.name, project_default))
134 ba8c50e5 Giorgos Korfiatis
    else:
135 ba8c50e5 Giorgos Korfiatis
        resource.project_default = project_default
136 ba8c50e5 Giorgos Korfiatis
        resource.save()
137 ba8c50e5 Giorgos Korfiatis
        logger.info("Updated resource %s with project default %s."
138 ba8c50e5 Giorgos Korfiatis
                    % (resource.name, project_default))
139 ba8c50e5 Giorgos Korfiatis
140 ba8c50e5 Giorgos Korfiatis
141 85ae5a4c Giorgos Korfiatis
def resources_to_dict(resources):
142 85ae5a4c Giorgos Korfiatis
    resource_dict = {}
143 85ae5a4c Giorgos Korfiatis
    for r in resources:
144 85ae5a4c Giorgos Korfiatis
        resource_dict[r.name] = r.get_info()
145 85ae5a4c Giorgos Korfiatis
    return resource_dict
146 85ae5a4c Giorgos Korfiatis
147 85ae5a4c Giorgos Korfiatis
148 08043775 Giorgos Korfiatis
def get_resources(resources=None, services=None):
149 08043775 Giorgos Korfiatis
    if resources is None:
150 08043775 Giorgos Korfiatis
        rs = Resource.objects.all()
151 08043775 Giorgos Korfiatis
    else:
152 08043775 Giorgos Korfiatis
        rs = Resource.objects.filter(name__in=resources)
153 08043775 Giorgos Korfiatis
154 08043775 Giorgos Korfiatis
    if services is not None:
155 08043775 Giorgos Korfiatis
        rs = rs.filter(service__in=services)
156 08043775 Giorgos Korfiatis
157 85ae5a4c Giorgos Korfiatis
    return rs
158 08043775 Giorgos Korfiatis
159 85ae5a4c Giorgos Korfiatis
160 85ae5a4c Giorgos Korfiatis
def get_api_visible_resources(resources=None, services=None):
161 85ae5a4c Giorgos Korfiatis
    rs = get_resources(resources, services)
162 85ae5a4c Giorgos Korfiatis
    return rs.filter(api_visible=True)
163 bd1f667b Giorgos Korfiatis
164 bd1f667b Giorgos Korfiatis
165 eb765213 Giorgos Korfiatis
def add_endpoint(component, service, endpoint_dict, out=None):
166 bd1f667b Giorgos Korfiatis
    endpoint = Endpoint.objects.create(service=service)
167 bd1f667b Giorgos Korfiatis
    for key, value in endpoint_dict.iteritems():
168 eb765213 Giorgos Korfiatis
        base_url = component.base_url
169 6f8a3e6a Giorgos Korfiatis
        if key == "publicURL" and (base_url is None or
170 6f8a3e6a Giorgos Korfiatis
                                   not value.startswith(base_url)):
171 eb765213 Giorgos Korfiatis
            warn = out.write if out is not None else logger.warning
172 eb765213 Giorgos Korfiatis
            warn("Warning: Endpoint URL '%s' does not start with "
173 eb765213 Giorgos Korfiatis
                 "assumed component base URL '%s'.\n" % (value, base_url))
174 bd1f667b Giorgos Korfiatis
        EndpointData.objects.create(
175 bd1f667b Giorgos Korfiatis
            endpoint=endpoint, key=key, value=value)
176 bd1f667b Giorgos Korfiatis
177 bd1f667b Giorgos Korfiatis
178 eb765213 Giorgos Korfiatis
def add_service(component, name, service_type, endpoints, out=None):
179 bd1f667b Giorgos Korfiatis
    defaults = {'component': component,
180 bd1f667b Giorgos Korfiatis
                'type': service_type,
181 bd1f667b Giorgos Korfiatis
                }
182 bd1f667b Giorgos Korfiatis
    service, created = Service.objects.get_or_create(
183 bd1f667b Giorgos Korfiatis
        name=name, defaults=defaults)
184 bd1f667b Giorgos Korfiatis
185 bd1f667b Giorgos Korfiatis
    if not created:
186 bd1f667b Giorgos Korfiatis
        if service.component != component:
187 bd1f667b Giorgos Korfiatis
            m = ("There is already a service named %s registered by %s." %
188 bd1f667b Giorgos Korfiatis
                 (name, service.component.name))
189 38807757 Giorgos Korfiatis
            raise RegisterException(m)
190 bd1f667b Giorgos Korfiatis
        service.endpoints.all().delete()
191 51356707 Giorgos Korfiatis
        for key, value in defaults.iteritems():
192 51356707 Giorgos Korfiatis
            setattr(service, key, value)
193 bd1f667b Giorgos Korfiatis
        service.save()
194 bd1f667b Giorgos Korfiatis
195 bd1f667b Giorgos Korfiatis
    for endpoint in endpoints:
196 eb765213 Giorgos Korfiatis
        add_endpoint(component, service, endpoint, out=out)
197 bd1f667b Giorgos Korfiatis
198 bd1f667b Giorgos Korfiatis
    return not created