Support Deploy Templates for Ironic API

1. Create Deploy Template
2. List Deploy Templates
3. Show Deploy Template Details
4. Update a Deploy Template
5. Delete Deploy Template

Story: 2008193
Task: 40957

Change-Id: I0636d810f3dac03ba18a9d5c09cda415333f80e8
This commit is contained in:
anuradha1904 2020-12-28 23:43:47 +05:30
parent eefd1609ac
commit 10a1ee452b
9 changed files with 461 additions and 0 deletions

View File

@ -77,6 +77,14 @@ Volume Target Operations
create_volume_target, update_volume_target,
patch_volume_target, delete_volume_target
Deploy Template Operations
^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: openstack.baremetal.v1._proxy.Proxy
:noindex:
:members: deploy_templates, get_deploy_template,
create_deploy_template, update_deploy_template,
patch_deploy_template, delete_deploy_template
Utilities
---------

View File

@ -12,3 +12,4 @@ Baremetal Resources
v1/allocation
v1/volume_connector
v1/volume_target
v1/deploy_templates

View File

@ -0,0 +1,13 @@
openstack.baremetal.v1.deploy_templates
=======================================
.. automodule:: openstack.baremetal.v1.deploy_templates
The DeployTemplate Class
-------------------------
The ``DeployTemplate`` class inherits
from :class:`~openstack.resource.Resource`.
.. autoclass:: openstack.baremetal.v1.deploy_templates.DeployTemplate
:members:

View File

