Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Renderer to generate the ConfigMap #2120

Merged
merged 6 commits into from
Dec 16, 2019
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
56 changes: 27 additions & 29 deletions buildchain/buildchain/salt_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@


import abc
import base64
import importlib
from pathlib import Path
import sys
Expand Down Expand Up @@ -153,25 +152,6 @@ def _get_parts(self) -> Iterator[str]:
return parts


def salt_embed_text(path: Path, indent: int) -> str:
"""Return the content a text file in usable form by Salt."""
data = ['|']
with path.open(encoding='utf-8') as fp:
for line in fp:
data.append('{}{}'.format(' '*indent, line.rstrip()))
return '\n'.join(data)


def salt_embed_bytes(path: Path, indent: int) -> str:
"""Return the content of a binary file in usable form by Salt."""
data = ['|']
bytestring = path.read_bytes()
b64data = base64.encodebytes(bytestring).decode('utf-8')
for line in b64data.split('\n'):
data.append('{}{}'.format(' '*indent, line.rstrip()))
return '\n'.join(data)


PILLAR_FILES : Tuple[Union[Path, targets.AtomicTarget], ...] = (
Path('pillar/metalk8s/roles/bootstrap.sls'),
Path('pillar/metalk8s/roles/ca.sls'),
Expand Down Expand Up @@ -251,20 +231,38 @@ def salt_embed_bytes(path: Path, indent: int) -> str:
Path('salt/metalk8s/addons/dex/deployed/namespace.sls'),
Path('salt/metalk8s/addons/dex/deployed/tls-secret.sls'),
Path('salt/metalk8s/addons/dex/deployed/clusterrolebinding.sls'),
targets.TemplateFile(
targets.SerializedData(
task_name='theme-configmap.sls',
source=constants.ROOT.joinpath(
'salt/metalk8s/addons/dex/deployed/theme-configmap.sls.in'
),
destination=constants.ISO_ROOT.joinpath(
'salt/metalk8s/addons/dex/deployed/theme-configmap.sls'
),
context={
'branding': salt_embed_bytes(SCALITY_LOGO, indent=4),
'favicon': salt_embed_bytes(SCALITY_FAVICON, indent=4),
'styles': salt_embed_text(LOGIN_STYLE, indent=4),
},
data=targets.SaltState(
shebang='#!jinja | metalk8s_kubernetes',
imports=[],
content=[{
'apiVersion': 'v1',
'kind': 'ConfigMap',
'metadata': {
'name': 'dex-login',
'namespace': 'metalk8s-auth',
},
'data': {
'styles.css': targets.YAMLDocument.text(
LOGIN_STYLE.read_text(encoding='utf-8')
),
},
'binaryData': {
'favicon.png': targets.YAMLDocument.bytestring(
SCALITY_FAVICON.read_bytes()
),
'logo.png': targets.YAMLDocument.bytestring(
SCALITY_LOGO.read_bytes()
)
},
}],
),
file_dep=[SCALITY_LOGO, SCALITY_FAVICON, LOGIN_STYLE],
renderer=targets.Renderer.SLS,
),
Path('salt/metalk8s/addons/prometheus-operator/deployed/chart.sls'),
Path('salt/metalk8s/addons/prometheus-operator/deployed/cleanup.sls'),
Expand Down
6 changes: 4 additions & 2 deletions buildchain/buildchain/targets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
from buildchain.targets.repository import (
Repository, RPMRepository, DEBRepository
)
from buildchain.targets.serialize import Renderer, SerializedData
from buildchain.targets.serialize import (
Renderer, SerializedData, SaltState, YAMLDocument
)
from buildchain.targets.template import TemplateFile

# For mypy, see `--no-implicit-reexport` documentation.
Expand All @@ -29,6 +31,6 @@
'Package', 'RPMPackage', 'DEBPackage',
'RemoteImage',
'Repository', 'RPMRepository', 'DEBRepository',
'Renderer', 'SerializedData',
'Renderer', 'SerializedData', 'SaltState', 'YAMLDocument',
'TemplateFile',
]
91 changes: 89 additions & 2 deletions buildchain/buildchain/targets/serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@

"""Targets to write files from Python objects."""

import base64
import collections
import enum
import json
from pathlib import Path
from typing import Any, Callable, Mapping
from typing import Any, Callable, Dict, IO, Mapping, Sequence

import yaml

from buildchain import types
from buildchain import utils
Expand All @@ -29,18 +33,40 @@ def render_envfile(variables: Mapping[str, str], filepath: Path) -> None:
fp.write('\n')


def render_yaml(data: Sequence[Any], filepath: Path) -> None:
"""Serialize an object as YAML to a given file path."""
with filepath.open('w', encoding='utf-8') as fp:
_yaml_dump(data, fp)


def render_sls(sls: 'SaltState', filepath: Path) -> None:
"""Serialize a Salt state to a given file path."""
with filepath.open('w', encoding='utf-8') as fp:
if sls.shebang:
fp.write(sls.shebang)
fp.write('\n'*2)
if sls.imports:
fp.write('\n'.join(sls.imports))
fp.write('\n'*2)
_yaml_dump(sls.content, fp)


class Renderer(enum.Enum):
"""Supported rendering methods for `SerializedData` targets."""
JSON = 'JSON'
ENV = 'ENV'
SLS = 'SLS'
YAML = 'YAML'


class SerializedData(base.AtomicTarget):
"""Serialize an object into a file with a specific renderer."""

RENDERERS = {
RENDERERS : Dict[Renderer, Callable[[Any, Path], None]] = {
Renderer.JSON: render_json,
Renderer.ENV: render_envfile,
Renderer.YAML: render_yaml,
Renderer.SLS: render_sls,
}

def __init__(
Expand Down Expand Up @@ -95,3 +121,64 @@ def _render(self) -> Callable[[Any, Path], None]:
def _run(self) -> None:
"""Render the file."""
self._render(self._data, self._dest)


# YAML {{{


class YAMLDocument():
"""A YAML document, with an optional preamble (like a shebang)."""
class Literal(str):
"""A large block of text, to be rendered as a block scalar."""

class ByteString(bytes):
"""A binary string, to be rendered as a base64-encoded literal."""

@classmethod
def text(cls, value: str) -> 'YAMLDocument.Literal':
"""Cast the value to a Literal."""
return cls.Literal(value)

@classmethod
def bytestring(cls, value: bytes) -> 'YAMLDocument.ByteString':
"""Cast the value to a ByteString."""
return cls.ByteString(value)


SaltState = collections.namedtuple(
'SaltState', ['content', 'shebang', 'imports']
)


def _literal_representer(dumper: yaml.BaseDumper, data: Any) -> Any:
scalar = yaml.representer.SafeRepresenter.represent_str( # type: ignore
dumper, data
)
scalar.style = '|'
return scalar


def _bytestring_representer(dumper: yaml.BaseDumper, data: Any) -> Any:
return _literal_representer(
dumper, base64.encodebytes(data).decode('utf-8')
)


def _yaml_dump(data: Sequence[Any], fp: IO[Any]) -> None:
dumper = yaml.SafeDumper(fp, sort_keys=False) # type: ignore
dumper.add_representer( # type: ignore
YAMLDocument.Literal, _literal_representer
)
dumper.add_representer( # type: ignore
YAMLDocument.ByteString, _bytestring_representer
)
try:
dumper.open() # type: ignore
for document in data:
dumper.represent(document) # type: ignore
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this then adds the ---?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I've tested locally.

And the code is highly inspired from official PyYAML code.

dumper.close() # type: ignore
finally:
dumper.dispose() # type: ignore


# }}}
14 changes: 14 additions & 0 deletions buildchain/requirements-Darwin.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ idna==2.8 \
macfsevents==0.8.1 \
--hash=sha256:1324b66b356051de662ba87d84f73ada062acd42b047ed1246e60a449f833e10 \
# via doit
pyyaml==5.1.2 \
--hash=sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9 \
--hash=sha256:01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4 \
--hash=sha256:5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8 \
--hash=sha256:5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696 \
--hash=sha256:7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34 \
--hash=sha256:7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9 \
--hash=sha256:87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73 \
--hash=sha256:9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299 \
--hash=sha256:a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b \
--hash=sha256:b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae \
--hash=sha256:b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681 \
--hash=sha256:bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41 \
--hash=sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8
requests==2.22.0 \
--hash=sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4 \
--hash=sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31 \
Expand Down
14 changes: 14 additions & 0 deletions buildchain/requirements-Linux.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ idna==2.8 \
pyinotify==0.9.6 \
--hash=sha256:9c998a5d7606ca835065cdabc013ae6c66eb9ea76a00a1e3bc6e0cfe2b4f71f4 \
# via doit
pyyaml==5.1.2 \
--hash=sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9 \
--hash=sha256:01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4 \
--hash=sha256:5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8 \
--hash=sha256:5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696 \
--hash=sha256:7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34 \
--hash=sha256:7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9 \
--hash=sha256:87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73 \
--hash=sha256:9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299 \
--hash=sha256:a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b \
--hash=sha256:b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae \
--hash=sha256:b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681 \
--hash=sha256:bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41 \
--hash=sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8
requests==2.22.0 \
--hash=sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4 \
--hash=sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31 \
Expand Down
1 change: 1 addition & 0 deletions buildchain/requirements.in
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
doit ~= 0.31.1
docker ~= 4.1.0
PyYAML ~= 5.1.2
14 changes: 0 additions & 14 deletions salt/metalk8s/addons/dex/deployed/theme-configmap.sls.in

This file was deleted.