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