1# Copyright 2007 Google Inc.
2#
3# This program is free software; you can redistribute it and/or
4# modify it under the terms of the GNU General Public License
5# as published by the Free Software Foundation; either version 2
6# of the License, or (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software Foundation,
15# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16"""Base class of data source object for nss_cache."""
17
18__author__ = ('jaq@google.com (Jamie Wilkinson)',
19              'vasilios@google.com (Vasilios Hoffman)')
20
21import logging
22
23from nss_cache import config
24from nss_cache import error
25
26
27class Source(object):
28    """Abstract base class for map data sources."""
29
30    UPDATER = None
31
32    def __init__(self, conf):
33        """Initialise the Source object.
34
35        Args:
36          conf: A dictionary of key/value pairs.
37
38        Raises:
39          RuntimeError: object wasn't initialised with a dict
40        """
41        if not isinstance(conf, dict):
42            raise RuntimeError('Source constructor not passed a dictionary')
43
44        self.conf = conf
45
46        # create a logger for our children
47        self.log = logging.getLogger(__name__)
48
49    def GetMap(self, map_name, since=None, location=None):
50        """Get a specific map from this source.
51
52        Args:
53          map_name: A string representation of the map you want
54          since: optional timestamp for incremental query
55          location: optional field used by automounts to indicate a specific map
56
57        Returns:
58          A Map child class for the map requested.
59
60        Raises:
61          UnsupportedMap: for unknown source maps
62        """
63        if map_name == config.MAP_PASSWORD:
64            return self.GetPasswdMap(since)
65        elif map_name == config.MAP_SSHKEY:
66            return self.GetSshkeyMap(since)
67        elif map_name == config.MAP_GROUP:
68            return self.GetGroupMap(since)
69        elif map_name == config.MAP_SHADOW:
70            return self.GetShadowMap(since)
71        elif map_name == config.MAP_NETGROUP:
72            return self.GetNetgroupMap(since)
73        elif map_name == config.MAP_AUTOMOUNT:
74            return self.GetAutomountMap(since, location=location)
75
76        raise error.UnsupportedMap('Source can not fetch %s' % map_name)
77
78    def GetAutomountMap(self, since=None, location=None):
79        """Get an automount map from this source."""
80        raise NotImplementedError
81
82    def GetAutomountMasterMap(self):
83        """Get an automount map from this source."""
84        raise NotImplementedError
85
86    def Verify(self):
87        """Perform verification of the source availability.
88
89        Attempt to open/connect or otherwise use the data source, and
90        report if there are any problems.
91        """
92        raise NotImplementedError
93
94
95class FileSource(object):
96    """Abstract base class for file data sources."""
97
98    def __init__(self, conf):
99        """Initialise the Source object.
100
101        Args:
102          conf: A dictionary of key/value pairs.
103
104        Raises:
105          RuntimeError: object wasn't initialised with a dict
106        """
107        if not isinstance(conf, dict):
108            raise RuntimeError('Source constructor not passed a dictionary')
109
110        self.conf = conf
111
112        # create a logger for our children
113        self.log = logging.getLogger(__name__)
114
115    def GetFile(self, map_name, dst_file, current_file, location=None):
116        """Retrieve a file from this source.
117
118        Args:
119          map_name: A string representation of the map whose file you want
120          dst_file: Temporary filename to write to.
121          current_file: Path to the current cache.
122          location: optional field used by automounts to indicate a specific map
123
124        Returns:
125          path to new file
126
127        Raises:
128          UnsupportedMap: for unknown source maps
129        """
130        if map_name == config.MAP_PASSWORD:
131            return self.GetPasswdFile(dst_file, current_file)
132        elif map_name == config.MAP_GROUP:
133            return self.GetGroupFile(dst_file, current_file)
134        elif map_name == config.MAP_SHADOW:
135            return self.GetShadowFile(dst_file, current_file)
136        elif map_name == config.MAP_NETGROUP:
137            return self.GetNetgroupFile(dst_file, current_file)
138        elif map_name == config.MAP_AUTOMOUNT:
139            return self.GetAutomountFile(dst_file,
140                                         current_file,
141                                         location=location)
142
143        raise error.UnsupportedMap('Source can not fetch %s' % map_name)
144