refactor devops_c4k_mixin to arch

This commit is contained in:
Michael Jerger 2023-03-12 19:09:32 +01:00
parent eec7392470
commit dd85b7b95b
10 changed files with 128 additions and 63 deletions

View file

@ -3,13 +3,38 @@
```mermaid
classDiagram
class Build {
__init__(project, config)
do_sth(project)
stage
name
project_root_path
module
build_dir_name
}
class C4kBuild {
executabel_name
c4k_mixin_config
c4k_mixin_auth
}
class DnsRecord {
fqdn
ipv4
ipv6
}
C4kBuild *-- DnsRecord
```
# Infrastructure
```mermaid
classDiagram
class ProjectRepository {
get_build(project): Build
set_build(project, build)
}
```

View file

@ -19,8 +19,8 @@ from .devops_terraform_build import DevopsTerraformBuild, create_devops_terrafor
from .devops_build import DevopsBuild, create_devops_build_config, get_devops_build, get_tag_from_latest_commit
from .credential import gopass_password_from_path, gopass_field_from_path
from .domain import Validateable, Build, DockerBuild, C4kBuild
from .application import DockerBuildService, C4kBuildService
from .domain import Validateable, DnsRecord, Build, DockerBuild, C4kBuild
from .application import DockerBuildService
from .infrastructure import ProjectRepository, ResourceApi, FileApi, DockerApi, ExecutionApi
__version__ = "${version}"

View file

@ -48,20 +48,3 @@ class DockerBuildService:
def test(self, build: Build):
self.docker_api.test(build.name(), build.build_path())
class C4kBuildService:
def __init__(self):
self.file_api = FileApi()
self.execution_api = ExecutionApi()
def write_c4k_config(self, c4k_build: C4kBuild):
path = c4k_build.build.build_path() + "/out_c4k_config.yaml"
self.file_api.write_yaml_to_file(path, c4k_build.config())
def write_c4k_auth(self, c4k_build: C4kBuild):
path = c4k_build.build.build_path() + "/out_c4k_auth.yaml"
self.file_api.write_yaml_to_file(path, c4k_build.c4k_mixin_auth)
def c4k_apply(self, c4k_build: C4kBuild, dry_run=False):
return self.execution_api.execute(c4k_build.command(), dry_run)

View file

