diff -pruN 3.3.1-2/blazarclient/base.py 3.4.0-2/blazarclient/base.py
--- 3.3.1-2/blazarclient/base.py	2021-09-02 10:44:24.000000000 +0000
+++ 3.4.0-2/blazarclient/base.py	2022-02-23 23:46:23.000000000 +0000
@@ -67,6 +67,14 @@ class RequestManager(object):
         """
         return self.request(url, 'PUT', body=body)
 
+    def patch(self, url, body):
+        """Sends patch request to Blazar.
+
+        :param url: URL to the wanted Blazar resource.
+        :type url: str
+        """
+        return self.request(url, 'PATCH', body=body)
+
     def request(self, url, method, **kwargs):
         """Base request method.
 
diff -pruN 3.3.1-2/blazarclient/command.py 3.4.0-2/blazarclient/command.py
--- 3.3.1-2/blazarclient/command.py	2021-09-02 10:44:24.000000000 +0000
+++ 3.4.0-2/blazarclient/command.py	2022-02-23 23:46:23.000000000 +0000
@@ -307,3 +307,69 @@ class ShowCommand(BlazarCommand, show.Sh
         data = resource_manager.get(res_id)
         self.format_output_data(data)
         return list(zip(*sorted(data.items())))
+
+
+class ShowPropertyCommand(BlazarCommand, show.ShowOne):
+    """Show information of a given resource property."""
+
+    api = 'reservation'
+    resource = None
+    log = None
+
+    def get_parser(self, prog_name):
+        parser = super(ShowPropertyCommand, self).get_parser(prog_name)
+        parser.add_argument('property_name', metavar='PROPERTY_NAME',
+                            help='Name of property.')
+        return parser
+
+    def get_data(self, parsed_args):
+        self.log.debug('get_data(%s)' % parsed_args)
+        blazar_client = self.get_client()
+        resource_manager = getattr(blazar_client, self.resource)
+        data = resource_manager.get_property(parsed_args.property_name)
+        if parsed_args.formatter == 'table':
+            self.format_output_data(data)
+        return list(zip(*sorted(data.items())))
+
+
+class UpdatePropertyCommand(BlazarCommand):
+    api = 'reservation'
+    resource = None
+    log = None
+
+    def run(self, parsed_args):
+        self.log.debug('run(%s)' % parsed_args)
+        blazar_client = self.get_client()
+        body = self.args2body(parsed_args)
+        resource_manager = getattr(blazar_client, self.resource)
+        resource_manager.set_property(**body)
+        print(
+            'Updated %s property: %s' % (
+                self.resource, parsed_args.property_name),
+            file=self.app.stdout)
+        return
+
+    def get_parser(self, prog_name):
+        parser = super(UpdatePropertyCommand, self).get_parser(prog_name)
+        parser.add_argument(
+            'property_name', metavar='PROPERTY_NAME',
+            help='Name of property to patch.'
+        )
+        parser.add_argument(
+            '--private',
+            action='store_true',
+            default=False,
+            help='Set property to private.'
+        )
+        parser.add_argument(
+            '--public',
+            action='store_true',
+            default=False,
+            help='Set property to public.'
+        )
+        return parser
+
+    def args2body(self, parsed_args):
+        return dict(
+            property_name=parsed_args.property_name,
+            private=(parsed_args.private is True))
diff -pruN 3.3.1-2/blazarclient/exception.py 3.4.0-2/blazarclient/exception.py
--- 3.3.1-2/blazarclient/exception.py	2021-09-02 10:44:24.000000000 +0000
+++ 3.4.0-2/blazarclient/exception.py	2022-02-23 23:46:23.000000000 +0000
@@ -90,3 +90,9 @@ class InsufficientAuthInformation(Blazar
                 "for the authentication. The instance of "
                 "keystoneauth1.session.Session class is required.")
     code = 400
+
+
+class ResourcePropertyNotFound(BlazarClientException):
+    """Occurs if the resource property specified does not exist"""
+    message = _("The resource property does not exist.")
+    code = 404
diff -pruN 3.3.1-2/blazarclient/shell.py 3.4.0-2/blazarclient/shell.py
--- 3.3.1-2/blazarclient/shell.py	2021-09-02 10:44:24.000000000 +0000
+++ 3.4.0-2/blazarclient/shell.py	2022-02-23 23:46:23.000000000 +0000
@@ -44,6 +44,9 @@ COMMANDS_V1 = {
     'host-create': hosts.CreateHost,
     'host-update': hosts.UpdateHost,
     'host-delete': hosts.DeleteHost,
+    'host-property-list': hosts.ListHostProperties,
+    'host-property-show': hosts.ShowHostProperty,
+    'host-property-set': hosts.UpdateHostProperty,
     'floatingip-list': floatingips.ListFloatingIPs,
     'floatingip-show': floatingips.ShowFloatingIP,
     'floatingip-create': floatingips.CreateFloatingIP,
diff -pruN 3.3.1-2/blazarclient/v1/hosts.py 3.4.0-2/blazarclient/v1/hosts.py
--- 3.3.1-2/blazarclient/v1/hosts.py	2021-09-02 10:44:24.000000000 +0000
+++ 3.4.0-2/blazarclient/v1/hosts.py	2022-02-23 23:46:23.000000000 +0000
@@ -14,6 +14,7 @@
 # limitations under the License.
 
 from blazarclient import base
+from blazarclient import exception
 from blazarclient.i18n import _
 
 
@@ -52,3 +53,43 @@ class ComputeHostClientManager(base.Base
         if sort_by:
             hosts = sorted(hosts, key=lambda l: l[sort_by])
         return hosts
+
+    def list_properties(self, detail=False, all=False, sort_by=None):
+        url = '/os-hosts/properties'
+
+        query_parts = []
+        if detail:
+            query_parts.append("detail=True")
+        if all:
+            query_parts.append("all=True")
+        if query_parts:
+            url += "?" + "&".join(query_parts)
+
+        resp, body = self.request_manager.get(url)
+        resource_properties = body['resource_properties']
+
+        # Values is a reserved word in cliff so need to rename values column.
+        if detail:
+            for p in resource_properties:
+                p['property_values'] = p['values']
+                del p['values']
+
+        if sort_by:
+            resource_properties = sorted(resource_properties,
+                                         key=lambda l: l[sort_by])
+        return resource_properties
+
+    def get_property(self, property_name):
+        resource_property = [
+            x for x in self.list_properties(detail=True)
+            if x['property'] == property_name]
+        if not resource_property:
+            raise exception.ResourcePropertyNotFound()
+        return resource_property[0]
+
+    def set_property(self, property_name, private):
+        data = {'private': private}
+        resp, body = self.request_manager.patch(
+            '/os-hosts/properties/%s' % property_name, body=data)
+
+        return body['resource_property']
diff -pruN 3.3.1-2/blazarclient/v1/shell_commands/hosts.py 3.4.0-2/blazarclient/v1/shell_commands/hosts.py
--- 3.3.1-2/blazarclient/v1/shell_commands/hosts.py	2021-09-02 10:44:24.000000000 +0000
+++ 3.4.0-2/blazarclient/v1/shell_commands/hosts.py	2022-02-23 23:46:23.000000000 +0000
@@ -16,6 +16,7 @@
 import logging
 
 from blazarclient import command
+from blazarclient import exception
 
 HOST_ID_PATTERN = '^[0-9]+$'
 
@@ -120,3 +121,68 @@ class DeleteHost(command.DeleteCommand):
     log = logging.getLogger(__name__ + '.DeleteHost')
     name_key = 'hypervisor_hostname'
     id_pattern = HOST_ID_PATTERN
+
+
+class ShowHostProperty(command.ShowPropertyCommand):
+    """Show host property."""
+    resource = 'host'
+    json_indent = 4
+    log = logging.getLogger(__name__ + '.ShowHostProperty')
+
+
+class ListHostProperties(command.ListCommand):
+    """List host properties."""
+    resource = 'host'
+    log = logging.getLogger(__name__ + '.ListHostProperties')
+    list_columns = ['property', 'private', 'property_values']
+
+    def args2body(self, parsed_args):
+        params = {
+            'detail': parsed_args.detail,
+            'all': parsed_args.all,
+        }
+        if parsed_args.sort_by:
+            if parsed_args.sort_by in self.list_columns:
+                params['sort_by'] = parsed_args.sort_by
+            else:
+                msg = 'Invalid sort option %s' % parsed_args.sort_by
+                raise exception.BlazarClientException(msg)
+
+        return params
+
+    def retrieve_list(self, parsed_args):
+        """Retrieve a list of resources from Blazar server."""
+        blazar_client = self.get_client()
+        body = self.args2body(parsed_args)
+        resource_manager = getattr(blazar_client, self.resource)
+        data = resource_manager.list_properties(**body)
+        return data
+
+    def get_parser(self, prog_name):
+        parser = super(ListHostProperties, self).get_parser(prog_name)
+        parser.add_argument(
+            '--detail',
+            action='store_true',
+            help='Return properties with values and attributes.',
+            default=False
+        )
+        parser.add_argument(
+            '--sort-by', metavar="<property_column>",
+            help='column name used to sort result',
+            default='property'
+        )
+        parser.add_argument(
+            '--all',
+            action='store_true',
+            help='Return all properties, public and private.',
+            default=False
+        )
+        return parser
+
+
+class UpdateHostProperty(command.UpdatePropertyCommand):
+    """Update attributes of a host property."""
+    resource = 'host'
+    json_indent = 4
+    log = logging.getLogger(__name__ + '.UpdateHostProperty')
+    name_key = 'property_name'
diff -pruN 3.3.1-2/debian/changelog 3.4.0-2/debian/changelog
--- 3.3.1-2/debian/changelog	2021-09-29 15:12:54.000000000 +0000
+++ 3.4.0-2/debian/changelog	2022-03-25 08:57:06.000000000 +0000
@@ -1,3 +1,16 @@
+python-blazarclient (3.4.0-2) unstable; urgency=medium
+
+  * Uploading to unstable.
+  * Add autopkgtest.
+
+ -- Thomas Goirand <zigo@debian.org>  Fri, 25 Mar 2022 09:57:06 +0100
+
+python-blazarclient (3.4.0-1) experimental; urgency=medium
+
+  * New upstream release.
+
+ -- Thomas Goirand <zigo@debian.org>  Thu, 24 Feb 2022 16:22:01 +0100
+
 python-blazarclient (3.3.1-2) unstable; urgency=medium
 
   * Uploading to unstable.
diff -pruN 3.3.1-2/debian/tests/control 3.4.0-2/debian/tests/control
--- 3.3.1-2/debian/tests/control	1970-01-01 00:00:00.000000000 +0000
+++ 3.4.0-2/debian/tests/control	2022-03-25 08:57:06.000000000 +0000
@@ -0,0 +1,5 @@
+Tests: unittests
+Depends:
+ @,
+ @builddeps@,
+Restrictions: allow-stderr needs-root
diff -pruN 3.3.1-2/debian/tests/unittests 3.4.0-2/debian/tests/unittests
--- 3.3.1-2/debian/tests/unittests	1970-01-01 00:00:00.000000000 +0000
+++ 3.4.0-2/debian/tests/unittests	2022-03-25 08:57:06.000000000 +0000
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+set -e
+
+pkgos-dh_auto_test --no-py2 'blazarclient\.tests\.(?!.*v1\.shell_commands\.test_leases\.CreateLeaseTestCase\.test_args2body_start_now.*)'
diff -pruN 3.3.1-2/releasenotes/notes/host-resource-property-9ac5c21bd3ca6699.yaml 3.4.0-2/releasenotes/notes/host-resource-property-9ac5c21bd3ca6699.yaml
--- 3.3.1-2/releasenotes/notes/host-resource-property-9ac5c21bd3ca6699.yaml	1970-01-01 00:00:00.000000000 +0000
+++ 3.4.0-2/releasenotes/notes/host-resource-property-9ac5c21bd3ca6699.yaml	2022-02-23 23:46:23.000000000 +0000
@@ -0,0 +1,9 @@
+---
+features:
+  - |
+    Added support for managing host resource properties using the following new
+    commands:
+
+    * ``host-property-list``
+    * ``host-property-show``
+    * ``host-property-set``
diff -pruN 3.3.1-2/releasenotes/source/index.rst 3.4.0-2/releasenotes/source/index.rst
--- 3.3.1-2/releasenotes/source/index.rst	2021-09-02 10:44:24.000000000 +0000
+++ 3.4.0-2/releasenotes/source/index.rst	2022-02-23 23:46:23.000000000 +0000
@@ -6,6 +6,7 @@
    :maxdepth: 1
 
    unreleased
+   xena
    wallaby
    victoria
    ussuri
diff -pruN 3.3.1-2/releasenotes/source/xena.rst 3.4.0-2/releasenotes/source/xena.rst
--- 3.3.1-2/releasenotes/source/xena.rst	1970-01-01 00:00:00.000000000 +0000
+++ 3.4.0-2/releasenotes/source/xena.rst	2022-02-23 23:46:23.000000000 +0000
@@ -0,0 +1,6 @@
+=========================
+Xena Series Release Notes
+=========================
+
+.. release-notes::
+   :branch: stable/xena
diff -pruN 3.3.1-2/setup.cfg 3.4.0-2/setup.cfg
--- 3.3.1-2/setup.cfg	2021-09-02 10:44:24.000000000 +0000
+++ 3.4.0-2/setup.cfg	2022-02-23 23:46:23.000000000 +0000
@@ -12,6 +12,7 @@ classifiers =
     Programming Language :: Python :: 3.6
     Programming Language :: Python :: 3.7
     Programming Language :: Python :: 3.8
+    Programming Language :: Python :: 3.9
     Environment :: OpenStack
     Development Status :: 3 - Alpha
     Framework :: Setuptools Plugin
@@ -44,6 +45,9 @@ openstack.reservation.v1 =
     reservation_host_list = blazarclient.v1.shell_commands.hosts:ListHosts
     reservation_host_set = blazarclient.v1.shell_commands.hosts:UpdateHost
     reservation_host_show = blazarclient.v1.shell_commands.hosts:ShowHost
+    reservation_host_property_list = blazarclient.v1.shell_commands.hosts:ListHostProperties
+    reservation_host_property_show = blazarclient.v1.shell_commands.hosts:ShowHostProperty
+    reservation_host_property_set = blazarclient.v1.shell_commands.hosts:UpdateHostProperty
     reservation_lease_create = blazarclient.v1.shell_commands.leases:CreateLeaseBase
     reservation_lease_delete = blazarclient.v1.shell_commands.leases:DeleteLease
     reservation_lease_list = blazarclient.v1.shell_commands.leases:ListLeases
diff -pruN 3.3.1-2/.zuul.yaml 3.4.0-2/.zuul.yaml
--- 3.3.1-2/.zuul.yaml	2021-09-02 10:44:24.000000000 +0000
+++ 3.4.0-2/.zuul.yaml	2022-02-23 23:46:23.000000000 +0000
@@ -2,6 +2,6 @@
     templates:
       - check-requirements
       - openstack-lower-constraints-jobs
-      - openstack-python3-xena-jobs
+      - openstack-python3-yoga-jobs
       - release-notes-jobs-python3
       - openstack-cover-jobs
\ No newline at end of file
