Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aws
GitHub Repository: aws/aws-cli
Path: blob/develop/awscli/customizations/generatecliskeleton.py
1566 views
1
# Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
#
3
# Licensed under the Apache License, Version 2.0 (the "License"). You
4
# may not use this file except in compliance with the License. A copy of
5
# the License is located at
6
#
7
# http://aws.amazon.com/apache2.0/
8
#
9
# or in the "license" file accompanying this file. This file is
10
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
# ANY KIND, either express or implied. See the License for the specific
12
# language governing permissions and limitations under the License.
13
import json
14
import sys
15
16
from botocore import xform_name
17
from botocore.stub import Stubber
18
from botocore.utils import ArgumentGenerator
19
20
from awscli.clidriver import CLIOperationCaller
21
from awscli.customizations.arguments import OverrideRequiredArgsArgument
22
from awscli.utils import json_encoder
23
24
25
def register_generate_cli_skeleton(cli):
26
cli.register('building-argument-table', add_generate_skeleton)
27
28
29
def add_generate_skeleton(session, operation_model, argument_table, **kwargs):
30
# This argument cannot support operations with streaming output which
31
# is designated by the argument name `outfile`.
32
if 'outfile' not in argument_table:
33
generate_cli_skeleton_argument = GenerateCliSkeletonArgument(
34
session, operation_model)
35
generate_cli_skeleton_argument.add_to_arg_table(argument_table)
36
37
38
class GenerateCliSkeletonArgument(OverrideRequiredArgsArgument):
39
"""This argument writes a generated JSON skeleton to stdout
40
41
The argument, if present in the command line, will prevent the intended
42
command from taking place. Instead, it will generate a JSON skeleton and
43
print it to standard output.
44
"""
45
ARG_DATA = {
46
'name': 'generate-cli-skeleton',
47
'help_text': (
48
'Prints a JSON skeleton to standard output without sending '
49
'an API request. If provided with no value or the value '
50
'``input``, prints a sample input JSON that can be used as an '
51
'argument for ``--cli-input-json``. If provided with the value '
52
'``output``, it validates the command inputs and returns a '
53
'sample output JSON for that command.'
54
),
55
'nargs': '?',
56
'const': 'input',
57
'choices': ['input', 'output'],
58
}
59
60
def __init__(self, session, operation_model):
61
super(GenerateCliSkeletonArgument, self).__init__(session)
62
self._operation_model = operation_model
63
64
def _register_argument_action(self):
65
self._session.register(
66
'calling-command.*', self.generate_json_skeleton)
67
super(GenerateCliSkeletonArgument, self)._register_argument_action()
68
69
def override_required_args(self, argument_table, args, **kwargs):
70
arg_name = '--' + self.name
71
if arg_name in args:
72
arg_location = args.index(arg_name)
73
try:
74
# If the value of --generate-cli-skeleton is ``output``,
75
# do not force required arguments to be optional as
76
# ``--generate-cli-skeleton output`` validates commands
77
# as well as print out the sample output.
78
if args[arg_location + 1] == 'output':
79
return
80
except IndexError:
81
pass
82
super(GenerateCliSkeletonArgument, self).override_required_args(
83
argument_table, args, **kwargs)
84
85
def generate_json_skeleton(self, call_parameters, parsed_args,
86
parsed_globals, **kwargs):
87
if getattr(parsed_args, 'generate_cli_skeleton', None):
88
for_output = parsed_args.generate_cli_skeleton == 'output'
89
operation_model = self._operation_model
90
91
if for_output:
92
service_name = operation_model.service_model.service_name
93
operation_name = operation_model.name
94
# TODO: It would be better to abstract this logic into
95
# classes for both the input and output option such that
96
# a similar set of inputs are taken in and output
97
# similar functionality.
98
return StubbedCLIOperationCaller(self._session).invoke(
99
service_name, operation_name, call_parameters,
100
parsed_globals)
101
else:
102
argument_generator = ArgumentGenerator()
103
operation_input_shape = operation_model.input_shape
104
if operation_input_shape is None:
105
skeleton = {}
106
else:
107
skeleton = argument_generator.generate_skeleton(
108
operation_input_shape)
109
110
sys.stdout.write(
111
json.dumps(skeleton, indent=4, default=json_encoder)
112
)
113
sys.stdout.write('\n')
114
return 0
115
116
117
class StubbedCLIOperationCaller(CLIOperationCaller):
118
"""A stubbed CLIOperationCaller
119
120
It generates a fake response and uses the response and provided parameters
121
to make a stubbed client call for an operation command.
122
"""
123
def _make_client_call(self, client, operation_name, parameters,
124
parsed_globals):
125
method_name = xform_name(operation_name)
126
operation_model = client.meta.service_model.operation_model(
127
operation_name)
128
fake_response = {}
129
if operation_model.output_shape:
130
argument_generator = ArgumentGenerator(use_member_names=True)
131
fake_response = argument_generator.generate_skeleton(
132
operation_model.output_shape)
133
with Stubber(client) as stubber:
134
stubber.add_response(method_name, fake_response)
135
return getattr(client, method_name)(**parameters)
136
137