@ -19,6 +19,7 @@ from openstack.baremetal.v1 import port as _port
from openstack.baremetal.v1 import port_group as _portgroup
from openstack.baremetal.v1 import volume_connector as _volumeconnector
from openstack.baremetal.v1 import volume_target as _volumetarget
from openstack.baremetal.v1 import deploy_templates as _deploytemplates
from openstack import exceptions
from openstack import proxy
from openstack import utils
@ -1309,3 +1310,108 @@ class Proxy(proxy.Proxy):
"""
return self._delete(_volumetarget.VolumeTarget,
volume_target, ignore_missing=ignore_missing)
def deploy_templates(self, details=False, **query):
"""Retrieve a generator of deploy_templates.
:param details: A boolean indicating whether the detailed information
for every deploy_templates should be returned.
:param dict query: Optional query parameters to be sent to
restrict the deploy_templates to be returned.
:returns: A generator of Deploy templates instances.
"""
if details:
query['detail'] = True
return _deploytemplates.DeployTemplate.list(self, **query)
def create_deploy_template(self, **attrs):
"""Create a new deploy_template from attributes.
:param dict attrs: Keyword arguments that will be used to create a
:class:`~openstack.baremetal.v1.deploy_templates.DeployTemplate`.
:returns: The results of deploy_template creation.
:rtype:
:class:`~openstack.baremetal.v1.deploy_templates.DeployTemplate`.
"""
return self._create(_deploytemplates.DeployTemplate, **attrs)
def update_deploy_template(self, deploy_template, **attrs):
"""Update a deploy_template.
:param deploy_template: Either the ID of a deploy_template,
or an instance of
:class:`~openstack.baremetal.v1.deploy_templates.DeployTemplate`.
:param dict attrs: The attributes to update on
the deploy_template represented
by the ``deploy_template`` parameter.
:returns: The updated deploy_template.
:rtype::class:
`~openstack.baremetal.v1.deploy_templates.DeployTemplate`
"""
return self._update(_deploytemplates.DeployTemplate,
deploy_template, **attrs)
def delete_deploy_template(self, deploy_template,
ignore_missing=True):
"""Delete a deploy_template.
:param deploy_template:The value can be
either the ID of a deploy_template or a
:class:`~openstack.baremetal.v1.deploy_templates.DeployTemplate`
instance.
:param bool ignore_missing: When set to ``False``,
an exception:class:`~openstack.exceptions.ResourceNotFound`
will be raised when the deploy_template
could not be found.
When set to ``True``, no
exception will be raised when attempting
to delete a non-existent
deploy_template.
:returns: The instance of the deploy_template which was deleted.
:rtype::class:
`~openstack.baremetal.v1.deploy_templates.DeployTemplate`.
"""
return self._delete(_deploytemplates.DeployTemplate,
deploy_template, ignore_missing=ignore_missing)
def get_deploy_template(self, deploy_template, fields=None):
"""Get a specific deployment template.
:param deploy_template: The value can be the name or ID
of a deployment template
:class:`~openstack.baremetal.v1.deploy_templates.DeployTemplate`
instance.
:param fields: Limit the resource fields to fetch.
:returns: One
:class:`~openstack.baremetal.v1.deploy_templates.DeployTemplate`
:raises: :class:`~openstack.exceptions.ResourceNotFound`
when no deployment template matching the name or
ID could be found.
"""
return self._get_with_fields(_deploytemplates.DeployTemplate,
deploy_template, fields=fields)
def patch_deploy_template(self, deploy_template, patch):
"""Apply a JSON patch to the deploy_templates.
:param deploy_templates: The value can be the ID of a
deploy_template or a
:class:`~openstack.baremetal.v1.deploy_templates.DeployTemplate`
instance.
:param patch: JSON patch to apply.
:returns: The updated deploy_template.
:rtype::class:
`~openstack.baremetal.v1.deploy_templates.DeployTemplate`
"""
return self._get_resource(_deploytemplates.DeployTemplate,
deploy_template).patch(self, patch)

View File

@ -0,0 +1,51 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from openstack.baremetal.v1 import _common
from openstack import resource
class DeployTemplate(_common.ListMixin, resource.Resource):
resources_key = 'deploy_templates'
base_path = '/deploy_templates'
# capabilities
allow_create = True
allow_fetch = True
allow_commit = True
allow_delete = True
allow_list = True
allow_patch = True
commit_method = 'PATCH'
commit_jsonpatch = True
_query_mapping = resource.QueryParameters(
'detail',
fields={'type': _common.fields_type},
)
# Deploy Templates is available since 1.55
_max_microversion = '1.55'
name = resource.Body('name')
#: Timestamp at which the deploy_template was created.
created_at = resource.Body('created_at')
#: A set of one or more arbitrary metadata key and value pairs.
extra = resource.Body('extra')
#: A list of relative links. Includes the self and bookmark links.
links = resource.Body('links', type=list)
#: A set of physical information of the deploy_template.
steps = resource.Body('steps', type=list)
#: Timestamp at which the deploy_template was last updated.
updated_at = resource.Body('updated_at')
#: The UUID of the resource.
id = resource.Body('uuid', alternate_id=True)

View File

@ -84,3 +84,16 @@ class BaseBaremetalTest(base.BaseFunctionalTest):
self.conn.baremetal.delete_volume_target(volume_target.id,
ignore_missing=True))
return volume_target
def create_deploy_template(self, **kwargs):
"""Create a new deploy_template from attributes.
"""
deploy_template = self.conn.baremetal.create_deploy_template(
**kwargs)
self.addCleanup(
lambda: self.conn.baremetal.delete_deploy_template(
deploy_template.id,
ignore_missing=True))
return deploy_template

View File

@ -0,0 +1,190 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from openstack import exceptions
from openstack.tests.functional.baremetal import base
class TestBareMetalDeployTemplate(base.BaseBaremetalTest):
min_microversion = '1.55'
def setUp(self):
super(TestBareMetalDeployTemplate, self).setUp()
def test_baremetal_deploy_create_get_delete(self):
steps = [
{
"interface": "bios",
"step": "apply_configuration",
"args": {
"settings": [
{
"name": "LogicalProc",
"value": "Enabled"
}
]
},
"priority": 150
}
]
deploy_template = self.create_deploy_template(
name='CUSTOM_DEPLOY_TEMPLATE',
steps=steps)
loaded = self.conn.baremetal.get_deploy_template(
deploy_template.id)
self.assertEqual(loaded.id, deploy_template.id)
self.conn.baremetal.delete_deploy_template(deploy_template,
ignore_missing=False)
self.assertRaises(exceptions.ResourceNotFound,
self.conn.baremetal.get_deploy_template,
deploy_template.id)
def test_baremetal_deploy_template_list(self):
steps = [
{
"interface": "bios",
"step": "apply_configuration",
"args": {
"settings": [
{
"name": "LogicalProc",
"value": "Enabled"
}
]
},
"priority": 150
}
]
deploy_template1 = self.create_deploy_template(
name='CUSTOM_DEPLOY_TEMPLATE1',
steps=steps)
deploy_template2 = self.create_deploy_template(
name='CUSTOM_DEPLOY_TEMPLATE2',
steps=steps)
deploy_templates = self.conn.baremetal.deploy_templates()
ids = [template.id for template in deploy_templates]
self.assertIn(deploy_template1.id, ids)
self.assertIn(deploy_template2.id, ids)
deploy_templates_with_details = self.conn.baremetal.deploy_templates(
details=True)
for dp in deploy_templates_with_details:
self.assertIsNotNone(dp.id)
self.assertIsNotNone(dp.name)
deploy_tempalte_with_fields = self.conn.baremetal.deploy_templates(
fields=['uuid'])
for dp in deploy_tempalte_with_fields:
self.assertIsNotNone(dp.id)
self.assertIsNone(dp.name)
def test_baremetal_deploy_list_update_delete(self):
steps = [
{
"interface": "bios",
"step": "apply_configuration",
"args": {
"settings": [
{
"name": "LogicalProc",
"value": "Enabled"
}
]
},
"priority": 150
}
]
deploy_template = self.create_deploy_template(
name='CUSTOM_DEPLOY_TEMPLATE4',
steps=steps)
self.assertFalse(deploy_template.extra)
deploy_template.extra = {'answer': 42}
deploy_template = self.conn.baremetal.update_deploy_template(
deploy_template)
self.assertEqual({'answer': 42}, deploy_template.extra)
deploy_template = self.conn.baremetal.get_deploy_template(
deploy_template.id)
self.conn.baremetal.delete_deploy_template(deploy_template.id,
ignore_missing=False)
def test_baremetal_deploy_update(self):
steps = [
{
"interface": "bios",
"step": "apply_configuration",
"args": {
"settings": [
{
"name": "LogicalProc",
"value": "Enabled"
}
]
},
"priority": 150
}
]
deploy_template = self.create_deploy_template(
name='CUSTOM_DEPLOY_TEMPLATE4',
steps=steps)
deploy_template.extra = {'answer': 42}
deploy_template = self.conn.baremetal.update_deploy_template(
deploy_template)
self.assertEqual({'answer': 42}, deploy_template.extra)
deploy_template = self.conn.baremetal.get_deploy_template(
deploy_template.id)
self.assertEqual({'answer': 42}, deploy_template.extra)
def test_deploy_template_patch(self):
name = "CUSTOM_HYPERTHREADING_ON"
steps = [
{
"interface": "bios",
"step": "apply_configuration",
"args": {
"settings": [
{
"name": "LogicalProc",
"value": "Enabled"
}
]
},
"priority": 150
}
]
deploy_template = self.create_deploy_template(
name=name,
steps=steps)
deploy_template = self.conn.baremetal.patch_deploy_template(
deploy_template, dict(path='/extra/answer', op='add', value=42))
self.assertEqual({'answer': 42}, deploy_template.extra)
self.assertEqual(name,
deploy_template.name)
deploy_template = self.conn.baremetal.get_deploy_template(
deploy_template.id)
self.assertEqual({'answer': 42}, deploy_template.extra)
def test_deploy_template_negative_non_existing(self):
uuid = "bbb45f41-d4bc-4307-8d1d-32f95ce1e920"
self.assertRaises(exceptions.ResourceNotFound,
self.conn.baremetal.get_deploy_template, uuid)
self.assertRaises(exceptions.ResourceNotFound,
self.conn.baremetal.delete_deploy_template, uuid,
ignore_missing=False)
self.assertIsNone(self.conn.baremetal.delete_deploy_template(uuid))

View File

@ -0,0 +1,75 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from openstack.tests.unit import base
from openstack.baremetal.v1 import deploy_templates
FAKE = {
"created_at": "2016-08-18T22:28:48.643434+11:11",
"extra": {},
"links": [
{
"href": """http://10.60.253.180:6385/v1/deploy_templates
/bbb45f41-d4bc-4307-8d1d-32f95ce1e920""",
"rel": "self"
},
{
"href": """http://10.60.253.180:6385/deploy_templates
/bbb45f41-d4bc-4307-8d1d-32f95ce1e920""",
"rel": "bookmark"
}
],
"name": "CUSTOM_HYPERTHREADING_ON",
"steps": [
{
"args": {
"settings": [
{
"name": "LogicalProc",
"value": "Enabled"
}
]
},
"interface": "bios",
"priority": 150,
"step": "apply_configuration"
}
],
"updated_at": None,
"uuid": "bbb45f41-d4bc-4307-8d1d-32f95ce1e920"
}
class DeployTemplates(base.TestCase):
def test_basic(self):
sot = deploy_templates.DeployTemplate()
self.assertIsNone(sot.resource_key)
self.assertEqual('deploy_templates', sot.resources_key)
self.assertEqual('/deploy_templates', sot.base_path)
self.assertTrue(sot.allow_create)
self.assertTrue(sot.allow_fetch)
self.assertTrue(sot.allow_commit)
self.assertTrue(sot.allow_delete)
self.assertTrue(sot.allow_list)
self.assertEqual('PATCH', sot.commit_method)
def test_instantiate(self):
sot = deploy_templates.DeployTemplate(**FAKE)
self.assertEqual(FAKE['steps'], sot.steps)
self.assertEqual(FAKE['created_at'], sot.created_at)
self.assertEqual(FAKE['extra'], sot.extra)
self.assertEqual(FAKE['links'], sot.links)
self.assertEqual(FAKE['name'], sot.name)
self.assertEqual(FAKE['updated_at'], sot.updated_at)
self.assertEqual(FAKE['uuid'], sot.id)

View File

@ -0,0 +1,4 @@
---
features:
- |
Support Deploy Templates for Ironic API