xref: /spdk/scripts/sma-client.py (revision 7506a7aa53d239f533af3bc768f0d2af55e735fe)
1#!/usr/bin/env python3
2
3from argparse import ArgumentParser
4import grpc
5import google.protobuf.json_format as json_format
6import importlib
7import json
8import logging
9import os
10import sys
11
12sys.path.append(os.path.dirname(__file__) + '/../python')
13
14import spdk.sma.proto.sma_pb2 as sma_pb2                        # noqa
15import spdk.sma.proto.sma_pb2_grpc as sma_pb2_grpc              # noqa
16import spdk.sma.proto.nvmf_tcp_pb2 as nvmf_tcp_pb2              # noqa
17import spdk.sma.proto.nvmf_tcp_pb2_grpc as nvmf_tcp_pb2_grpc    # noqa
18
19
20class Client:
21    def __init__(self, addr, port):
22        self._service = sma_pb2.DESCRIPTOR.services_by_name['StorageManagementAgent']
23        self.addr = addr
24        self.port = port
25
26    def _get_message_type(self, descriptor):
27        return getattr(sma_pb2, descriptor.name)
28
29    def _get_method_types(self, method_name):
30        method = self._service.methods_by_name.get(method_name)
31        return (self._get_message_type(method.input_type),
32                self._get_message_type(method.output_type))
33
34    def call(self, method, params):
35        with grpc.insecure_channel(f'{self.addr}:{self.port}') as channel:
36            stub = sma_pb2_grpc.StorageManagementAgentStub(channel)
37            func = getattr(stub, method)
38            input, output = self._get_method_types(method)
39            response = func(request=json_format.ParseDict(params, input()))
40            return json_format.MessageToDict(response,
41                                             preserving_proto_field_name=True)
42
43
44def load_plugins(plugins):
45    for plugin in plugins:
46        logging.debug(f'Loading external plugin: {plugin}')
47        module = importlib.import_module(plugin)
48
49
50def parse_argv():
51    parser = ArgumentParser(description='Storage Management Agent client')
52    parser.add_argument('--address', '-a', default='localhost',
53                        help='IP address of SMA instance to connect to')
54    parser.add_argument('--port', '-p', default=8080, type=int,
55                        help='Port number of SMA instance to connect to')
56    return parser.parse_args()
57
58
59def main(args):
60    argv = parse_argv()
61    logging.basicConfig(level=os.environ.get('SMA_LOGLEVEL', 'WARNING').upper())
62    load_plugins(filter(None, os.environ.get('SMA_PLUGINS', '').split(':')))
63    client = Client(argv.address, argv.port)
64    request = json.loads(sys.stdin.read())
65    result = client.call(request['method'], request.get('params', {}))
66    print(json.dumps(result, indent=2))
67
68
69if __name__ == '__main__':
70    main(sys.argv[1:])
71