Path: blob/develop/awscli/customizations/generatecliskeleton.py
1566 views
# Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.1#2# Licensed under the Apache License, Version 2.0 (the "License"). You3# may not use this file except in compliance with the License. A copy of4# the License is located at5#6# http://aws.amazon.com/apache2.0/7#8# or in the "license" file accompanying this file. This file is9# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF10# ANY KIND, either express or implied. See the License for the specific11# language governing permissions and limitations under the License.12import json13import sys1415from botocore import xform_name16from botocore.stub import Stubber17from botocore.utils import ArgumentGenerator1819from awscli.clidriver import CLIOperationCaller20from awscli.customizations.arguments import OverrideRequiredArgsArgument21from awscli.utils import json_encoder222324def register_generate_cli_skeleton(cli):25cli.register('building-argument-table', add_generate_skeleton)262728def add_generate_skeleton(session, operation_model, argument_table, **kwargs):29# This argument cannot support operations with streaming output which30# is designated by the argument name `outfile`.31if 'outfile' not in argument_table:32generate_cli_skeleton_argument = GenerateCliSkeletonArgument(33session, operation_model)34generate_cli_skeleton_argument.add_to_arg_table(argument_table)353637class GenerateCliSkeletonArgument(OverrideRequiredArgsArgument):38"""This argument writes a generated JSON skeleton to stdout3940The argument, if present in the command line, will prevent the intended41command from taking place. Instead, it will generate a JSON skeleton and42print it to standard output.43"""44ARG_DATA = {45'name': 'generate-cli-skeleton',46'help_text': (47'Prints a JSON skeleton to standard output without sending '48'an API request. If provided with no value or the value '49'``input``, prints a sample input JSON that can be used as an '50'argument for ``--cli-input-json``. If provided with the value '51'``output``, it validates the command inputs and returns a '52'sample output JSON for that command.'53),54'nargs': '?',55'const': 'input',56'choices': ['input', 'output'],57}5859def __init__(self, session, operation_model):60super(GenerateCliSkeletonArgument, self).__init__(session)61self._operation_model = operation_model6263def _register_argument_action(self):64self._session.register(65'calling-command.*', self.generate_json_skeleton)66super(GenerateCliSkeletonArgument, self)._register_argument_action()6768def override_required_args(self, argument_table, args, **kwargs):69arg_name = '--' + self.name70if arg_name in args:71arg_location = args.index(arg_name)72try:73# If the value of --generate-cli-skeleton is ``output``,74# do not force required arguments to be optional as75# ``--generate-cli-skeleton output`` validates commands76# as well as print out the sample output.77if args[arg_location + 1] == 'output':78return79except IndexError:80pass81super(GenerateCliSkeletonArgument, self).override_required_args(82argument_table, args, **kwargs)8384def generate_json_skeleton(self, call_parameters, parsed_args,85parsed_globals, **kwargs):86if getattr(parsed_args, 'generate_cli_skeleton', None):87for_output = parsed_args.generate_cli_skeleton == 'output'88operation_model = self._operation_model8990if for_output:91service_name = operation_model.service_model.service_name92operation_name = operation_model.name93# TODO: It would be better to abstract this logic into94# classes for both the input and output option such that95# a similar set of inputs are taken in and output96# similar functionality.97return StubbedCLIOperationCaller(self._session).invoke(98service_name, operation_name, call_parameters,99parsed_globals)100else:101argument_generator = ArgumentGenerator()102operation_input_shape = operation_model.input_shape103if operation_input_shape is None:104skeleton = {}105else:106skeleton = argument_generator.generate_skeleton(107operation_input_shape)108109sys.stdout.write(110json.dumps(skeleton, indent=4, default=json_encoder)111)112sys.stdout.write('\n')113return 0114115116class StubbedCLIOperationCaller(CLIOperationCaller):117"""A stubbed CLIOperationCaller118119It generates a fake response and uses the response and provided parameters120to make a stubbed client call for an operation command.121"""122def _make_client_call(self, client, operation_name, parameters,123parsed_globals):124method_name = xform_name(operation_name)125operation_model = client.meta.service_model.operation_model(126operation_name)127fake_response = {}128if operation_model.output_shape:129argument_generator = ArgumentGenerator(use_member_names=True)130fake_response = argument_generator.generate_skeleton(131operation_model.output_shape)132with Stubber(client) as stubber:133stubber.add_response(method_name, fake_response)134return getattr(client, method_name)(**parameters)135136137