Bootaction cleanup
- Clean up the docs and code around bootactions to support the baclient work - Update the Jinja2 environment in the bootaction rendering - Refactor authentication of bootaction signal API calls Change-Id: Ic64f0c7ee09a487be750188953013f1ed3cd99cb
This commit is contained in:
parent
0f39a55942
commit
9a52dca199
@ -112,6 +112,9 @@ object in details can be extended with additional fields as needed.
|
||||
Once a POST containing the ``status`` field is made to a bootaction-id, that bootaction-id can no
|
||||
longer be updated with status changes nor additional detailed status messages.
|
||||
|
||||
Each request made must contain the ``X-Bootaction-Key`` header with the correct hex
|
||||
key for ``bootaction-id``.
|
||||
|
||||
validatedesign API
|
||||
------------------
|
||||
|
||||
|
@ -111,9 +111,11 @@ template
|
||||
- node.network.[network_name].cidr - CIDR of [network_name]
|
||||
- node.network.[network_name].dns_suffix - DNS suffix of [network_name]
|
||||
- node.hostname - Hostname of the node
|
||||
- node.domain - DNS Domain of the primary network on the node
|
||||
- node.tags - Sequence of tags assigned to this node
|
||||
- node.labels - Key, value pairs of both explicit and dynamic labels for this node
|
||||
- action.key - A key that uniquely identifies this boot action on this node. Can be used for signaling boot action result.
|
||||
- action.action_id - A ULID that uniquely identifies this boot action on this node. Can be used for signaling boot action result.
|
||||
- action.action_key - A random key in hex that authenticates API calls for signaling boot action result.
|
||||
- action.report_url - The URL that can be POSTed to for reporting boot action result.
|
||||
- action.design_ref - The design reference for the deployment that initiated the bootaction
|
||||
|
||||
|
@ -43,6 +43,8 @@ RUN pip3 install \
|
||||
--no-cache-dir \
|
||||
-r /tmp/drydock/requirements-lock.txt
|
||||
|
||||
COPY ./alembic /tmp/drydock/alembic
|
||||
COPY ./alembic.ini /tmp/drydock/alembic.ini
|
||||
COPY ./python /tmp/drydock/python
|
||||
COPY ${BUILD_DIR}/baclient /tmp/drydock/python/drydock_provisioner/assets/baclient
|
||||
|
||||
|
@ -176,11 +176,13 @@ class BootactionAssetsResource(StatefulResource):
|
||||
if hostname in ba.target_nodes:
|
||||
ba_status = ba_status_list.get(ba.name, None)
|
||||
action_id = ba_status.get('action_id')
|
||||
action_key = ba_status.get('identity_key')
|
||||
assets.extend(
|
||||
ba.render_assets(
|
||||
hostname,
|
||||
site_design,
|
||||
action_id,
|
||||
action_key,
|
||||
task.design_ref,
|
||||
type_filter=asset_type_filter))
|
||||
|
||||
|
@ -64,6 +64,7 @@ class BootAction(base.DrydockPersistentObject, base.DrydockObject):
|
||||
nodename,
|
||||
site_design,
|
||||
action_id,
|
||||
action_key,
|
||||
design_ref,
|
||||
type_filter=None):
|
||||
"""Render all of the assets in this bootaction.
|
||||
@ -77,6 +78,8 @@ class BootAction(base.DrydockPersistentObject, base.DrydockObject):
|
||||
:param site_design: a objects.SiteDesign instance holding the design sets
|
||||
:param action_id: a 128-bit ULID action_id of the boot action
|
||||
the assets are part of
|
||||
:param action_key: a 256-bit random key to authenticate API calls
|
||||
for updating the status of this bootaction
|
||||
:param design_ref: the design ref this boot action was initiated under
|
||||
:param type_filter: optional filter of the types of assets to render
|
||||
"""
|
||||
@ -84,7 +87,7 @@ class BootAction(base.DrydockPersistentObject, base.DrydockObject):
|
||||
for a in self.asset_list:
|
||||
if type_filter is None or (type_filter is not None
|
||||
and a.type == type_filter):
|
||||
a.render(nodename, site_design, action_id, design_ref)
|
||||
a.render(nodename, site_design, action_id, action_key, design_ref)
|
||||
assets.append(a)
|
||||
|
||||
return assets
|
||||
@ -140,7 +143,7 @@ class BootActionAsset(base.DrydockObject):
|
||||
super().__init__(package_list=package_list, permissions=mode, **kwargs)
|
||||
self.rendered_bytes = None
|
||||
|
||||
def render(self, nodename, site_design, action_id, design_ref):
|
||||
def render(self, nodename, site_design, action_id, action_key, design_ref):
|
||||
"""Render this asset into a base64 encoded string.
|
||||
|
||||
The ``nodename`` and ``action_id`` will be used to construct
|
||||
@ -149,10 +152,11 @@ class BootActionAsset(base.DrydockObject):
|
||||
:param nodename: the name of the node where the asset will be deployed
|
||||
:param site_design: instance of objects.SiteDesign
|
||||
:param action_id: a 128-bit ULID boot action id
|
||||
:param action_key: a 256-bit random key for API auth
|
||||
:param design_ref: The design ref this bootaction was initiated under
|
||||
"""
|
||||
tpl_ctx = self._get_template_context(nodename, site_design, action_id,
|
||||
design_ref)
|
||||
action_key, design_ref)
|
||||
|
||||
if self.location is not None:
|
||||
rendered_location = self.execute_pipeline(
|
||||
@ -207,27 +211,30 @@ class BootActionAsset(base.DrydockObject):
|
||||
return package_list
|
||||
|
||||
def _get_template_context(self, nodename, site_design, action_id,
|
||||
design_ref):
|
||||
action_key, design_ref):
|
||||
"""Create a context to be used for template rendering.
|
||||
|
||||
:param nodename: The name of the node for the bootaction
|
||||
:param site_design: The full site design
|
||||
:param action_id: the ULID assigned to the boot action using this context
|
||||
:param action_key: a 256 bit random key for API auth
|
||||
:param design_ref: The design reference representing ``site_design``
|
||||
"""
|
||||
|
||||
return dict(
|
||||
node=self._get_node_context(nodename, site_design),
|
||||
action=self._get_action_context(action_id, design_ref))
|
||||
action=self._get_action_context(action_id, action_key, design_ref))
|
||||
|
||||
def _get_action_context(self, action_id, design_ref):
|
||||
def _get_action_context(self, action_id, action_key, design_ref):
|
||||
"""Create the action-specific context items for template rendering.
|
||||
|
||||
:param action_id: ULID of this boot action
|
||||
:param action_key: random key of this boot action
|
||||
:param design_ref: Design reference representing the site design
|
||||
"""
|
||||
return dict(
|
||||
key=ulid2.ulid_to_base32(action_id),
|
||||
action_id=ulid2.ulid_to_base32(action_id),
|
||||
action_key=action_key.hex(),
|
||||
report_url=config.config_mgr.conf.bootactions.report_url,
|
||||
design_ref=design_ref)
|
||||
|
||||
|
@ -22,4 +22,4 @@ docker run --rm --net host postgres:9.5 psql -h localhost -c "create database dr
|
||||
|
||||
export DRYDOCK_DB_URL="postgresql+psycopg2://drydock:drydock@localhost:5432/drydock"
|
||||
|
||||
sudo docker run --rm -t --net=host -e DRYDOCK_DB_URL="$DRYDOCK_DB_URL" --entrypoint /usr/local/bin/alembic $IMAGE upgrade head
|
||||
sudo docker run --rm -t --net=host -e DRYDOCK_DB_URL="$DRYDOCK_DB_URL" -w /tmp/drydock --entrypoint /usr/local/bin/alembic $IMAGE upgrade head
|
||||
|
@ -14,6 +14,7 @@
|
||||
"""Test that boot action assets are rendered correctly."""
|
||||
|
||||
import ulid2
|
||||
import os
|
||||
|
||||
from drydock_provisioner.statemgmt.state import DrydockState
|
||||
|
||||
@ -32,8 +33,9 @@ class TestBootactionRenderAction(object):
|
||||
|
||||
ba = design_data.get_bootaction('helloworld')
|
||||
action_id = ulid2.generate_binary_ulid()
|
||||
action_key = os.urandom(32)
|
||||
assets = ba.render_assets('compute01', design_data, action_id,
|
||||
design_ref)
|
||||
action_key, design_ref)
|
||||
|
||||
assert 'compute01' in assets[0].rendered_bytes.decode('utf-8')
|
||||
|
||||
@ -50,12 +52,34 @@ class TestBootactionRenderAction(object):
|
||||
|
||||
ba = design_data.get_bootaction('helloworld')
|
||||
action_id = ulid2.generate_binary_ulid()
|
||||
action_key = os.urandom(32)
|
||||
assets = ba.render_assets('compute01', design_data, action_id,
|
||||
design_ref)
|
||||
action_key, design_ref)
|
||||
|
||||
assert 'deckhand_fullsite.yaml' in assets[2].rendered_bytes.decode(
|
||||
'utf-8')
|
||||
|
||||
def test_bootaction_render_key(self, input_files, deckhand_ingester,
|
||||
setup):
|
||||
"""Test that a bootaction can render the correct action_id and
|
||||
action_key needed by the signalling API."""
|
||||
input_file = input_files.join("deckhand_fullsite.yaml")
|
||||
|
||||
design_state = DrydockState()
|
||||
design_ref = "file://%s" % str(input_file)
|
||||
|
||||
design_status, design_data = deckhand_ingester.ingest_data(
|
||||
design_state=design_state, design_ref=design_ref)
|
||||
|
||||
ba = design_data.get_bootaction('helloworld')
|
||||
action_id = ulid2.generate_binary_ulid()
|
||||
action_key = os.urandom(32)
|
||||
assets = ba.render_assets('compute01', design_data, action_id,
|
||||
action_key, design_ref)
|
||||
|
||||
assert action_key.hex() in assets[2].rendered_bytes.decode('utf-8')
|
||||
assert ulid2.ulid_to_base32(action_id) in assets[2].rendered_bytes.decode('utf-8')
|
||||
|
||||
def test_bootaction_network_context(self, input_files,
|
||||
deckhand_orchestrator, setup):
|
||||
"""Test that a boot action creates proper network context."""
|
||||
|
@ -16,6 +16,7 @@
|
||||
import ulid2
|
||||
import tarfile
|
||||
import io
|
||||
import os
|
||||
|
||||
import drydock_provisioner.objects as objects
|
||||
from drydock_provisioner.statemgmt.state import DrydockState
|
||||
@ -39,8 +40,9 @@ class TestClass(object):
|
||||
|
||||
ba = design_data.get_bootaction('helloworld')
|
||||
action_id = ulid2.generate_binary_ulid()
|
||||
action_key = os.urandom(32)
|
||||
assets = ba.render_assets(target_host, design_data, action_id,
|
||||
design_ref)
|
||||
action_key, design_ref)
|
||||
|
||||
assert len(assets) > 0
|
||||
|
||||
|
@ -541,9 +541,11 @@ data:
|
||||
- path: /var/tmp/designref.sh
|
||||
type: file
|
||||
permissions: '500'
|
||||
data: e3sgYWN0aW9uLmRlc2lnbl9yZWYgfX0K
|
||||
data: |
|
||||
{{ action.design_ref }}
|
||||
{{ action.action_id }}
|
||||
{{ action.action_key }}
|
||||
data_pipeline:
|
||||
- base64_decode
|
||||
- utf8_decode
|
||||
- template
|
||||
---
|
||||
|
Loading…
Reference in New Issue
Block a user