|
| 1 | +#!/usr/bin/env python |
| 2 | +# Licensed to Cloudera, Inc. under one |
| 3 | +# or more contributor license agreements. See the NOTICE file |
| 4 | +# distributed with this work for additional information |
| 5 | +# regarding copyright ownership. Cloudera, Inc. licenses this file |
| 6 | +# to you under the Apache License, Version 2.0 (the |
| 7 | +# "License"); you may not use this file except in compliance |
| 8 | +# with the License. You may obtain a copy of the License at |
| 9 | +# |
| 10 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 11 | +# |
| 12 | +# Unless required by applicable law or agreed to in writing, software |
| 13 | +# distributed under the License is distributed on an "AS IS" BASIS, |
| 14 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 15 | +# See the License for the specific language governing permissions and |
| 16 | +# limitations under the License. |
| 17 | +""" |
| 18 | +usage: aws.py [-h] -H HOSTNAME [-p PORT] [-u USERNAME] [--password PASSWORD] |
| 19 | + [--api-version API_VERSION] [--tls] [-c] [-t CATEGORY_NAME] |
| 20 | + [-n TYPE_NAME] [--prune CREDENTIAL_NAME] [--version] |
| 21 | +
|
| 22 | +A utility to interact with AWS using Cloudera Manager. |
| 23 | +
|
| 24 | +optional arguments: |
| 25 | + -h, --help show this help message and exit |
| 26 | + -H HOSTNAME, --hostname HOSTNAME |
| 27 | + The hostname of the Cloudera Manager server. |
| 28 | + -p PORT The port of the Cloudera Manager server. Defaults to |
| 29 | + 7180 (http) or 7183 (https). |
| 30 | + -u USERNAME, --username USERNAME |
| 31 | + Login name. |
| 32 | + --password PASSWORD Login password. |
| 33 | + --api-version API_VERSION |
| 34 | + API version to be used. Defaults to 16. |
| 35 | + --tls Whether to use tls (https). |
| 36 | + -c, --show-categories |
| 37 | + Prints a list of supported external account category |
| 38 | + names. For example, "AWS" is a supported external |
| 39 | + account category name. |
| 40 | + -t CATEGORY_NAME, --show-types CATEGORY_NAME |
| 41 | + Prints a list of supported external account type names |
| 42 | + for the given CATEGORY_NAME. For example, |
| 43 | + "AWS_ACCESS_KEY_AUTH" is a supported external account |
| 44 | + type name for external account category "AWS". |
| 45 | + -n TYPE_NAME, --show-credentials TYPE_NAME |
| 46 | + Prints a list of available credential names for the |
| 47 | + given TYPE_NAME. |
| 48 | + --prune CREDENTIAL_NAME |
| 49 | + Runs S3Guard prune command on external account |
| 50 | + associated with the given CREDENTIAL_NAME. |
| 51 | + --version show program's version number and exit |
| 52 | +""" |
| 53 | +import argparse |
| 54 | +import getpass |
| 55 | +import logging |
| 56 | +import sys |
| 57 | + |
| 58 | +from cm_api.api_client import ApiResource |
| 59 | +from cm_api.endpoints.external_accounts import * |
| 60 | + |
| 61 | +# Configuration |
| 62 | +DEFAULT_HTTP_PORT = 7180 |
| 63 | +DEFAULT_HTTPS_PORT = 7183 |
| 64 | +MINIMUM_SUPPORTED_API_VERSION = 16 |
| 65 | + |
| 66 | +# Constants |
| 67 | +COMMA_WITH_SPACE = ", " |
| 68 | + |
| 69 | +# Global API object |
| 70 | +api = None |
| 71 | + |
| 72 | + |
| 73 | +def list_supported_categories(): |
| 74 | + """ |
| 75 | + Prints a list of supported external account category names. |
| 76 | + For example, "AWS" is a supported external account category name. |
| 77 | + """ |
| 78 | + categories = get_supported_categories(api) |
| 79 | + category_names = [category.name for category in categories] |
| 80 | + print ("Supported account categories by name: {0}".format( |
| 81 | + COMMA_WITH_SPACE.join(map(str, category_names)))) |
| 82 | + |
| 83 | + |
| 84 | +def list_supported_types(category_name): |
| 85 | + """ |
| 86 | + Prints a list of supported external account type names for the given |
| 87 | + category_name. For example, "AWS_ACCESS_KEY_AUTH" is a supported external |
| 88 | + account type name for external account category "AWS". |
| 89 | + """ |
| 90 | + types = get_supported_types(api, category_name) |
| 91 | + type_names = [type.name for type in types] |
| 92 | + print ("Supported account types by name for '{0}': [{1}]".format( |
| 93 | + category_name, COMMA_WITH_SPACE.join(map(str, type_names)))) |
| 94 | + |
| 95 | + |
| 96 | +def list_credentials_by_name(type_name): |
| 97 | + """ |
| 98 | + Prints a list of available credential names for the given type_name. |
| 99 | + """ |
| 100 | + accounts = get_all_external_accounts(api, type_name) |
| 101 | + account_names = [account.name for account in accounts] |
| 102 | + print ("List of credential names for '{0}': [{1}]".format( |
| 103 | + type_name, COMMA_WITH_SPACE.join(map(str, account_names)))) |
| 104 | + |
| 105 | + |
| 106 | +def call_s3guard_prune(credential_name): |
| 107 | + """ |
| 108 | + Runs S3Guard prune command on external account associated with the |
| 109 | + given credential_name. |
| 110 | + """ # Get the AWS credential account associated with the credential |
| 111 | + account = get_external_account(api, credential_name) |
| 112 | + # Invoke the prune command for the account by its name |
| 113 | + cmd = account.external_account_cmd_by_name('S3GuardPrune') |
| 114 | + print ("Issued '{0}' command with id '{1}'".format(cmd.name, cmd.id)) |
| 115 | + print ("Waiting for command {0} to finish...".format(cmd.id)) |
| 116 | + cmd = cmd.wait() |
| 117 | + print ("Command succeeded: {0}".format(cmd.success)) |
| 118 | + |
| 119 | + |
| 120 | +def setup_logging(level): |
| 121 | + """ |
| 122 | + Sets up the logging for the script. The default logging level |
| 123 | + is set to INFO. |
| 124 | + """ |
| 125 | + logging.basicConfig() |
| 126 | + logging.getLogger().setLevel(level) |
| 127 | + |
| 128 | + |
| 129 | +def initialize_api(args): |
| 130 | + """ |
| 131 | + Initializes the global API instance using the given arguments. |
| 132 | + @param args: arguments provided to the script. |
| 133 | + """ |
| 134 | + global api |
| 135 | + api = ApiResource(server_host=args.hostname, server_port=args.port, |
| 136 | + username=args.username, password=args.password, |
| 137 | + version=args.api_version, use_tls=args.use_tls) |
| 138 | + |
| 139 | + |
| 140 | +def validate_api_compatibility(args): |
| 141 | + """ |
| 142 | + Validates the API version. |
| 143 | + @param args: arguments provided to the script. |
| 144 | + """ |
| 145 | + if args.api_version and args.api_version < MINIMUM_SUPPORTED_API_VERSION: |
| 146 | + print("ERROR: Given API version: {0}. Minimum supported API version: {1}" |
| 147 | + .format(args.api_version, MINIMUM_SUPPORTED_API_VERSION)) |
| 148 | + |
| 149 | + |
| 150 | +def get_login_credentials(args): |
| 151 | + """ |
| 152 | + Gets the login credentials from the user, if not specified while invoking |
| 153 | + the script. |
| 154 | + @param args: arguments provided to the script. |
| 155 | + """ |
| 156 | + if not args.username: |
| 157 | + args.username = raw_input("Enter Username: ") |
| 158 | + if not args.password: |
| 159 | + args.password = getpass.getpass("Enter Password: ") |
| 160 | + |
| 161 | + |
| 162 | +def main(): |
| 163 | + """ |
| 164 | + The "main" entry that controls the flow of the script based |
| 165 | + on the provided arguments. |
| 166 | + """ |
| 167 | + setup_logging(logging.INFO) |
| 168 | + |
| 169 | + # Parse arguments |
| 170 | + parser = argparse.ArgumentParser( |
| 171 | + description="A utility to interact with AWS using Cloudera Manager.") |
| 172 | + parser.add_argument('-H', '--hostname', action='store', dest='hostname', |
| 173 | + required=True, |
| 174 | + help='The hostname of the Cloudera Manager server.') |
| 175 | + parser.add_argument('-p', action='store', dest='port', type=int, |
| 176 | + help='The port of the Cloudera Manager server. Defaults ' |
| 177 | + 'to 7180 (http) or 7183 (https).') |
| 178 | + parser.add_argument('-u', '--username', action='store', dest='username', |
| 179 | + help='Login name.') |
| 180 | + parser.add_argument('--password', action='store', dest='password', |
| 181 | + help='Login password.') |
| 182 | + parser.add_argument('--api-version', action='store', dest='api_version', |
| 183 | + type=int, |
| 184 | + default=MINIMUM_SUPPORTED_API_VERSION, |
| 185 | + help='API version to be used. Defaults to {0}.'.format( |
| 186 | + MINIMUM_SUPPORTED_API_VERSION)) |
| 187 | + parser.add_argument('--tls', action='store_const', dest='use_tls', |
| 188 | + const=True, default=False, |
| 189 | + help='Whether to use tls (https).') |
| 190 | + parser.add_argument('-c', '--show-categories', action='store_true', |
| 191 | + default=False, dest='show_categories', |
| 192 | + help='Prints a list of supported external account ' |
| 193 | + 'category names. For example, "AWS" is a supported ' |
| 194 | + 'external account category name.') |
| 195 | + parser.add_argument('-t', '--show-types', action='store', |
| 196 | + dest='category_name', |
| 197 | + help='Prints a list of supported external account type ' |
| 198 | + 'names for the given CATEGORY_NAME. For example, ' |
| 199 | + '"AWS_ACCESS_KEY_AUTH" is a supported external ' |
| 200 | + 'account type name for external account category ' |
| 201 | + '"AWS".') |
| 202 | + parser.add_argument('-n', '--show-credentials', action='store', |
| 203 | + dest='type_name', |
| 204 | + help='Prints a list of available credential names for ' |
| 205 | + 'the given TYPE_NAME.') |
| 206 | + parser.add_argument('--prune', action='store', dest='credential_name', |
| 207 | + help='Runs S3Guard prune command on external account ' |
| 208 | + 'associated with the given CREDENTIAL_NAME.') |
| 209 | + parser.add_argument('--version', action='version', version='%(prog)s 1.0') |
| 210 | + args = parser.parse_args() |
| 211 | + |
| 212 | + # Use the default port if required. |
| 213 | + if not args.port: |
| 214 | + if args.use_tls: |
| 215 | + args.port = DEFAULT_HTTPS_PORT |
| 216 | + else: |
| 217 | + args.port = DEFAULT_HTTP_PORT |
| 218 | + |
| 219 | + validate_api_compatibility(args) |
| 220 | + get_login_credentials(args) |
| 221 | + initialize_api(args) |
| 222 | + |
| 223 | + # Perform the AWS operation based on the input arguments. |
| 224 | + if args.show_categories: |
| 225 | + list_supported_categories() |
| 226 | + elif args.category_name: |
| 227 | + list_supported_types(args.category_name) |
| 228 | + elif args.type_name: |
| 229 | + list_credentials_by_name(args.type_name) |
| 230 | + elif args.credential_name: |
| 231 | + call_s3guard_prune(args.credential_name) |
| 232 | + else: |
| 233 | + print ("ERROR: No arguments given to perform any AWS operation.") |
| 234 | + parser.print_help() |
| 235 | + sys.exit(1) |
| 236 | + |
| 237 | + |
| 238 | +""" |
| 239 | +The "main" entry. |
| 240 | +""" |
| 241 | +if __name__ == "__main__": |
| 242 | + sys.exit(main()) |
0 commit comments