Blame pynslcd/service.py

Packit 6bd9ab
Packit 6bd9ab
# service.py - service entry lookup routines
Packit 6bd9ab
#
Packit 6bd9ab
# Copyright (C) 2011, 2012, 2013 Arthur de Jong
Packit 6bd9ab
#
Packit 6bd9ab
# This library is free software; you can redistribute it and/or
Packit 6bd9ab
# modify it under the terms of the GNU Lesser General Public
Packit 6bd9ab
# License as published by the Free Software Foundation; either
Packit 6bd9ab
# version 2.1 of the License, or (at your option) any later version.
Packit 6bd9ab
#
Packit 6bd9ab
# This library is distributed in the hope that it will be useful,
Packit 6bd9ab
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6bd9ab
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6bd9ab
# Lesser General Public License for more details.
Packit 6bd9ab
#
Packit 6bd9ab
# You should have received a copy of the GNU Lesser General Public
Packit 6bd9ab
# License along with this library; if not, write to the Free Software
Packit 6bd9ab
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit 6bd9ab
# 02110-1301 USA
Packit 6bd9ab
Packit 6bd9ab
import datetime
Packit 6bd9ab
Packit 6bd9ab
import cache
Packit 6bd9ab
import common
Packit 6bd9ab
import constants
Packit 6bd9ab
import search
Packit 6bd9ab
Packit 6bd9ab
Packit 6bd9ab
attmap = common.Attributes(cn='cn',
Packit 6bd9ab
                           ipServicePort='ipServicePort',
Packit 6bd9ab
                           ipServiceProtocol='ipServiceProtocol')
Packit 6bd9ab
filter = '(objectClass=ipService)'
Packit 6bd9ab
Packit 6bd9ab
Packit 6bd9ab
class Search(search.LDAPSearch):
Packit 6bd9ab
Packit 6bd9ab
    case_sensitive = ('cn', 'ipServiceProtocol')
Packit 6bd9ab
    limit_attributes = ('ipServiceProtocol', )
Packit 6bd9ab
    canonical_first = ('cn', )
Packit 6bd9ab
    required = ('cn', 'ipServicePort', 'ipServiceProtocol')
Packit 6bd9ab
Packit 6bd9ab
Packit 6bd9ab
class Cache(cache.Cache):
Packit 6bd9ab
Packit 6bd9ab
    tables = ('service_cache', 'service_alias_cache')
Packit 6bd9ab
Packit 6bd9ab
    create_sql = '''
Packit 6bd9ab
        CREATE TABLE IF NOT EXISTS `service_cache`
Packit 6bd9ab
          ( `cn` TEXT NOT NULL,
Packit 6bd9ab
            `ipServicePort` INTEGER NOT NULL,
Packit 6bd9ab
            `ipServiceProtocol` TEXT NOT NULL,
Packit 6bd9ab
            `mtime` TIMESTAMP NOT NULL,
Packit 6bd9ab
            UNIQUE (`ipServicePort`, `ipServiceProtocol`) );
Packit 6bd9ab
        CREATE TABLE IF NOT EXISTS `service_alias_cache`
Packit 6bd9ab
          ( `ipServicePort` INTEGER NOT NULL,
Packit 6bd9ab
            `ipServiceProtocol` TEXT NOT NULL,
Packit 6bd9ab
            `cn` TEXT NOT NULL,
Packit 6bd9ab
            FOREIGN KEY(`ipServicePort`) REFERENCES `service_cache`(`ipServicePort`)
Packit 6bd9ab
            ON DELETE CASCADE ON UPDATE CASCADE,
Packit 6bd9ab
            FOREIGN KEY(`ipServiceProtocol`) REFERENCES `service_cache`(`ipServiceProtocol`)
Packit 6bd9ab
            ON DELETE CASCADE ON UPDATE CASCADE );
Packit 6bd9ab
        CREATE INDEX IF NOT EXISTS `service_alias_idx1` ON `service_alias_cache`(`ipServicePort`);
Packit 6bd9ab
        CREATE INDEX IF NOT EXISTS `service_alias_idx2` ON `service_alias_cache`(`ipServiceProtocol`);
Packit 6bd9ab
    '''
Packit 6bd9ab
Packit 6bd9ab
    retrieve_sql = '''
Packit 6bd9ab
        SELECT `service_cache`.`cn` AS `cn`,
Packit 6bd9ab
               `service_alias_cache`.`cn` AS `alias`,
Packit 6bd9ab
               `service_cache`.`ipServicePort`,
Packit 6bd9ab
               `service_cache`.`ipServiceProtocol`,
Packit 6bd9ab
               `mtime`
Packit 6bd9ab
        FROM `service_cache`
Packit 6bd9ab
        LEFT JOIN `service_alias_cache`
Packit 6bd9ab
          ON `service_alias_cache`.`ipServicePort` = `service_cache`.`ipServicePort`
Packit 6bd9ab
         AND `service_alias_cache`.`ipServiceProtocol` = `service_cache`.`ipServiceProtocol`
Packit 6bd9ab
    '''
