aboutsummaryrefslogtreecommitdiffstats
path: root/keystone-moon/keystone/catalog/backends/kvs.py
blob: 30a121d8a1e56aa74baf7e017c0ccf56fedc9b45 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# Copyright 2012 OpenStack Foundation
#
# 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 keystone import catalog
from keystone.common import driver_hints
from keystone.common import kvs


class Catalog(kvs.Base, catalog.Driver):
    # Public interface
    def get_catalog(self, user_id, tenant_id):
        return self.db.get('catalog-%s-%s' % (tenant_id, user_id))

    # region crud

    def _delete_child_regions(self, region_id, root_region_id):
        """Delete all child regions.

        Recursively delete any region that has the supplied region
        as its parent.
        """
        children = [r for r in self.list_regions(driver_hints.Hints())
                    if r['parent_region_id'] == region_id]
        for child in children:
            if child['id'] == root_region_id:
                # Hit a circular region hierarchy
                return
            self._delete_child_regions(child['id'], root_region_id)
            self._delete_region(child['id'])

    def _check_parent_region(self, region_ref):
        """Raise a NotFound if the parent region does not exist.

        If the region_ref has a specified parent_region_id, check that
        the parent exists, otherwise, raise a NotFound.
        """
        parent_region_id = region_ref.get('parent_region_id')
        if parent_region_id is not None:
            # This will raise NotFound if the parent doesn't exist,
            # which is the behavior we want.
            self.get_region(parent_region_id)

    def create_region(self, region):
        region_id = region['id']
        region.setdefault('parent_region_id')
        self._check_parent_region(region)
        self.db.set('region-%s' % region_id, region)
        region_list = set(self.db.get('region_list', []))
        region_list.add(region_id)
        self.db.set('region_list', list(region_list))
        return region

    def list_regions(self, hints):
        return [self.get_region(x) for x in self.db.get('region_list', [])]

    def get_region(self, region_id):
        return self.db.get('region-%s' % region_id)

    def update_region(self, region_id, region):
        self._check_parent_region(region)
        old_region = self.get_region(region_id)
        old_region.update(region)
        self._ensure_no_circle_in_hierarchical_regions(old_region)
        self.db.set('region-%s' % region_id, old_region)
        return old_region

    def _delete_region(self, region_id):
        self.db.delete('region-%s' % region_id)
        region_list = set(self.db.get('region_list', []))
        region_list.remove(region_id)
        self.db.set('region_list', list(region_list))

    def delete_region(self, region_id):
        self._delete_child_regions(region_id, region_id)
        self._delete_region(region_id)

    # service crud

    def create_service(self, service_id, service):
        self.db.set('service-%s' % service_id, service)
        service_list = set(self.db.get('service_list', []))
        service_list.add(service_id)
        self.db.set('service_list', list(service_list))
        return service

    def list_services(self, hints):
        return [self.get_service(x) for x in self.db.get('service_list', [])]

    def get_service(self, service_id):
        return self.db.get('service-%s' % service_id)

    def update_service(self, service_id, service):
        old_service = self.get_service(service_id)
        old_service.update(service)
        self.db.set('service-%s' % service_id, old_service)
        return old_service

    def delete_service(self, service_id):
        # delete referencing endpoints
        for endpoint_id in self.db.get('endpoint_list', []):
            if self.get_endpoint(endpoint_id)['service_id'] == service_id:
                self.delete_endpoint(endpoint_id)

        self.db.delete('service-%s' % service_id)
        service_list = set(self.db.get('service_list', []))
        service_list.remove(service_id)
        self.db.set('service_list', list(service_list))

    # endpoint crud

    def create_endpoint(self, endpoint_id, endpoint):
        self.db.set('endpoint-%s' % endpoint_id, endpoint)
        endpoint_list = set(self.db.get('endpoint_list', []))
        endpoint_list.add(endpoint_id)
        self.db.set('endpoint_list', list(endpoint_list))
        return endpoint

    def list_endpoints(self, hints):
        return [self.get_endpoint(x) for x in self.db.get('endpoint_list', [])]

    def get_endpoint(self, endpoint_id):
        return self.db.get('endpoint-%s' % endpoint_id)

    def update_endpoint(self, endpoint_id, endpoint):
        if endpoint.get('region_id') is not None:
            self.get_region(endpoint['region_id'])

        old_endpoint = self.get_endpoint(endpoint_id)
        old_endpoint.update(endpoint)
        self.db.set('endpoint-%s' % endpoint_id, old_endpoint)
        return old_endpoint

    def delete_endpoint(self, endpoint_id):
        self.db.delete('endpoint-%s' % endpoint_id)
        endpoint_list = set(self.db.get('endpoint_list', []))
        endpoint_list.remove(endpoint_id)
        self.db.set('endpoint_list', list(endpoint_list))

    # Private interface
    def _create_catalog(self, user_id, tenant_id, data):
        self.db.set('catalog-%s-%s' % (tenant_id, user_id), data)
        return data