#!/usr/bin/python3 # ============================================================================== # Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== import cfnbootstrap from cfnbootstrap.cfn_client import CloudFormationClient from optparse import OptionParser from cfnbootstrap import util import sys import json parser = OptionParser() parser.add_option_group(util.get_cred_options(parser)) parser.add_option_group(util.get_proxy_options(parser)) parser.add_option("-s", "--stack", help="A CloudFormation stack", type="string", dest="stack_name") parser.add_option("-r", "--resource", help="A CloudFormation logical resource ID", type="string", dest="logical_resource_id") parser.add_option("-k", "--key", help="Retrieve the value at in the Metadata object; must be in dotted object notation (parent.child.leaf)", type="string", dest="key") parser.add_option("-u", "--url", help="The CloudFormation service URL. The endpoint URL must match the region option. Use of this parameter is discouraged.", type="string", dest="endpoint") parser.add_option("", "--region", help="The CloudFormation region. Default: us-east-1.", type="string", dest="region", default="us-east-1") parser.add_option("-v", "--verbose", help="Enables verbose logging", action="store_true", dest="verbose") (options, args) = parser.parse_args() if not options.stack_name or not options.logical_resource_id: print("Error: You must specify both a stack name and logical resource id", file=sys.stderr) parser.print_help(sys.stderr) sys.exit(1) cfnbootstrap.configureLogging("DEBUG" if options.verbose else "INFO") creds = util.get_creds_or_die(options) url = CloudFormationClient.endpointForRegion(options.region) if options.endpoint: url = options.endpoint client = CloudFormationClient( creds, url=url, region=options.region, proxyinfo=util.get_proxyinfo(options)) try: detail = client.describe_stack_resource( options.logical_resource_id, options.stack_name) except IOError as e: if e.strerror: print(e.strerror, file=sys.stderr) else: print("Unknown error retrieving {}".format( options.logical_resource_id), file=sys.stderr) sys.exit(1) if not detail.metadata: print("Error: {} does not specify any metadata".format( detail.logicalResourceId), file=sys.stderr) sys.exit(1) metadata_to_dump = detail.metadata if options.key: metadata_to_dump = util.extract_value(metadata_to_dump, options.key) if not metadata_to_dump: print("Error: %s is not present in the metadata for %s".format( options.key, detail.logicalResourceId), file=sys.stderr) sys.exit(1) if isinstance(metadata_to_dump, str): print(metadata_to_dump, file=sys.stdout) else: json.dump(metadata_to_dump, sys.stdout, indent=4) # This removes the annoying no-EOL symbols from some consoles, as json.dump does not end with a newline print("", file=sys.stdout)