Packit 6bd9ab
Packit 6bd9ab
    retrieve_by = dict(
Packit 6bd9ab
        cn='''
Packit 6bd9ab
            ( `service_cache`.`cn` = ? OR
Packit 6bd9ab
              0 < (
Packit 6bd9ab
                  SELECT COUNT(*)
Packit 6bd9ab
                  FROM `service_alias_cache` `by_alias`
Packit 6bd9ab
                  WHERE `by_alias`.`cn` = ?
Packit 6bd9ab
                    AND `by_alias`.`ipServicePort` = `service_cache`.`ipServicePort`
Packit 6bd9ab
                    AND `by_alias`.`ipServiceProtocol` = `service_cache`.`ipServiceProtocol`
Packit 6bd9ab
                ))
Packit 6bd9ab
        ''',
Packit 6bd9ab
    )
Packit 6bd9ab
Packit 6bd9ab
    group_by = (0, 2, 3)  # cn, ipServicePort, ipServiceProtocol
Packit 6bd9ab
    group_columns = (1, )  # alias
Packit 6bd9ab
Packit 6bd9ab
    def store(self, name, aliases, port, protocol):
Packit 6bd9ab
        self.con.execute('''
Packit 6bd9ab
            INSERT OR REPLACE INTO `service_cache`
Packit 6bd9ab
            VALUES
Packit 6bd9ab
              (?, ?, ?, ?)
Packit 6bd9ab
        ''', (name, port, protocol, datetime.datetime.now()))
Packit 6bd9ab
        self.con.execute('''
Packit 6bd9ab
            DELETE FROM `service_alias_cache`
Packit 6bd9ab
            WHERE `ipServicePort` = ?
Packit 6bd9ab
              AND `ipServiceProtocol` = ?
Packit 6bd9ab
        ''', (port, protocol))
Packit 6bd9ab
        self.con.executemany('''
Packit 6bd9ab
            INSERT INTO `service_alias_cache`
Packit 6bd9ab
            VALUES
Packit 6bd9ab
              (?, ?, ?)
Packit 6bd9ab
        ''', ((port, protocol, alias) for alias in aliases))
Packit 6bd9ab
Packit 6bd9ab
Packit 6bd9ab
class ServiceRequest(common.Request):
Packit 6bd9ab
Packit 6bd9ab
    def write(self, name, aliases, port, protocol):
Packit 6bd9ab
        self.fp.write_string(name)
Packit 6bd9ab
        self.fp.write_stringlist(aliases)
Packit 6bd9ab
        self.fp.write_int32(port)
Packit 6bd9ab
        self.fp.write_string(protocol)
Packit 6bd9ab
Packit 6bd9ab
    def convert(self, dn, attributes, parameters):
Packit 6bd9ab
        names = attributes['cn']
Packit 6bd9ab
        port = int(attributes['ipServicePort'][0])
Packit 6bd9ab
        protocols = attributes['ipServiceProtocol']
Packit 6bd9ab
        for protocol in protocols:
Packit 6bd9ab
            yield (names[0], names[1:], port, protocol)
Packit 6bd9ab
Packit 6bd9ab
Packit 6bd9ab
class ServiceByNameRequest(ServiceRequest):
Packit 6bd9ab
Packit 6bd9ab
    action = constants.NSLCD_ACTION_SERVICE_BYNAME
Packit 6bd9ab
Packit 6bd9ab
    def read_parameters(self, fp):
Packit 6bd9ab
        name = fp.read_string()
Packit 6bd9ab
        protocol = fp.read_string()
Packit 6bd9ab
        if protocol:
Packit 6bd9ab
            return dict(cn=name, ipServiceProtocol=protocol)
Packit 6bd9ab
        else:
Packit 6bd9ab
            return dict(cn=name)
Packit 6bd9ab
Packit 6bd9ab
Packit 6bd9ab
class ServiceByNumberRequest(ServiceRequest):
Packit 6bd9ab
Packit 6bd9ab
    action = constants.NSLCD_ACTION_SERVICE_BYNUMBER
Packit 6bd9ab
Packit 6bd9ab
    def read_parameters(self, fp):
Packit 6bd9ab
        number = fp.read_int32()
Packit 6bd9ab
        protocol = fp.read_string()
Packit 6bd9ab
        if protocol:
Packit 6bd9ab
            return dict(ipServicePort=number, ipServiceProtocol=protocol)
Packit 6bd9ab
        else:
Packit 6bd9ab
            return dict(ipServicePort=number)
Packit 6bd9ab
Packit 6bd9ab
Packit 6bd9ab
class ServiceAllRequest(ServiceRequest):
Packit 6bd9ab
Packit 6bd9ab
    action = constants.NSLCD_ACTION_SERVICE_ALL