1# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
2# All Rights Reserved.
3#
4#    Licensed under the Apache License, Version 2.0 (the "License"); you may
5#    not use this file except in compliance with the License. You may obtain
6#    a copy of the License at
7#
8#         http://www.apache.org/licenses/LICENSE-2.0
9#
10#    Unless required by applicable law or agreed to in writing, software
11#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13#    License for the specific language governing permissions and limitations
14#    under the License.
15
16"""
17Client side of the volume backup RPC API.
18"""
19
20
21from oslo_log import log as logging
22
23from cinder.common import constants
24from cinder import rpc
25
26
27LOG = logging.getLogger(__name__)
28
29
30class BackupAPI(rpc.RPCAPI):
31    """Client side of the volume rpc API.
32
33    API version history:
34
35    .. code-block:: none
36
37        1.0 - Initial version.
38        1.1 - Changed methods to accept backup objects instead of IDs.
39        1.2 - A version that got in by mistake (without breaking anything).
40        1.3 - Dummy version bump to mark start of having cinder-backup service
41              decoupled from cinder-volume.
42
43        ... Mitaka supports messaging 1.3. Any changes to existing methods in
44        1.x after this point should be done so that they can handle version cap
45        set to 1.3.
46
47        2.0 - Remove 1.x compatibility
48        2.1 - Adds set_log_levels and get_log_levels
49    """
50
51    RPC_API_VERSION = '2.1'
52    RPC_DEFAULT_VERSION = '2.0'
53    TOPIC = constants.BACKUP_TOPIC
54    BINARY = 'cinder-backup'
55
56    def create_backup(self, ctxt, backup):
57        LOG.debug("create_backup in rpcapi backup_id %s", backup.id)
58        cctxt = self._get_cctxt(server=backup.host)
59        cctxt.cast(ctxt, 'create_backup', backup=backup)
60
61    def restore_backup(self, ctxt, volume_host, backup, volume_id):
62        LOG.debug("restore_backup in rpcapi backup_id %s", backup.id)
63        cctxt = self._get_cctxt(server=volume_host)
64        cctxt.cast(ctxt, 'restore_backup', backup=backup,
65                   volume_id=volume_id)
66
67    def delete_backup(self, ctxt, backup):
68        LOG.debug("delete_backup rpcapi backup_id %s", backup.id)
69        cctxt = self._get_cctxt(server=backup.host)
70        cctxt.cast(ctxt, 'delete_backup', backup=backup)
71
72    def export_record(self, ctxt, backup):
73        LOG.debug("export_record in rpcapi backup_id %(id)s "
74                  "on host %(host)s.",
75                  {'id': backup.id,
76                   'host': backup.host})
77        cctxt = self._get_cctxt(server=backup.host)
78        return cctxt.call(ctxt, 'export_record', backup=backup)
79
80    def import_record(self, ctxt, host, backup, backup_service, backup_url,
81                      backup_hosts):
82        LOG.debug("import_record rpcapi backup id %(id)s "
83                  "on host %(host)s for backup_url %(url)s.",
84                  {'id': backup.id, 'host': host, 'url': backup_url})
85        cctxt = self._get_cctxt(server=host)
86        cctxt.cast(ctxt, 'import_record',
87                   backup=backup,
88                   backup_service=backup_service,
89                   backup_url=backup_url,
90                   backup_hosts=backup_hosts)
91
92    def reset_status(self, ctxt, backup, status):
93        LOG.debug("reset_status in rpcapi backup_id %(id)s "
94                  "on host %(host)s.",
95                  {'id': backup.id, 'host': backup.host})
96        cctxt = self._get_cctxt(server=backup.host)
97        return cctxt.cast(ctxt, 'reset_status', backup=backup, status=status)
98
99    def check_support_to_force_delete(self, ctxt, host):
100        LOG.debug("Check if backup driver supports force delete "
101                  "on host %(host)s.", {'host': host})
102        cctxt = self._get_cctxt(server=host)
103        return cctxt.call(ctxt, 'check_support_to_force_delete')
104
105    @rpc.assert_min_rpc_version('2.1')
106    def set_log_levels(self, context, service, log_request):
107        cctxt = self._get_cctxt(server=service.host, version='2.1')
108        cctxt.cast(context, 'set_log_levels', log_request=log_request)
109
110    @rpc.assert_min_rpc_version('2.1')
111    def get_log_levels(self, context, service, log_request):
112        cctxt = self._get_cctxt(server=service.host, version='2.1')
113        return cctxt.call(context, 'get_log_levels', log_request=log_request)
114