Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

# vim: tabstop=4 shiftwidth=4 softtabstop=4 

 

# Copyright 2012 OpenStack LLC 

# 

# 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 os.path 

 

from keystone.catalog.backends import kvs 

from keystone.catalog import core 

from keystone.common import logging 

from keystone import config 

 

 

LOG = logging.getLogger(__name__) 

 

CONF = config.CONF 

config.register_str('template_file', 

                    default='default_catalog.templates', 

                    group='catalog') 

 

 

def parse_templates(template_lines): 

    o = {} 

    for line in template_lines: 

        if ' = ' not in line: 

            continue 

 

        k, v = line.strip().split(' = ') 

41        if not k.startswith('catalog.'): 

            continue 

 

        parts = k.split('.') 

 

        region = parts[1] 

        # NOTE(termie): object-store insists on having a dash 

        service = parts[2].replace('_', '-') 

        key = parts[3] 

 

        region_ref = o.get(region, {}) 

        service_ref = region_ref.get(service, {}) 

        service_ref[key] = v 

 

        region_ref[service] = service_ref 

        o[region] = region_ref 

 

    return o 

 

 

# TODO(jaypipes): should be templated.Catalog, 

# not templated.TemplatedCatalog to be consistent with 

# other catalog backends 

class TemplatedCatalog(kvs.Catalog): 

    """A backend that generates endpoints for the Catalog based on templates. 

 

    It is usually configured via config entries that look like: 

 

      catalog.$REGION.$SERVICE.$key = $value 

 

    and is stored in a similar looking hierarchy. Where a value can contain 

    values to be interpolated by standard python string interpolation that look 

    like (the % is replaced by a $ due to paste attmepting to interpolate on 

    its own: 

 

      http://localhost:$(public_port)s/ 

 

    When expanding the template it will pass in a dict made up of the conf 

    instance plus a few additional key-values, notably tenant_id and user_id. 

 

    It does not care what the keys and values are but it is worth noting that 

    keystone_compat will expect certain keys to be there so that it can munge 

    them into the output format keystone expects. These keys are: 

 

      name - the name of the service, most likely repeated for all services of 

             the same type, across regions. 

 

      adminURL - the url of the admin endpoint 

 

      publicURL - the url of the public endpoint 

 

      internalURL - the url of the internal endpoint 

 

    """ 

 

    def __init__(self, templates=None): 

97        if templates: 

            self.templates = templates 

        else: 

            template_file = CONF.catalog.template_file 

101            if not os.path.exists(template_file): 

                template_file = CONF.find_file(template_file) 

            self._load_templates(template_file) 

        super(TemplatedCatalog, self).__init__() 

 

    def _load_templates(self, template_file): 

        try: 

            self.templates = parse_templates(open(template_file)) 

        except IOError: 

            LOG.critical(_('Unable to open template file %s') % template_file) 

            raise 

 

    def get_catalog(self, user_id, tenant_id, metadata=None): 

        d = dict(CONF.iteritems()) 

        d.update({'tenant_id': tenant_id, 

                  'user_id': user_id}) 

 

        o = {} 

        for region, region_ref in self.templates.iteritems(): 

            o[region] = {} 

            for service, service_ref in region_ref.iteritems(): 

                o[region][service] = {} 

                for k, v in service_ref.iteritems(): 

                    o[region][service][k] = core.format_url(v, d) 

 

        return o