Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 181 additions & 0 deletions kmip/core/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,187 @@ def __ne__(self, other):
return NotImplemented


class CurrentAttribute(primitives.Struct):
"""
A structure containing a single attribute.

This is intended for use with KMIP 2.0+.

Attributes:
attribute: An attribute instance.
"""

def __init__(self, attribute=None):
"""
Construct a CurrentAttribute structure.

Args:
attribute (struct): An attribute structure of varying type.
Defaults to None. Required for read/write.
"""
super(CurrentAttribute, self).__init__(
tag=enums.Tags.CURRENT_ATTRIBUTE
)

self._factory = AttributeValueFactory()

self._attribute = None

self.attribute = attribute

@property
def attribute(self):
if self._attribute:
return self._attribute
return None

@attribute.setter
def attribute(self, value):
if value is None:
self._attribute = None
elif isinstance(value, primitives.Base):
if enums.is_attribute(value.tag):
self._attribute = value
else:
raise TypeError(
"The attribute must be a supported attribute type."
)
else:
raise TypeError(
"The attribute must be a Base object, not a {}.".format(
type(value)
)
)

def read(self, input_buffer, kmip_version=enums.KMIPVersion.KMIP_2_0):
"""
Read the data stream and decode the CurrentAttribute structure into
its parts.

Args:
input_buffer (stream): A data stream containing encoded object
data, supporting a read method.
kmip_version (enum): A KMIPVersion enumeration defining the KMIP
version with which the object will be decoded. Optional,
defaults to KMIP 2.0.

Raises:
AttributeNotSupported: Raised when an invalid value is decoded as
the attribute from the encoding.
InvalidKmipEncoding: Raised if the attribute is missing from the
encoding.
VersionNotSupported: Raised when a KMIP version is provided that
does not support the CurrentAttribute structure.
"""
if kmip_version < enums.KMIPVersion.KMIP_2_0:
raise exceptions.VersionNotSupported(
"KMIP {} does not support the CurrentAttribute object.".format(
kmip_version.value
)
)

super(CurrentAttribute, self).read(
input_buffer,
kmip_version=kmip_version
)
local_buffer = BytearrayStream(input_buffer.read(self.length))

if len(local_buffer) < 3:
raise exceptions.InvalidKmipEncoding(
"The CurrentAttribute encoding is missing the attribute field."
)
tag = struct.unpack('!I', b'\x00' + local_buffer.peek(3))[0]
if enums.is_enum_value(enums.Tags, tag):
tag = enums.Tags(tag)
if enums.is_attribute(tag, kmip_version=kmip_version):
value = self._factory.create_attribute_value_by_enum(tag, None)
value.read(local_buffer, kmip_version=kmip_version)
self._attribute = value
else:
raise exceptions.AttributeNotSupported(
"Attribute {} is not supported by KMIP {}.".format(
tag.name,
kmip_version.value
)
)
else:
raise exceptions.InvalidKmipEncoding(
"The CurrentAttribute encoding is missing the attribute field."
)

self.is_oversized(local_buffer)

def write(self, output_buffer, kmip_version=enums.KMIPVersion.KMIP_2_0):
"""
Write the CurrentAttribute structure encoding to the data stream.

Args:
output_buffer (stream): A data stream in which to encode
CurrentAttribute structure data, supporting a write method.
kmip_version (enum): A KMIPVersion enumeration defining the KMIP
version with which the object will be encoded. Optional,
defaults to KMIP 2.0.

Raises:
AttributeNotSupported: Raised if an unsupported attribute is
found while encoding.
InvalidField: Raised when the attribute is unspecified at write
time.
VersionNotSupported: Raised when a KMIP version is provided that
does not support the CurrentAttribute object.
"""
if kmip_version < enums.KMIPVersion.KMIP_2_0:
raise exceptions.VersionNotSupported(
"KMIP {} does not support the CurrentAttribute object.".format(
kmip_version.value
)
)

local_buffer = BytearrayStream()

if self._attribute:
tag = self._attribute.tag
if not enums.is_attribute(tag, kmip_version=kmip_version):
raise exceptions.AttributeNotSupported(
"Attribute {} is not supported by KMIP {}.".format(
tag.name,
kmip_version.value
)
)
self._attribute.write(local_buffer, kmip_version=kmip_version)
else:
raise exceptions.InvalidField(
"The CurrentAttribute object is missing the attribute field."
)

self.length = local_buffer.length()
super(CurrentAttribute, self).write(
output_buffer,
kmip_version=kmip_version
)
output_buffer.write(local_buffer.buffer)

def __repr__(self):
return "CurrentAttribute(attribute={})".format(repr(self.attribute))

def __str__(self):
value = '"attribute": {}'.format(repr(self.attribute))
return '{' + value + '}'

def __eq__(self, other):
if not isinstance(other, CurrentAttribute):
return NotImplemented
elif self.attribute != other.attribute:
return False
return True

def __ne__(self, other):
if isinstance(other, CurrentAttribute):
return not (self == other)
else:
return NotImplemented


class AttributeReference(primitives.Struct):
"""
A structure containing reference information for an attribute.
Expand Down
Loading