@ -1,9 +1,11 @@
from .domain import C4kBuild
from .application import C4kBuildService
from .domain import C4kBuild, DnsRecord
from .devops_build import DevopsBuild
from .credential import gopass_field_from_path, gopass_password_from_path
from .infrastructure import ProjectRepository, FileApi, ExecutionApi
@deprecation.deprecated(deprecated_in="3.2")
# create objects direct instead
def add_c4k_mixin_config(
config,
c4k_config_dict,
@ -42,17 +44,32 @@ def add_c4k_mixin_config(
return config
#TODO: refactor this to C4kBuild
class C4kMixin(DevopsBuild):
def __init__(self, project, config):
super().__init__(project, config)
self.c4k_build = C4kBuild(self.build, project, config)
self.c4k_build_service = C4kBuildService()
self.execution_api = ExecutionApi()
c4k_build = C4kBuild(config)
self.repo.set_c4k_build(self.project, c4k_build)
def update_runtime_config(self, dns_record: DnsRecord):
c4k_build = self.repo.get_c4k_build(self.project)
c4k_build.update_runtime_config(dns_record)
self.repo.set_c4k_build(self.project, c4k_build)
def write_c4k_config(self):
self.c4k_build_service.write_c4k_config(self.c4k_build)
build = self.repo.get_build(self.project)
c4k_build = self.repo.get_c4k_build(self.project)
path = build.build_path() + "/out_c4k_config.yaml"
self.file_api.write_yaml_to_file(path, c4k_build.config())
def write_c4k_auth(self):
self.c4k_build_service.write_c4k_auth(self.c4k_build)
build = self.repo.get_build(self.project)
c4k_build = self.repo.get_c4k_build(self.project)
path = build.build_path() + "/out_c4k_auth.yaml"
self.file_api.write_yaml_to_file(path, c4k_build.c4k_mixin_auth)
def c4k_apply(self, dry_run=False):
self.c4k_build_service.c4k_apply(self.c4k_build, dry_run)
build = self.repo.get_build(self.project)
c4k_build = self.repo.get_c4k_build(self.project)
return self.execution_api.execute(c4k_build.command(build), dry_run)

View file

@ -2,7 +2,8 @@ import deprecation
from .domain import Build
from .infrastructure import ProjectRepository, FileApi
@deprecation.deprecated(deprecated_in="3.2")
# create objects direct instead
def create_devops_build_config(
stage, project_root_path, module, build_dir_name="target"
):
@ -51,4 +52,5 @@ class DevopsBuild:
return build.build_path()
def initialize_build_dir(self):
build = self.repo.get_build(self.project)
self.file_api.clean_dir(build.build_path())

View file

@ -2,7 +2,8 @@ from .domain import DockerBuild
from .application import DockerBuildService
from .devops_build import DevopsBuild, create_devops_build_config
@deprecation.deprecated(deprecated_in="3.2")
# create objects direct instead
def create_devops_docker_build_config(
stage,
project_root_path,

View file

@ -18,6 +18,20 @@ class Validateable:
return len(self.validate()) < 1
class DnsRecord(Validateable):
def __init__(self, fqdn, ipv4=None, ipv6=None):
self.fqdn = fqdn
self.ipv4 = ipv4
self.ipv6 = ipv6
def validate(self) -> List[str]:
result = []
result += self.__validate_is_not_empty__("fqdn")
if (not self.ipv4) and (not self.ipv6):
result.append("ipv4 & ipv6 may not both be empty.")
return result
class Build(Validateable):
def __init__(self, config):
self.stage = config["stage"]
@ -37,12 +51,6 @@ class Build(Validateable):
path = [self.project_root_path, self.build_dir_name, self.name, self.module]
return "/".join(filter_none(path))
# TODO: these functions should be located at TerraformBuild later on.
def update_runtime_config(self, fqdn, ipv4, ipv6):
self.__put__("fqdn", fqdn)
self.__put__("ipv4", ipv4)
self.__put__("ipv6", ipv6)
def __put__(self, key, value):
self.stack[key] = value
@ -57,7 +65,7 @@ class Build(Validateable):
class DockerBuild(Validateable):
def __init__(self, config):
def __init__(self, config: map):
self.dockerhub_user = config["dockerhub_user"]
self.dockerhub_password = config["dockerhub_password"]
self.use_package_common_files = config["use_package_common_files"]
@ -71,31 +79,37 @@ class DockerBuild(Validateable):
class C4kBuild(Validateable):
def __init__(self, build: Build, project, config):
self.build = build
def __init__(self, config: map):
tmp_executabel_name = config["C4kMixin"]["executabel_name"]
if not tmp_executabel_name:
tmp_executabel_name = self.build.module
tmp_executabel_name = config["module"]
self.executabel_name = tmp_executabel_name
self.c4k_mixin_config = config["C4kMixin"]["config"]
self.c4k_mixin_auth = config["C4kMixin"]["auth"]
tmp = self.c4k_mixin_config["mon-cfg"]
tmp.update(
{"cluster-name": self.build.module, "cluster-stage": self.build.stage}
)
tmp.update({"cluster-name": config["module"], "cluster-stage": config["stage"]})
self.c4k_mixin_config.update({"mon-cfg": tmp})
self.dns_record = None
def update_runtime_config(self, fqdn, ipv4, ipv6):
self.build.update_runtime_config(fqdn, ipv4, ipv6)
# TODO: these functions should be located at TerraformBuild later on.
def update_runtime_config(self, dns_record: DnsRecord):
self.dns_record = dns_record
def validate(self) -> List[str]:
result = []
result += self.__validate_is_not_empty__("fqdn")
if self.dns_record:
result += self.dns_record.validate()
return result
def config(self):
fqdn = self.build.__get__("fqdn")
fqdn = self.dns_record.fqdn
self.c4k_mixin_config.update({"fqdn": fqdn})
return self.c4k_mixin_config
def command(self):
module = self.build.module
build_path = self.build.build_path()
def command(self, build: Build):
module = build.module
build_path = build.build_path()
config_path = f"{build_path}/out_c4k_config.yaml"
auth_path = f"{build_path}/out_c4k_auth.yaml"
output_path = f"{build_path}/out_{module}.yaml"

View file

@ -3,7 +3,7 @@ from sys import stdout
from pkg_resources import resource_string
from os import chmod
import yaml
from .domain import Build, DockerBuild
from .domain import Build, DockerBuild, C4kBuild
from .python_util import execute
@ -20,6 +20,12 @@ class ProjectRepository:
def set_docker_build(self, project, build: DockerBuild):
project.set_property("docker_build", build)
def get_c4k_build(self, project) -> C4kBuild:
return project.get_property("c4k_build")
def set_c4k_build(self, project, build: C4kBuild):
project.set_property("c4k_build", build)
class ResourceApi:
def read_resource(self, path: str) -> bytes:

View file

@ -1,5 +1,6 @@
import os
from pybuilder.core import Project
from src.main.python.ddadevops.domain import DnsRecord
from src.main.python.ddadevops.c4k_mixin import C4kMixin, add_c4k_mixin_config
class MyC4kMixin(C4kMixin):
@ -32,14 +33,15 @@ def test_c4k_mixin(tmp_path):
mixin.initialize_build_dir()
assert mixin.build_path() == f'{tmp_path_str}/{build_dir}/{project_name}/{module_name}'
mixin.build.update_runtime_config('test.de', None, None)
mixin.update_runtime_config(DnsRecord('test.de', ipv6="1::"))
sut = mixin.repo.get_c4k_build(mixin.project)
assert 'fqdn' in sut.config()
assert 'mon-cfg' in sut.config()
assert 'mon-auth' in sut.c4k_mixin_auth
mixin.write_c4k_config()
assert 'fqdn' in mixin.c4k_build.config()
assert 'mon-cfg' in mixin.c4k_build.config()
assert os.path.exists(f'{mixin.build_path()}/out_c4k_config.yaml')
mixin.write_c4k_auth()
assert 'mon-auth' in mixin.c4k_build.c4k_mixin_auth
assert os.path.exists(f'{mixin.build_path()}/out_c4k_auth.yaml')

View file

@ -1,5 +1,5 @@
from pybuilder.core import Project
from src.main.python.ddadevops.domain import Validateable, C4kBuild, Build
from src.main.python.ddadevops.domain import Validateable, DnsRecord, C4kBuild, Build
from src.main.python.ddadevops.c4k_mixin import add_c4k_mixin_config
@ -41,6 +41,20 @@ def test_validate_with_reason():
assert sut.validate()[0] == "Field 'field' may not be empty."
def test_should_validate_DnsRecord():
sut = DnsRecord(None)
assert not sut.is_valid()
sut = DnsRecord('name')
assert not sut.is_valid()
sut = DnsRecord('name', ipv4='1.2.3.4')
assert sut.is_valid()
sut = DnsRecord('name', ipv6='1::')
assert sut.is_valid()
def test_c4k_build_should_update_fqdn(tmp_path):
project = Project(str(tmp_path), name="name")
project_config = {
@ -63,8 +77,9 @@ def test_c4k_build_should_update_fqdn(tmp_path):
grafana_cloud_user="user",
grafana_cloud_password="password",
)
sut = C4kBuild(Build(project_config), project, project_config)
sut.update_runtime_config("test.de", None, None)
build = Build(project_config)
sut = C4kBuild(project_config)
sut.update_runtime_config(DnsRecord("test.de", ipv6="1::"))
assert {
"issuer": "staging",
@ -85,8 +100,6 @@ def test_c4k_build_should_update_fqdn(tmp_path):
},
} == sut.c4k_mixin_auth
sut.update_runtime_config
def test_c4k_build_should_calculate_command(tmp_path):
project = Project(str(tmp_path), name="name")
@ -104,13 +117,14 @@ def test_c4k_build_should_calculate_command(tmp_path):
grafana_cloud_user="user",
grafana_cloud_password="password",
)
sut = C4kBuild(Build(project_config), project, project_config)
build = Build(project_config)
sut = C4kBuild(project_config)
assert (
"c4k-module-standalone.jar "
+ "/target/name/module/out_c4k_config.yaml "
+ "/target/name/module/out_c4k_auth.yaml > "
+ "/target/name/module/out_module.yaml"
== sut.command()
== sut.command(build)
)
project_config = {
@ -128,12 +142,13 @@ def test_c4k_build_should_calculate_command(tmp_path):
grafana_cloud_user="user",
grafana_cloud_password="password",
)
sut = C4kBuild(Build(project_config), project, project_config)
build = Build(project_config)
sut = C4kBuild(project_config)
assert (
"c4k-executabel_name-standalone.jar "
+ "/target/name/module/out_c4k_config.yaml "
+ "/target/name/module/out_c4k_auth.yaml > "
+ "/target/name/module/out_module.yaml"
== sut.command()
== sut.command(build)
)