def validate_instance_name(params): if params.instance_name: if not re.match(INSTANCE_NAME_PATTERN, params.instance_name): raise ParamValidationError( 'Instance name contains invalid characters.') if params.instance_name.startswith('i-'): raise ParamValidationError( 'Instance name cannot start with \'i-\'.') if len(params.instance_name) > MAX_INSTANCE_NAME_LENGTH: raise ParamValidationError( 'Instance name cannot be longer than {0} characters.'.format( MAX_INSTANCE_NAME_LENGTH))
def _check_for_supported_apps(self, parsed_applications): for app_config in parsed_applications: app_name = app_config['Name'].upper() if app_name in constants.APPLICATIONS: if app_name not in self.supported_apps: raise ParamValidationError( "aws: error: " + app_config['Name'] + " cannot be" " installed on a running cluster. 'Name' should be one" " of the following: " + ', '.join(self.supported_apps)) else: raise ParamValidationError( "aws: error: Unknown application: " + app_config['Name'] + ". 'Name' should be one of the following: " + ', '.join(constants.APPLICATIONS))
def validate_tags(params): if params.tags: if len(params.tags) > MAX_TAGS_PER_INSTANCE: raise ParamValidationError( 'Instances can only have a maximum of {0} tags.'.format( MAX_TAGS_PER_INSTANCE)) for tag in params.tags: if len(tag['Key']) > MAX_TAG_KEY_LENGTH: raise ParamValidationError( 'Tag Key cannot be longer than {0} characters.'.format( MAX_TAG_KEY_LENGTH)) if len(tag['Value']) > MAX_TAG_VALUE_LENGTH: raise ParamValidationError( 'Tag Value cannot be longer than {0} characters.'.format( MAX_TAG_VALUE_LENGTH))
def add_to_params(self, parameters, value): if value is None: return if parameters.get('parameterValues', None) is not None: raise ParamValidationError( "Only parameter-values or parameter-values-uri is allowed") parameter_object = {} # break string into = point for argument in value: try: argument_components = argument.split('=', 1) key = argument_components[0] value = argument_components[1] if key in parameter_object: if isinstance(parameter_object[key], list): parameter_object[key].append(value) else: parameter_object[key] = [parameter_object[key], value] else: parameter_object[key] = value except IndexError: raise ParameterDefinitionError( "Invalid inline parameter format: %s" % argument) parsed = {'values': parameter_object} parameter_values = translator.definition_to_parameter_values(parsed) parameters['parameterValues'] = parameter_values
def _check_type(self, type): type = type.lower() if type != constants.FULL and type != constants.INCREMENTAL: raise ParamValidationError('aws: error: invalid type. ' 'type should be either ' + constants.FULL + ' or ' + constants.INCREMENTAL + '.')
def add_to_params(self, parameters, value): if value: try: int_value = int(value) if (int_value < 0 or int_value > 255) and int_value != -1: msg = ('protocol numbers must be in the range 0-255 ' 'or -1 to specify all protocols') raise ParamValidationError(msg) except ValueError: if value not in ('tcp', 'udp', 'icmp', 'all'): msg = ('protocol parameter should be one of: ' 'tcp|udp|icmp|all or any valid protocol number.') raise ParamValidationError(msg) if value == 'all': value = '-1' _build_ip_permissions(parameters, 'IpProtocol', value)
def _resolve_query(value): try: return jmespath.compile(value) except Exception as e: raise ParamValidationError( "Bad value for --query %s: %s" % (value, str(e)) )
def validate_boolean_mutex_groups(boolean_pairs, parsed_args, **kwargs): # Validate we didn't pass in an --option and a --no-option. for positive, negative in boolean_pairs: if getattr(parsed_args, positive.py_name) is not _NOT_SPECIFIED and \ getattr(parsed_args, negative.py_name) is not _NOT_SPECIFIED: raise ParamValidationError( 'Cannot specify both the "%s" option and ' 'the "%s" option.' % (positive.cli_name, negative.cli_name))
def assert_cloudtrail_arn_is_valid(trail_arn): """Ensures that the arn looks correct. ARNs look like: arn:aws:cloudtrail:us-east-1:123456789012:trail/foo""" pattern = re.compile('arn:.+:cloudtrail:.+:\d{12}:trail/.+') if not pattern.match(trail_arn): raise ParamValidationError('Invalid trail ARN provided: %s' % trail_arn)
def resolve_given_outfile_path(path): """Asserts that a path is writable and returns the expanded path""" if path is None: return outfile = os.path.expanduser(os.path.expandvars(path)) if not os.access(os.path.dirname(os.path.abspath(outfile)), os.W_OK): raise ParamValidationError('Unable to write to file: %s' % outfile) return outfile
def _check_unit(self, unit): unit = unit.lower() if (unit != constants.MINUTES and unit != constants.HOURS and unit != constants.DAYS): raise ParamValidationError( 'aws: error: invalid unit. unit should be one of' ' the following values: ' + constants.MINUTES + ', ' + constants.HOURS + ' or ' + constants.DAYS + '.')
def _set_grant_params(cls, request_params, cli_params): if cli_params.get('grants'): for grant in cli_params['grants']: try: permission, grantee = grant.split('=', 1) except ValueError: raise ParamValidationError( 'grants should be of the form permission=principal') request_params[cls._permission_to_param(permission)] = grantee
def _resolve_endpoint_url(value): parsed = urlparse.urlparse(value) # Our http library requires you specify an endpoint url # that contains a scheme, so we'll verify that up front. if not parsed.scheme: raise ParamValidationError( 'Bad value for --endpoint-url "%s": scheme is ' 'missing. Must be of the form ' 'http://<hostname>/ or https://<hostname>/' % value ) return value
def _permission_to_param(cls, permission): if permission == 'read': return 'GrantRead' if permission == 'full': return 'GrantFullControl' if permission == 'readacl': return 'GrantReadACP' if permission == 'writeacl': return 'GrantWriteACP' raise ParamValidationError( 'permission must be one of: read|readacl|writeacl|full')
def apply_boolean_options(true_option, true_option_name, false_option, false_option_name): if true_option and false_option: error_message = \ 'aws: error: cannot use both ' + true_option_name + \ ' and ' + false_option_name + ' options together.' raise ParamValidationError(error_message) elif true_option: return True else: return False
def _check_args(parsed_args, **kwargs): # This function checks the parsed args. If the user specified # the --ip-permissions option with any of the scalar options we # raise an error. arg_dict = vars(parsed_args) if arg_dict['ip_permissions']: for key in ('protocol', 'port', 'cidr', 'source_group', 'group_owner'): if arg_dict[key]: msg = ('The --%s option is not compatible ' 'with the --ip-permissions option ') % key raise ParamValidationError(msg)
def _put(self, parsed_args): items = self._get_items(parsed_args) # batch write does not support condition expressions, so if we use # that then we just have to call put_item for each item. if len(items) > 1 and parsed_args.condition is None: self._batch_write(items, parsed_args) else: if len(items) > 1: raise ParamValidationError( '--condition is not supported for multiple items') self._put_item(items, parsed_args)
def add_to_params(self, parameters, value): if value is None: return if parameters.get('parameterValues', None) is not None: raise ParamValidationError( "Only parameter-values or parameter-values-uri is allowed") parsed = json.loads(value) parameter_values = translator.definition_to_parameter_values(parsed) parameters['parameterValues'] = parameter_values
def _should_contain_zip_content(value): if not isinstance(value, bytes): # If it's not bytes it's basically impossible for # this to be valid zip content, but we'll at least # still try to load the contents as a zip file # to be absolutely sure. value = value.encode('utf-8') fileobj = six.BytesIO(value) try: with closing(zipfile.ZipFile(fileobj)) as f: f.infolist() except zipfile.BadZipfile: raise ParamValidationError(ERROR_MSG)
def build_revision_location(self, value_dict): required = ['repository', 'commitId'] valid = lambda k: value_dict.get(k, False) if not all(map(valid, required)): raise ParamValidationError( '--github-location must specify repository and commitId.') return { "revisionType": "GitHub", "gitHubLocation": { "repository": value_dict['repository'], "commitId": value_dict['commitId'] } }
def validate_s3_location(params, arg_name): arg_name = arg_name.replace('-', '_') if arg_name in params: s3_location = getattr(params, arg_name) if s3_location: matcher = re.match('s3://(.+?)/(.+)', str(s3_location)) if matcher: params.bucket = matcher.group(1) params.key = matcher.group(2) else: raise ParamValidationError( '--{0} must specify the Amazon S3 URL format as ' 's3://<bucket>/<key>.'.format(arg_name.replace('_', '-')))
def add_to_params(self, parameters, value): if value is None: return unpacked = self._unpack_argument(value) if 'File' in unpacked: raise ParamValidationError( "File cannot be provided as part of the '--terminology-data' " "argument. Please use the '--data-file' option instead to " "specify a file.") if parameters.get('TerminologyData'): parameters['TerminologyData'].update(unpacked) else: parameters['TerminologyData'] = unpacked
def build_applications(region, parsed_applications, ami_version=None): app_list = [] step_list = [] ba_list = [] for app_config in parsed_applications: app_name = app_config['Name'].lower() if app_name == constants.HIVE: hive_version = constants.LATEST step_list.append(_build_install_hive_step(region=region)) args = app_config.get('Args') if args is not None: hive_site_path = _find_matching_arg( key=constants.HIVE_SITE_KEY, args_list=args) if hive_site_path is not None: step_list.append( _build_install_hive_site_step( region=region, hive_site_path=hive_site_path)) elif app_name == constants.PIG: pig_version = constants.LATEST step_list.append(_build_pig_install_step(region=region)) elif app_name == constants.GANGLIA: ba_list.append( _build_ganglia_install_bootstrap_action(region=region)) elif app_name == constants.HBASE: ba_list.append( _build_hbase_install_bootstrap_action(region=region)) if ami_version >= '3.0': step_list.append( _build_hbase_install_step( constants.HBASE_PATH_HADOOP2_INSTALL_JAR)) elif ami_version >= '2.1': step_list.append( _build_hbase_install_step( constants.HBASE_PATH_HADOOP1_INSTALL_JAR)) else: raise ParamValidationError('aws: error: AMI version %s is not ' 'compatible with HBase.' % ami_version) elif app_name == constants.IMPALA: ba_list.append( _build_impala_install_bootstrap_action( region=region, args=app_config.get('Args'))) else: app_list.append( _build_supported_product(app_config['Name'], app_config.get('Args'))) return app_list, ba_list, step_list
def add_to_params(self, parameters, value): if value is None: return unpacked = self._unpack_argument(value) if 'ZipFile' in unpacked: raise ParamValidationError( "ZipFile cannot be provided " "as part of the %s argument. " "Please use the '--zip-file' " "option instead to specify a zip file." % self._cli_name) if parameters.get(self._param_to_replace): parameters[self._param_to_replace].update(unpacked) else: parameters[self._param_to_replace] = unpacked
def _check_args(parsed_args, **kwargs): # This function checks the parsed args. If the user specified # the --ip-permissions option with any of the scalar options we # raise an error. logger.debug(parsed_args) arg_dict = vars(parsed_args) if arg_dict['storage']: for key in ('bucket', 'prefix', 'owner_akid', 'owner_sak', 'policy'): if arg_dict[key]: msg = ('Mixing the --storage option ' 'with the simple, scalar options is ' 'not recommended.') raise ParamValidationError(msg)
def _check_args(parsed_args, **kwargs): # This function checks the parsed args. If the user specified # the --network-interfaces option with any of the scalar options we # raise an error. arg_dict = vars(parsed_args) if arg_dict['network_interfaces']: for key in ('secondary_private_ip_addresses', 'secondary_private_ip_address_count', 'associate_public_ip_address'): if arg_dict[key]: msg = ('Mixing the --network-interfaces option ' 'with the simple, scalar options is ' 'not supported.') raise ParamValidationError(msg)
def ensure_paging_params_not_set(parsed_args, shadowed_args): paging_params = ['starting_token', 'page_size', 'max_items'] shadowed_params = [p.replace('-', '_') for p in shadowed_args.keys()] params_used = [ p for p in paging_params if p not in shadowed_params and getattr(parsed_args, p, None) ] if len(params_used) > 0: converted_params = ', '.join( ["--" + p.replace('_', '-') for p in params_used]) raise ParamValidationError( "Cannot specify --no-paginate along with pagination " "arguments: %s" % converted_params)
def _build_hbase_disable_backups_args(self, parsed_args): args = [ constants.HBASE_MAIN, constants.HBASE_SCHEDULED_BACKUP, constants.FALSE ] if parsed_args.full is False and parsed_args.incremental is False: error_message = 'Should specify at least one of --' +\ constants.FULL + ' and --' +\ constants.INCREMENTAL + '.' raise ParamValidationError(error_message) if parsed_args.full is True: args.append(constants.HBASE_DISABLE_FULL_BACKUP) if parsed_args.incremental is True: args.append(constants.HBASE_DISABLE_INCREMENTAL_BACKUP) return args
def _dump_yaml(self, operation_name, data, parsed_globals): if parsed_globals.output == 'yaml-stream': # TODO: In the future, we should support yaml-stream. However, it # would require a larger refactoring. Right now we always build # the full result when paginating prior to sending it to the # formatter. We need to instead pass the page iterator and # deserialize in the formatter. We cannot necessarily just # convert these to client handlers because the DDB types we # introduce do not play nicely with the pagination interfaces. # For example, botocore cannot serialize our Binary types into # a resume token when --max-items gets set. raise ParamValidationError( 'yaml-stream output format is not supported for ddb commands') formatter = YAMLFormatter(parsed_globals, DynamoYAMLDumper()) with self._output_stream_factory.get_output_stream() as stream: formatter(operation_name, data, stream)
def build_revision_location(self, value_dict): required = ['bucket', 'key', 'bundleType'] valid = lambda k: value_dict.get(k, False) if not all(map(valid, required)): raise ParamValidationError( '--s3-location must specify bucket, key and bundleType.') revision = { "revisionType": "S3", "s3Location": { "bucket": value_dict['bucket'], "key": value_dict['key'], "bundleType": value_dict['bundleType'] } } if 'eTag' in value_dict: revision['s3Location']['eTag'] = value_dict['eTag'] if 'version' in value_dict: revision['s3Location']['version'] = value_dict['version'] return revision