def __init__(self, resource_type, extra_fields=(), include_default_fields=True, include_region=False, include_policy=False, fields=()): # Lookup default fields for resource type. model = resource_type self._id_field = model.id self._date_field = getattr(model, 'date', None) fields = OrderedDict(fields) mfields = getattr(model, 'default_report_fields', None) if mfields is None: mfields = [model.id] if model.name != model.id: mfields.append(model.name) if getattr(model, 'date', None): mfields.append(model.date) if include_default_fields: fields.update(OrderedDict(zip(mfields, mfields))) for index, field in enumerate(extra_fields): # TODO this type coercion should be done at cli input, not here h, cexpr = field.split('=', 1) fields[h] = cexpr # Add these at the end so that they are the last fields if include_default_fields: if include_region: fields['Region'] = 'region' if include_policy: fields['Policy'] = 'policy' self.fields = fields
def _build_subcommand_table(self): subcommand_table = OrderedDict() for subcommand in self.SUBCOMMANDS: subcommand_name = subcommand['name'] subcommand_class = subcommand['command_class'] subcommand_table[subcommand_name] = subcommand_class(self._session) self._session.emit('building-command-table.%s' % self.NAME, command_table=subcommand_table, session=self._session) return subcommand_table
def build_policy(self, resource, date_less_than, date_greater_than=None, ip_address=None): """A helper to build policy. :type resource: str :param resource: The URL or the stream filename of the protected object :type date_less_than: datetime :param date_less_than: The URL will expire after the time has passed :type date_greater_than: datetime :param date_greater_than: The URL will not be valid until this time :type ip_address: str :param ip_address: Use 'x.x.x.x' for an IP, or 'x.x.x.x/x' for a subnet :rtype: str :return: The policy in a compact string. """ # Note: # 1. Order in canned policy is significant. Special care has been taken # to ensure the output will match the order defined by the document. # There is also a test case to ensure that order. # SEE: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-canned-policy.html#private-content-canned-policy-creating-policy-statement # 2. Albeit the order in custom policy is not required by CloudFront, # we still use OrderedDict internally to ensure the result is stable # and also matches canned policy requirement. # SEE: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-custom-policy.html moment = int(datetime2timestamp(date_less_than)) condition = OrderedDict({"DateLessThan": {"AWS:EpochTime": moment}}) if ip_address: if '/' not in ip_address: ip_address += '/32' condition["IpAddress"] = {"AWS:SourceIp": ip_address} if date_greater_than: moment = int(datetime2timestamp(date_greater_than)) condition["DateGreaterThan"] = {"AWS:EpochTime": moment} ordered_payload = [('Resource', resource), ('Condition', condition)] custom_policy = {"Statement": [OrderedDict(ordered_payload)]} return json.dumps(custom_policy, separators=(',', ':'))
def test_profile(self): self._session.profile = "profile" self._correct_user_entry["user"]["exec"]["env"] = [ OrderedDict([("name", "AWS_PROFILE"), ("value", "profile")]) ] self.assertEqual(self._client.get_user_entry(), self._correct_user_entry) self._mock_client.describe_cluster.assert_called_once_with( name="ExampleCluster") self._session.create_client.assert_called_once_with("eks")
def _build_structure(self, model, shapes): members = OrderedDict() shape = self._build_initial_shape(model) shape['members'] = members for name, member_model in model['members'].items(): member_shape_name = self._get_shape_name(member_model) members[name] = {'shape': member_shape_name} self._build_model(member_model, shapes, member_shape_name) return shape
def test_list_objects_unicode_query_string_eu_central_1(self): self.region_name = 'eu-central-1' params = OrderedDict([('Bucket', 'safename'), ('Marker', u'\xe4\xf6\xfc-01.txt')]) prepared_request = self.get_prepared_request('list_objects', params) self.assertEqual( prepared_request.url, ('https://safename.s3.eu-central-1.amazonaws.com/' '?marker=%C3%A4%C3%B6%C3%BC-01.txt') )
def __init__(self, resource): self._resource = resource self._client = self._resource.meta.client self._resource_model = self._resource.meta.resource_model self._service_model = self._client.meta.service_model self._resource_name = self._resource.meta.resource_model.name self._service_name = self._service_model.service_name self._service_docs_name = self._client.__class__.__name__ self.member_map = OrderedDict() self.represents_service_resource = ( self._service_name == self._resource_name)
def _create_command_table(self): command_table = OrderedDict() service_object = self._get_service_object() for operation_object in service_object.operations: cli_name = xform_name(operation_object.name, '-') command_table[cli_name] = ServiceOperation( name=cli_name, operation_object=operation_object, operation_caller=CLIOperationCaller(self.session), service_object=service_object) return command_table
def test_key_not_array(self): initial = OrderedDict([ ("apiVersion", "v1"), ("contexts", []), ("current-context", None), ("kind", "Config"), ("preferences", OrderedDict()), ("users", []) ]) cluster = OrderedDict([ ("cluster", OrderedDict([ ("certificate-authority-data", "data"), ("server", "endpoint") ])), ("name", "clustername") ]) self.assertRaises(KubeconfigError, self._appender.insert_entry, Kubeconfig(None, initial), "kind", cluster)
def arg_table(self): arg_table = OrderedDict() for arg_data in self.ARG_TABLE: custom_argument = CustomArgument(**arg_data) # If a custom schema was passed in, create the argument object # so that it can be validated and docs can be generated if 'schema' in arg_data: custom_argument.create_argument_object() arg_table[arg_data['name']] = custom_argument return arg_table
def __init__(self, resource_manager, extra_fields=(), include_default_fields=True, include_region=False, include_policy=False): self.resource_manager = resource_manager # Lookup default fields for resource type. model = resource_manager.resource_type self._id_field = model.id self._date_field = getattr(model, 'date', None) mfields = getattr(model, 'default_report_fields', None) if mfields is None: mfields = [model.id] if model.name != model.id: mfields.append(model.name) if getattr(model, 'date', None): mfields.append(model.date) if include_default_fields: fields = OrderedDict(zip(mfields, mfields)) else: fields = OrderedDict() for index, field in enumerate(extra_fields): # TODO this type coercion should be done at cli input, not here h, cexpr = field.split('=', 1) fields[h] = cexpr # Add these at the end so that they are the last fields if include_default_fields: if include_region: fields['Region'] = 'region' if include_policy: fields['Policy'] = 'policy' self.fields = fields
def get_user_entry(self): """ Return a user entry generated using the previously obtained description. """ region = self._get_cluster_description().get("arn").split(":")[3] generated_user = OrderedDict([ ("name", self._get_cluster_description().get("arn", "")), ("user", OrderedDict([ ("exec", OrderedDict([ ("apiVersion", API_VERSION), ("args", [ "--region", region, "eks", "get-token", "--cluster-name", self._cluster_name, ]), ("command", "aws") ])) ])) ]) if self._role_arn is not None: generated_user["user"]["exec"]["args"].extend([ "--role", self._role_arn ]) if self._session.profile: generated_user["user"]["exec"]["env"] = [OrderedDict([ ("name", "AWS_PROFILE"), ("value", self._session.profile) ])] return generated_user
def _build_argument_table(self): argument_table = OrderedDict() cli_data = self._get_cli_data() cli_arguments = cli_data.get('options', None) for option in cli_arguments: option_params = copy_kwargs(cli_arguments[option]) cli_argument = self._create_cli_argument(option, option_params) cli_argument.add_to_arg_table(argument_table) # Then the final step is to send out an event so handlers # can add extra arguments or modify existing arguments. self.session.emit('building-top-level-params', argument_table=argument_table) return argument_table
def test_parse_yaml_preserve_elements_order(self): input_template = ( 'B_Resource:\n' ' Key2:\n' ' Name: name2\n' ' Key1:\n' ' Name: name1\n' 'A_Resource:\n' ' Key2:\n' ' Name: name2\n' ' Key1:\n' ' Name: name1\n' ) output_dict = yaml_parse(input_template) expected_dict = OrderedDict([ ('B_Resource', OrderedDict([('Key2', {'Name': 'name2'}), ('Key1', {'Name': 'name1'})])), ('A_Resource', OrderedDict([('Key2', {'Name': 'name2'}), ('Key1', {'Name': 'name1'})])) ]) self.assertEqual(expected_dict, output_dict) output_template = yaml_dump(output_dict) self.assertEqual(input_template, output_template)
def __init__(self, name, section_names=None, target='man', context=None): """Provides a Hierarichial structure to a ReSTDocument You can write to it similiar to as you can to a ReSTDocument but has an innate structure for more orginaztion and abstraction. :param name: The name of the document :param section_names: A list of sections to be included in the document. :param target: The target documentation of the Document structure :param context: A dictionary of tmp to store with the strucuture. These are only stored per section not the entire structure. """ super(DocumentStructure, self).__init__(target=target) self._name = name self._structure = OrderedDict() self._path = [self._name] self._context = {} if context is not None: self._context = context if section_names is not None: self._generate_structure(section_names)
def test_write_order(self): content = OrderedDict([("current-context", "context"), ("apiVersion", "v1")]) file_to_write = tempfile.NamedTemporaryFile(mode='w').name self.addCleanup(os.remove, file_to_write) config = Kubeconfig(file_to_write, content) self._writer.write_kubeconfig(config) with open(file_to_write, 'r') as stream: self.assertMultiLineEqual( stream.read(), "current-context: context\n" "apiVersion: v1\n")
def test_ordered_shape_builder(self): b = model.DenormalizedStructureBuilder() shape = b.with_members( OrderedDict([('A', { 'type': 'string' }), ('B', { 'type': 'structure', 'members': OrderedDict([('C', { 'type': 'string' }), ('D', { 'type': 'string' })]) })])).build_model() # Members should be in order self.assertEqual(['A', 'B'], list(shape.members.keys())) # Nested structure members should *also* stay ordered self.assertEqual(['C', 'D'], list(shape.members['B'].members.keys()))
def test_write_makedirs(self): content = OrderedDict([("current-context", "context"), ("apiVersion", "v1")]) containing_dir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, containing_dir) config_path = os.path.join(containing_dir, "dir1", "dir2", "dir3") config = Kubeconfig(config_path, content) self._writer.write_kubeconfig(config) with open(config_path, 'r') as stream: self.assertMultiLineEqual( stream.read(), "current-context: context\n" "apiVersion: v1\n")
def _create_command_table(self): command_table = OrderedDict() service_model = self._get_service_model() for operation_name in service_model.operation_names: cli_name = xform_name(operation_name, '-') # Receive model of operation (action/subcommand) operation_model = service_model.operation_model(operation_name) command_table[cli_name] = BACServiceOperation( name=cli_name, parent_name=self._name, session=self.session, operation_model=operation_model, operation_caller=None) return command_table
def build_argument_table(cli_data): """ Create an argument table, which contains all of the arguments that are available to the aws-cli. This is used in the Checker class to ensure correct usage of global aws-cli arguments. """ log.debug('Building command table') argument_table = OrderedDict() cli_arguments = cli_data.get('options', None) for option in cli_arguments: option_params = copy_kwargs(cli_arguments[option]) cli_argument = _create_cli_argument(option, option_params) cli_argument.add_to_arg_table(argument_table) return argument_table
def test_parse_json_preserve_elements_order(self): input_template = """ { "B_Resource": { "Key2": { "Name": "name2" }, "Key1": { "Name": "name1" } }, "A_Resource": { "Key2": { "Name": "name2" }, "Key1": { "Name": "name1" } } } """ expected_dict = OrderedDict([ ("B_Resource", OrderedDict([("Key2", { "Name": "name2" }), ("Key1", { "Name": "name1" })])), ("A_Resource", OrderedDict([("Key2", { "Name": "name2" }), ("Key1", { "Name": "name1" })])), ]) output_dict = yaml_parse(input_template) self.assertEqual(expected_dict, output_dict)
def build_command_table(session): """ Create a command table, which contains all of the commands and subcommands that are available to the aws-cli. """ log.debug('Building command table') command_table = OrderedDict() services = session.get_available_services() for service_name in services: command_table[service_name] = (BACServiceCommand( cli_name=service_name, session=session, service_name=service_name)) # Add the 's3api' to the supported services, as it is equal to # botocore's 's3' command_table['s3api'] = command_table['s3'] return command_table
def _create_command_table(self): command_table = OrderedDict() service_object = self._get_service_object() for operation_object in service_object.operations: cli_name = xform_name(operation_object.name, '-') command_table[cli_name] = ServiceOperation( name=cli_name, parent_name=self._name, operation_object=operation_object, operation_caller=CLIOperationCaller(self.session), service_object=service_object) self.session.emit('building-command-table.%s' % self._name, command_table=command_table, session=self.session) return command_table
def test_create_platform_application(self): op = self.sns.get_operation('CreatePlatformApplication') attributes = OrderedDict() attributes['PlatformCredential'] = 'foo' attributes['PlatformPrincipal'] = 'bar' params = op.build_parameters(name='gcmpushapp', platform='GCM', attributes=attributes)['body'] del params['Action'] del params['Version'] result = {'Name': 'gcmpushapp', 'Platform': 'GCM', 'Attributes.entry.1.key': 'PlatformCredential', 'Attributes.entry.1.value': 'foo', 'Attributes.entry.2.key': 'PlatformPrincipal', 'Attributes.entry.2.value': 'bar'} self.assertEqual(params, result)
def test_gen_structure_list_scalar_docs(self): argument = self.create_argument( OrderedDict([ ('Consistent', { 'type': 'boolean' }), ('Args', { 'type': 'list', 'member': { 'type': 'string' } }), ]), 'foo') generated_example = self.get_generated_example_for(argument) self.assertIn('Consistent=boolean,Args=string,string', generated_example)
def _build_arg_table(self): arg_table = OrderedDict() self._session.emit('building-arg-table.%s' % self.NAME, arg_table=self.ARG_TABLE) for arg_data in self.ARG_TABLE: # If a custom schema was passed in, create the argument_model # so that it can be validated and docs can be generated. if 'schema' in arg_data: argument_model = create_argument_model_from_schema( arg_data.pop('schema')) arg_data['argument_model'] = argument_model custom_argument = CustomArgument(**arg_data) arg_table[arg_data['name']] = custom_argument return arg_table
def test_make_context(self): cluster = OrderedDict([("name", "clustername"), ("cluster", OrderedDict())]) user = OrderedDict([("name", "username"), ("user", OrderedDict())]) context_correct = OrderedDict([("context", OrderedDict([("cluster", "clustername"), ("user", "username")])), ("name", "username")]) context = self._appender._make_context(cluster, user) self.assertDictEqual(context, context_correct)
def build_model(self): """Build the model based on the provided members. :rtype: botocore.model.StructureShape :return: The built StructureShape object. """ shapes = OrderedDict() denormalized = { 'type': 'structure', 'members': self._members, } self._build_model(denormalized, shapes, self.name) resolver = ShapeResolver(shape_map=shapes) return StructureShape(shape_name=self.name, shape_model=shapes[self.name], shape_resolver=resolver)
def handle_op_renames(new_model, enhancements): # This allows for operations to be renamed. The only # implemented transformation is removing part of the operation name # (because that's all we currently need.) remove = enhancements.get('transformations', {}).get('operation-name', {}).get('remove') if remove is not None: # We're going to recreate the dictionary because we want to preserve # the order. This is the only option we have unless we have our own # custom OrderedDict. remove_regex = re.compile(remove) operations = new_model['operations'] new_operation = OrderedDict() for key in operations: new_key = remove_regex.sub('', key) new_operation[new_key] = operations[key] new_model['operations'] = new_operation
def _create_command_table(self): command_table = OrderedDict() service_model = self._get_service_model() for operation_name in service_model.operation_names: cli_name = xform_name(operation_name, '-') operation_model = service_model.operation_model(operation_name) command_table[cli_name] = ServiceOperation( name=cli_name, parent_name=self._name, session=self.session, operation_model=operation_model, operation_caller=CLIOperationCaller(self.session), ) self.session.emit('building-command-table.%s' % self._name, command_table=command_table, session=self.session, command_object=self) self._add_lineage(command_table) return command_table
def handle_remove_deprecated_params(new_model, enhancements): # This removes any parameter whose documentation string contains # the specified phrase that marks a deprecated parameter. keyword = enhancements.get('transformations', {}).get( 'remove-deprecated-params', {}).get('deprecated_keyword') if keyword is not None: operations = new_model['operations'] for op_name in operations: operation = operations[op_name] params = operation.get('input', {}).get('members') if params: new_params = OrderedDict() for param_name in params: param = params[param_name] docs = param['documentation'] if docs and docs.find(keyword) >= 0: continue new_params[param_name] = param operation['input']['members'] = new_params
def __init__(self, name, section_names=None, target='man', context=None): """Provides a Hierarichial structure to a ReSTDocument You can write to it similiar to as you can to a ReSTDocument but has an innate structure for more orginaztion and abstraction. :param name: The name of the document :param section_names: A list of sections to be included in the document. :param target: The target documentation of the Document structure :param context: A dictionary of data to store with the strucuture. These are only stored per section not the entire structure. """ super(DocumentStructure, self).__init__(target=target) self._name = name self._structure = OrderedDict() self._path = [self._name] self._context = {} if context is not None: self._context = context if section_names is not None: self._generate_structure(section_names)
class DocumentStructure(ReSTDocument): def __init__(self, name, section_names=None, target='man', context=None): """Provides a Hierarichial structure to a ReSTDocument You can write to it similiar to as you can to a ReSTDocument but has an innate structure for more orginaztion and abstraction. :param name: The name of the document :param section_names: A list of sections to be included in the document. :param target: The target documentation of the Document structure :param context: A dictionary of data to store with the strucuture. These are only stored per section not the entire structure. """ super(DocumentStructure, self).__init__(target=target) self._name = name self._structure = OrderedDict() self._path = [self._name] self._context = {} if context is not None: self._context = context if section_names is not None: self._generate_structure(section_names) @property def name(self): """The name of the document structure""" return self._name @property def path(self): """ A list of where to find a particular document structure in the overlying document structure. """ return self._path @path.setter def path(self, value): self._path = value @property def available_sections(self): return list(self._structure) @property def context(self): return self._context def _generate_structure(self, section_names): for section_name in section_names: self.add_new_section(section_name) def add_new_section(self, name, context=None): """Adds a new section to the current document structure This document structure will be considered a section to the current document structure but will in itself be an entirely new document structure that can be written to and have sections as well :param name: The name of the section. :param context: A dictionary of data to store with the strucuture. These are only stored per section not the entire structure. :rtype: DocumentStructure :returns: A new document structure to add to but lives as a section to the document structure it was instantiated from. """ # Add a new section section = self.__class__(name=name, target=self.target, context=context) section.path = self.path + [name] # Indent the section apporpriately as well section.style.indentation = self.style.indentation section.translation_map = self.translation_map section.hrefs = self.hrefs self._structure[name] = section return section def get_section(self, name): """Retrieve a section""" return self._structure[name] def delete_section(self, name): """Delete a section""" del self._structure[name] def flush_structure(self): """Flushes a doc structure to a ReSTructed string The document is flushed out in a DFS style where sections and their subsections' values are added to the string as they are visited. """ # We are at the root flush the links at the beginning of the # document if len(self.path) == 1: if self.hrefs: self.style.new_paragraph() for refname, link in self.hrefs.items(): self.style.link_target_definition(refname, link) value = self.getvalue() for name, section in self._structure.items(): value += section.flush_structure() return value def getvalue(self): return ''.join(self._writes).encode('utf-8') def remove_all_sections(self): self._structure = OrderedDict() def clear_text(self): self._writes = []
def remove_all_sections(self): self._structure = OrderedDict()