2
0
mirror of https://github.com/openkmip/pykmip synced 2025-12-23 19:53:24 +00:00

Update the GetAttributes payloads to support KMIP 2.0

This change updates the GetAttributes payloads to support KMIP 2.0
features, including swapping out Attribute Names for the Attribute
Reference structure in the request payload and the Attribute list
for the Attributes structure in the response payload. Unit tests
have been added to cover these changes.
This commit is contained in:
Peter Hamilton
2019-03-29 13:14:59 -04:00
committed by Peter Hamilton
parent 568e87e89e
commit 0961687d66
2 changed files with 464 additions and 49 deletions

View File

@@ -124,6 +124,10 @@ class GetAttributesRequestPayload(primitives.Struct):
kmip_version (KMIPVersion): An enumeration defining the KMIP
version with which the object will be decoded. Optional,
defaults to KMIP 1.0.
Raises:
InvalidKmipEncoding: Raised if an invalid type is found for the
AttributeReference encoding for KMIP 2.0+ encodings.
"""
super(GetAttributesRequestPayload, self).read(
input_buffer,
@@ -143,11 +147,45 @@ class GetAttributesRequestPayload(primitives.Struct):
self._unique_identifier = None
names = list()
while self.is_tag_next(enums.Tags.ATTRIBUTE_NAME, local_buffer):
name = primitives.TextString(tag=enums.Tags.ATTRIBUTE_NAME)
name.read(local_buffer, kmip_version=kmip_version)
names.append(name)
self._attribute_names = names
if kmip_version < enums.KMIPVersion.KMIP_2_0:
while self.is_tag_next(enums.Tags.ATTRIBUTE_NAME, local_buffer):
name = primitives.TextString(tag=enums.Tags.ATTRIBUTE_NAME)
name.read(local_buffer, kmip_version=kmip_version)
names.append(name)
self._attribute_names = names
else:
while self.is_tag_next(
enums.Tags.ATTRIBUTE_REFERENCE,
local_buffer
):
if self.is_type_next(enums.Types.STRUCTURE, local_buffer):
reference = objects.AttributeReference()
reference.read(local_buffer, kmip_version=kmip_version)
names.append(
primitives.TextString(
value=reference.attribute_name,
tag=enums.Tags.ATTRIBUTE_NAME
)
)
elif self.is_type_next(enums.Types.ENUMERATION, local_buffer):
reference = primitives.Enumeration(
enums.Tags,
tag=enums.Tags.ATTRIBUTE_REFERENCE
)
reference.read(local_buffer, kmip_version=kmip_version)
name = enums.convert_attribute_tag_to_name(reference.value)
names.append(
primitives.TextString(
value=name,
tag=enums.Tags.ATTRIBUTE_NAME
)
)
else:
raise exceptions.InvalidKmipEncoding(
"The GetAttributes request payload encoding contains "
"an invalid AttributeReference type."
)
self._attribute_names = names
self.is_oversized(local_buffer)
@@ -172,8 +210,25 @@ class GetAttributesRequestPayload(primitives.Struct):
kmip_version=kmip_version
)
for attribute_name in self._attribute_names:
attribute_name.write(local_buffer, kmip_version=kmip_version)
if kmip_version < enums.KMIPVersion.KMIP_2_0:
for attribute_name in self._attribute_names:
attribute_name.write(local_buffer, kmip_version=kmip_version)
else:
# NOTE (ph) This approach simplifies backwards compatible issues
# but limits easy support for using AttributeReference
# structures going forward, specifically limiting the
# use of VendorIdentification for custom attributes.
# If custom attributes need to be retrieved using
# the GetAttributes operation for KMIP 2.0 applications
# this code will need to change.
for attribute_name in self._attribute_names:
t = enums.convert_attribute_name_to_tag(attribute_name.value)
e = primitives.Enumeration(
enums.Tags,
value=t,
tag=enums.Tags.ATTRIBUTE_REFERENCE
)
e.write(local_buffer, kmip_version=kmip_version)
self.length = local_buffer.length()
super(GetAttributesRequestPayload, self).write(
@@ -321,11 +376,26 @@ class GetAttributesResponsePayload(primitives.Struct):
"unique identifier."
)
self._attributes = list()
while self.is_tag_next(enums.Tags.ATTRIBUTE, local_buffer):
attribute = objects.Attribute()
attribute.read(local_buffer, kmip_version=kmip_version)
self._attributes.append(attribute)
if kmip_version < enums.KMIPVersion.KMIP_2_0:
self._attributes = list()
while self.is_tag_next(enums.Tags.ATTRIBUTE, local_buffer):
attribute = objects.Attribute()
attribute.read(local_buffer, kmip_version=kmip_version)
self._attributes.append(attribute)
else:
if self.is_tag_next(enums.Tags.ATTRIBUTES, local_buffer):
attributes = objects.Attributes()
attributes.read(local_buffer, kmip_version=kmip_version)
# TODO (ph) Add a new utility to avoid using TemplateAttributes
temp_attr = objects.convert_attributes_to_template_attribute(
attributes
)
self._attributes = temp_attr.attributes
else:
raise exceptions.InvalidKmipEncoding(
"The GetAttributes response payload encoding is missing "
"the attributes structure."
)
self.is_oversized(local_buffer)
@@ -355,8 +425,24 @@ class GetAttributesResponsePayload(primitives.Struct):
"identifier field."
)
for attribute in self._attributes:
attribute.write(local_buffer, kmip_version=kmip_version)
if kmip_version < enums.KMIPVersion.KMIP_2_0:
for attribute in self._attributes:
attribute.write(local_buffer, kmip_version=kmip_version)
else:
if self._attributes:
# TODO (ph) Add a new utility to avoid using TemplateAttributes
template_attribute = objects.TemplateAttribute(
attributes=self.attributes
)
attributes = objects.convert_template_attribute_to_attributes(
template_attribute
)
attributes.write(local_buffer, kmip_version=kmip_version)
else:
raise exceptions.InvalidField(
"The GetAttributes response payload is missing the "
"attributes list."
)
self.length = local_buffer.length()
super(GetAttributesResponsePayload, self).write(