Merge branch 'provs_k3s_to_ddd' into 'ddd-intro'
refactor provs-k3s-build to DDD See merge request domaindrivenarchitecture/dda-devops-build!13
This commit is contained in:
commit
3c6e0cfc12
19 changed files with 270 additions and 195 deletions
2
build.py
2
build.py
|
@ -28,7 +28,7 @@ use_plugin("python.distutils")
|
|||
default_task = "publish"
|
||||
|
||||
name = "ddadevops"
|
||||
version = "4.0.0-dev45"
|
||||
version = "4.0.0-dev47"
|
||||
summary = "tools to support builds combining gopass, terraform, dda-pallet, aws & hetzner-cloud"
|
||||
description = __doc__
|
||||
authors = [Author("meissa GmbH", "buero@meissa-gmbh.de")]
|
||||
|
|
|
@ -72,8 +72,8 @@ classDiagram
|
|||
tag_and_push_release()
|
||||
}
|
||||
|
||||
class ProvsK3sMixin {
|
||||
// ProvsK3sMixin -> ProvsK3sBuild
|
||||
class ProvsK3sBuild {
|
||||
// ProvsK3sBuild -> ProvsK3sBuild
|
||||
def update_runtime_config(fqdn, ipv4, ipv6=None)
|
||||
write_provs_config()
|
||||
provs_apply(dry_run=False)
|
||||
|
@ -95,7 +95,7 @@ classDiagram
|
|||
DevopsTerraformBuild <|-- DigitaloceanTerraformBuild
|
||||
DevopsTerraformBuild <|--ExoscaleMixin
|
||||
DevopsTerraformBuild <|--HetznerMixin
|
||||
DevopsBuild <|-- ProvsK3sMixin
|
||||
DevopsBuild <|-- ProvsK3sBuild
|
||||
DigitaloceanTerraformBuild <|-- DigitaloceanBackendPropertiesMixin
|
||||
AwsBackendPropertiesMixin <|-- AwsMfaMixin
|
||||
|
||||
|
|
|
@ -25,6 +25,16 @@ classDiagram
|
|||
c4k_executabel_name
|
||||
c4k_mixin_config
|
||||
c4k_mixin_auth
|
||||
c4k_grafana_cloud_user
|
||||
c4k_grafana_cloud_password
|
||||
}
|
||||
|
||||
class ProvsK3s {
|
||||
k3s_provision_user
|
||||
k3s_letsencrypt_email
|
||||
k3s_letsencrypt_endpoint
|
||||
k3s_enable_echo
|
||||
k3s_app_filename_to_provision
|
||||
}
|
||||
|
||||
class DnsRecord {
|
||||
|
@ -71,11 +81,13 @@ classDiagram
|
|||
|
||||
Devops *-- "0..1" Image: spcialized_builds
|
||||
Devops *-- "0..1" C4k: spcialized_builds
|
||||
Devops *-- "0..1" ProvsK3s: spcialized_builds
|
||||
Devops *-- "0..1" Release: mixins
|
||||
Release o-- "0..1" BuildFile: primary_build_file
|
||||
Release o-- "0..n" BuildFile: secondary_build_files
|
||||
BuildFile *-- "1" Version
|
||||
C4k *-- DnsRecord
|
||||
C4k *-- DnsRecord: dns_record
|
||||
ProvsK3s *-- DnsRecord: provision_dns
|
||||
Credentials *-- "0..n" CredentialMapping: mappings
|
||||
|
||||
```
|
||||
|
|
|
@ -5,14 +5,14 @@ terraform, dda-pallet, aws & hetzner-cloud.
|
|||
"""
|
||||
|
||||
from .python_util import execute
|
||||
from .provs_k3s_mixin import ProvsK3sMixin, add_provs_k3s_mixin_config
|
||||
from .provs_k3s_build import ProvsK3sBuild
|
||||
from .aws_mfa_mixin import AwsMfaMixin, add_aws_mfa_mixin_config
|
||||
from .aws_backend_properties_mixin import AwsBackendPropertiesMixin, add_aws_backend_properties_mixin_config
|
||||
from .c4k_build import C4kBuild, add_c4k_mixin_config
|
||||
from .c4k_build import C4kBuild
|
||||
from .digitalocean_backend_properties_mixin import DigitaloceanBackendPropertiesMixin, add_digitalocean_backend_properties_mixin_config
|
||||
from .digitalocean_terraform_build import DigitaloceanTerraformBuild, create_digitalocean_terraform_build_config
|
||||
from .hetzner_mixin import HetznerMixin, add_hetzner_mixin_config
|
||||
from .devops_image_build import DevopsImageBuild, create_devops_docker_build_config
|
||||
from .devops_image_build import DevopsImageBuild
|
||||
from .devops_terraform_build import DevopsTerraformBuild, create_devops_terraform_build_config
|
||||
from .devops_build import DevopsBuild, create_devops_build_config, get_devops_build
|
||||
from .credential import gopass_password_from_path, gopass_field_from_path
|
||||
|
|
|
@ -1,33 +1,33 @@
|
|||
from dda_python_terraform import Terraform
|
||||
from .devops_terraform_build import DevopsTerraformBuild
|
||||
|
||||
|
||||
def add_aws_backend_properties_mixin_config(config, account_name):
|
||||
config.update({'AwsBackendPropertiesMixin':
|
||||
{'account_name': account_name}})
|
||||
config.update({"AwsBackendPropertiesMixin": {"account_name": account_name}})
|
||||
return config
|
||||
|
||||
class AwsBackendPropertiesMixin(DevopsTerraformBuild):
|
||||
|
||||
class AwsBackendPropertiesMixin(DevopsTerraformBuild):
|
||||
def __init__(self, project, config):
|
||||
super().__init__(project, config)
|
||||
aws_mixin_config = config['AwsBackendPropertiesMixin']
|
||||
self.account_name = aws_mixin_config['account_name']
|
||||
self.backend_config = "backend." + self.account_name + "." + self.stage + ".properties"
|
||||
aws_mixin_config = config["AwsBackendPropertiesMixin"]
|
||||
self.account_name = aws_mixin_config["account_name"]
|
||||
self.backend_config = (
|
||||
"backend." + self.account_name + "." + self.stage + ".properties"
|
||||
)
|
||||
self.additional_tfvar_files.append(self.backend_config)
|
||||
|
||||
def project_vars(self):
|
||||
ret = super().project_vars()
|
||||
ret.update({'account_name': self.account_name})
|
||||
ret.update({"account_name": self.account_name})
|
||||
return ret
|
||||
|
||||
def copy_build_resources_from_package(self):
|
||||
super().copy_build_resources_from_package()
|
||||
self.copy_build_resource_file_from_package('provider_registry.tf')
|
||||
self.copy_build_resource_file_from_package('aws_provider.tf')
|
||||
self.copy_build_resource_file_from_package(
|
||||
'aws_backend_properties_vars.tf')
|
||||
self.copy_build_resource_file_from_package(
|
||||
'aws_backend_with_properties.tf')
|
||||
self.copy_build_resource_file_from_package("provider_registry.tf")
|
||||
self.copy_build_resource_file_from_package("aws_provider.tf")
|
||||
self.copy_build_resource_file_from_package("aws_backend_properties_vars.tf")
|
||||
self.copy_build_resource_file_from_package("aws_backend_with_properties.tf")
|
||||
|
||||
def copy_local_state(self):
|
||||
pass
|
||||
|
@ -36,14 +36,17 @@ class AwsBackendPropertiesMixin(DevopsTerraformBuild):
|
|||
pass
|
||||
|
||||
def init_client(self):
|
||||
terraform = Terraform(working_dir=self.build_path(), terraform_semantic_version=self.terraform_semantic_version)
|
||||
terraform = Terraform(
|
||||
working_dir=self.build_path(),
|
||||
terraform_semantic_version=self.terraform_semantic_version,
|
||||
)
|
||||
terraform.init(backend_config=self.backend_config)
|
||||
self.print_terraform_command(terraform)
|
||||
if self.use_workspace:
|
||||
try:
|
||||
terraform.workspace('select', self.stage)
|
||||
terraform.workspace("select", self.stage)
|
||||
self.print_terraform_command(terraform)
|
||||
except:
|
||||
terraform.workspace('new', self.stage)
|
||||
terraform.workspace("new", self.stage)
|
||||
self.print_terraform_command(terraform)
|
||||
return terraform
|
||||
|
|
|
@ -43,6 +43,7 @@ def add_c4k_mixin_config(
|
|||
)
|
||||
return config
|
||||
|
||||
|
||||
class C4kBuild(DevopsBuild):
|
||||
def __init__(self, project, config):
|
||||
super().__init__(project, config)
|
||||
|
|
|
@ -44,13 +44,13 @@ def create_devops_terraform_build_config(stage,
|
|||
class DevopsTerraformBuild(DevopsBuild):
|
||||
|
||||
def __init__(self, project, config):
|
||||
inp = {}
|
||||
inp = config.copy()
|
||||
inp["name"]=project.name
|
||||
inp["module"]=config.get("module")
|
||||
inp["stage"]=config.get("stage")
|
||||
inp["project_root_path"]=config.get("project_root_path")
|
||||
inp["build_types"]=[]
|
||||
inp["mixin_types"]=[]
|
||||
inp["build_types"]=config.get("build_types", [])
|
||||
inp["mixin_types"]=config.get("mixin_types", [])
|
||||
super().__init__(project, inp)
|
||||
project.build_depends_on('dda-python-terraform')
|
||||
self.additional_vars = config['additional_vars']
|
||||
|
|
|
@ -1,55 +1,55 @@
|
|||
from dda_python_terraform import Terraform
|
||||
from .digitalocean_terraform_build import DigitaloceanTerraformBuild
|
||||
|
||||
def add_digitalocean_backend_properties_mixin_config(config,
|
||||
account_name,
|
||||
endpoint,
|
||||
bucket,
|
||||
key,
|
||||
region='eu-central-1'):
|
||||
config.update({'DigitaloceanBackendPropertiesMixin':
|
||||
{'account_name': account_name,
|
||||
'endpoint': endpoint,
|
||||
'bucket': bucket,
|
||||
'key': key,
|
||||
'region': region}})
|
||||
|
||||
def add_digitalocean_backend_properties_mixin_config(
|
||||
config, account_name, endpoint, bucket, key, region="eu-central-1"
|
||||
):
|
||||
config.update(
|
||||
{
|
||||
"DigitaloceanBackendPropertiesMixin": {
|
||||
"account_name": account_name,
|
||||
"endpoint": endpoint,
|
||||
"bucket": bucket,
|
||||
"key": key,
|
||||
"region": region,
|
||||
}
|
||||
}
|
||||
)
|
||||
return config
|
||||
|
||||
|
||||
class DigitaloceanBackendPropertiesMixin(DigitaloceanTerraformBuild):
|
||||
|
||||
def __init__(self, project, config):
|
||||
super().__init__(project, config)
|
||||
do_mixin_config = config['DigitaloceanBackendPropertiesMixin']
|
||||
self.account_name = do_mixin_config['account_name']
|
||||
self.endpoint = do_mixin_config['endpoint']
|
||||
self.bucket = do_mixin_config['bucket']
|
||||
self.key = do_mixin_config['account_name'] + \
|
||||
'/' + do_mixin_config['key']
|
||||
self.region = do_mixin_config['region']
|
||||
do_mixin_config = config["DigitaloceanBackendPropertiesMixin"]
|
||||
self.account_name = do_mixin_config["account_name"]
|
||||
self.endpoint = do_mixin_config["endpoint"]
|
||||
self.bucket = do_mixin_config["bucket"]
|
||||
self.key = do_mixin_config["account_name"] + "/" + do_mixin_config["key"]
|
||||
self.region = do_mixin_config["region"]
|
||||
self.backend_config = {
|
||||
'access_key': self.do_spaces_access_id,
|
||||
'secret_key': self.do_spaces_secret_key,
|
||||
'endpoint': self.endpoint,
|
||||
'bucket': self.bucket,
|
||||
'key': self.key,
|
||||
'region': self.region}
|
||||
"access_key": self.do_spaces_access_id,
|
||||
"secret_key": self.do_spaces_secret_key,
|
||||
"endpoint": self.endpoint,
|
||||
"bucket": self.bucket,
|
||||
"key": self.key,
|
||||
"region": self.region,
|
||||
}
|
||||
|
||||
def project_vars(self):
|
||||
ret = super().project_vars()
|
||||
ret.update({'account_name': self.account_name})
|
||||
ret.update({'endpoint': self.endpoint})
|
||||
ret.update({'bucket': self.bucket})
|
||||
ret.update({'key': self.key})
|
||||
ret.update({'region': self.region})
|
||||
ret.update({"account_name": self.account_name})
|
||||
ret.update({"endpoint": self.endpoint})
|
||||
ret.update({"bucket": self.bucket})
|
||||
ret.update({"key": self.key})
|
||||
ret.update({"region": self.region})
|
||||
return ret
|
||||
|
||||
def copy_build_resources_from_package(self):
|
||||
super().copy_build_resources_from_package()
|
||||
self.copy_build_resource_file_from_package(
|
||||
'do_backend_properties_vars.tf')
|
||||
self.copy_build_resource_file_from_package(
|
||||
'do_backend_with_properties.tf')
|
||||
self.copy_build_resource_file_from_package("do_backend_properties_vars.tf")
|
||||
self.copy_build_resource_file_from_package("do_backend_with_properties.tf")
|
||||
|
||||
def copy_local_state(self):
|
||||
pass
|
||||
|
@ -58,15 +58,17 @@ class DigitaloceanBackendPropertiesMixin(DigitaloceanTerraformBuild):
|
|||
pass
|
||||
|
||||
def init_client(self):
|
||||
terraform = Terraform(working_dir=self.build_path(),
|
||||
terraform_semantic_version=self.terraform_semantic_version)
|
||||
terraform = Terraform(
|
||||
working_dir=self.build_path(),
|
||||
terraform_semantic_version=self.terraform_semantic_version,
|
||||
)
|
||||
terraform.init(backend_config=self.backend_config)
|
||||
self.print_terraform_command(terraform)
|
||||
if self.use_workspace:
|
||||
try:
|
||||
terraform.workspace('select', self.stage)
|
||||
terraform.workspace("select", self.stage)
|
||||
self.print_terraform_command(terraform)
|
||||
except:
|
||||
terraform.workspace('new', self.stage)
|
||||
terraform.workspace("new", self.stage)
|
||||
self.print_terraform_command(terraform)
|
||||
return terraform
|
||||
|
|
|
@ -2,6 +2,7 @@ from .common import Validateable, DnsRecord, Devops, BuildType, MixinType, Relea
|
|||
from .devops_factory import DevopsFactory
|
||||
from .image import Image
|
||||
from .c4k import C4k
|
||||
from .provs_k3s import K3s
|
||||
from .release import Release
|
||||
from .credentials import Credentials, CredentialMapping, GopassType
|
||||
from .version import Version
|
||||
|
|
|
@ -21,9 +21,9 @@ class C4k(Validateable):
|
|||
self.c4k_grafana_cloud_password = inp.get('c4k_grafana_cloud_password')
|
||||
self.dns_record: Optional[DnsRecord] = None
|
||||
|
||||
# TODO: these functions should be located at TerraformBuild later on.
|
||||
def update_runtime_config(self, dns_record: DnsRecord):
|
||||
self.dns_record = dns_record
|
||||
self.throw_if_invalid()
|
||||
|
||||
def validate(self) -> List[str]:
|
||||
result = []
|
||||
|
|
|
@ -9,6 +9,7 @@ def filter_none(list_to_filter):
|
|||
class BuildType(Enum):
|
||||
IMAGE = 0
|
||||
C4K = 1
|
||||
K3S = 2
|
||||
|
||||
|
||||
class MixinType(Enum):
|
||||
|
|
|
@ -2,6 +2,7 @@ from typing import List, Optional, Dict
|
|||
from .common import Validateable, Devops, BuildType, MixinType
|
||||
from .image import Image
|
||||
from .c4k import C4k
|
||||
from .provs_k3s import K3s
|
||||
from .release import Release
|
||||
from .version import Version
|
||||
|
||||
|
@ -19,6 +20,8 @@ class DevopsFactory:
|
|||
specialized_builds[BuildType.IMAGE] = Image(inp)
|
||||
if BuildType.C4K in build_types:
|
||||
specialized_builds[BuildType.C4K] = C4k(inp)
|
||||
if BuildType.K3S in build_types:
|
||||
specialized_builds[BuildType.K3S] = K3s(inp)
|
||||
|
||||
mixins: Dict[MixinType, Validateable] = {}
|
||||
if MixinType.RELEASE in mixin_types:
|
||||
|
|
93
src/main/python/ddadevops/domain/provs_k3s.py
Normal file
93
src/main/python/ddadevops/domain/provs_k3s.py
Normal file
|
@ -0,0 +1,93 @@
|
|||
from typing import List, Optional
|
||||
from string import Template
|
||||
from .common import (
|
||||
Validateable,
|
||||
DnsRecord,
|
||||
Devops,
|
||||
)
|
||||
|
||||
CONFIG_BASE = """
|
||||
fqdn: $fqdn
|
||||
"""
|
||||
CONFIG_IPV4 = """node:
|
||||
ipv4: $ipv4
|
||||
"""
|
||||
CONFIG_IPV6 = """ ipv6: $ipv6
|
||||
"""
|
||||
CONFIG_CERTMANAGER = """certmanager:
|
||||
email: $letsencrypt_email
|
||||
letsencryptEndpoint: $letsencrypt_endpoint
|
||||
"""
|
||||
CONFIG_ECHO = """echo: $echo
|
||||
"""
|
||||
|
||||
|
||||
class K3s(Validateable):
|
||||
def __init__(self, inp: dict):
|
||||
self.k3s_provision_user = inp.get("k3s_provision_user")
|
||||
self.k3s_letsencrypt_email = inp.get("k3s_letsencrypt_email")
|
||||
self.k3s_letsencrypt_endpoint = inp.get("k3s_letsencrypt_endpoint")
|
||||
self.k3s_app_filename_to_provision = inp.get("k3s_app_filename_to_provision")
|
||||
self.k3s_enable_echo = inp.get("k3s_enable_echo", "false")
|
||||
self.k3s_provs_template = inp.get("k3s_provs_template", None)
|
||||
self.provision_dns: Optional[DnsRecord] = None
|
||||
|
||||
def validate(self) -> List[str]:
|
||||
result = []
|
||||
result += self.__validate_is_not_empty__("k3s_provision_user")
|
||||
result += self.__validate_is_not_empty__("k3s_letsencrypt_email")
|
||||
result += self.__validate_is_not_empty__("k3s_letsencrypt_endpoint")
|
||||
result += self.__validate_is_not_empty__("k3s_app_filename_to_provision")
|
||||
if self.provision_dns:
|
||||
result += self.provision_dns.validate()
|
||||
return result
|
||||
|
||||
def update_runtime_config(self, dns_record: DnsRecord):
|
||||
self.provision_dns = dns_record
|
||||
self.throw_if_invalid()
|
||||
|
||||
def provs_config(self) -> str:
|
||||
if not self.provision_dns:
|
||||
raise ValueError("provision_dns was not set.")
|
||||
substitutes = {
|
||||
"fqdn": self.provision_dns.fqdn,
|
||||
}
|
||||
if self.provision_dns.ipv4 is not None:
|
||||
substitutes["ipv4"] = self.provision_dns.ipv4
|
||||
if self.provision_dns.ipv6 is not None:
|
||||
substitutes["ipv6"] = self.provision_dns.ipv6
|
||||
if self.k3s_letsencrypt_email is not None:
|
||||
substitutes["letsencrypt_email"] = self.k3s_letsencrypt_email
|
||||
if self.k3s_letsencrypt_endpoint is not None:
|
||||
substitutes["letsencrypt_endpoint"] = self.k3s_letsencrypt_endpoint
|
||||
if self.k3s_enable_echo is not None:
|
||||
substitutes["echo"] = self.k3s_enable_echo
|
||||
return self.__config_template__().substitute(substitutes)
|
||||
|
||||
def command(self, devops: Devops):
|
||||
if not self.provision_dns:
|
||||
raise ValueError("provision_dns was not set.")
|
||||
cmd = [
|
||||
"provs-server.jar",
|
||||
"k3s",
|
||||
f"{self.k3s_provision_user}@{self.provision_dns.fqdn}",
|
||||
"-c",
|
||||
f"{devops.build_path()}/out_k3sServerConfig.yaml",
|
||||
"-a",
|
||||
f"{devops.build_path()}/{self.k3s_app_filename_to_provision}",
|
||||
]
|
||||
return " ".join(cmd)
|
||||
|
||||
def __config_template__(self) -> Template:
|
||||
template_text = self.k3s_provs_template
|
||||
if template_text is None:
|
||||
template_text = CONFIG_BASE
|
||||
if self.k3s_letsencrypt_endpoint is not None:
|
||||
template_text += CONFIG_CERTMANAGER
|
||||
if self.k3s_enable_echo is not None:
|
||||
template_text += CONFIG_ECHO
|
||||
if self.provision_dns.ipv4 is not None:
|
||||
template_text += CONFIG_IPV4
|
||||
if self.provision_dns.ipv6 is not None:
|
||||
template_text += CONFIG_IPV6
|
||||
return Template(template_text)
|
|
@ -98,12 +98,15 @@ class ExecutionApi:
|
|||
output = output.rstrip()
|
||||
return output
|
||||
|
||||
def execute_live(self, command):
|
||||
process = Popen(command, stdout=PIPE)
|
||||
for line in iter(process.stdout.readline, b""):
|
||||
print(line.decode("utf-8"), end="")
|
||||
process.stdout.close()
|
||||
process.wait()
|
||||
def execute_live(self, command, dry_run=False):
|
||||
if dry_run:
|
||||
print(command)
|
||||
else:
|
||||
process = Popen(command, stdout=PIPE)
|
||||
for line in iter(process.stdout.readline, b""):
|
||||
print(line.decode("utf-8"), end="")
|
||||
process.stdout.close()
|
||||
process.wait()
|
||||
|
||||
|
||||
class EnvironmentApi:
|
||||
|
|
37
src/main/python/ddadevops/provs_k3s_build.py
Normal file
37
src/main/python/ddadevops/provs_k3s_build.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
from .domain import DnsRecord, BuildType
|
||||
from .infrastructure import ExecutionApi
|
||||
from .devops_build import DevopsBuild
|
||||
|
||||
|
||||
class ProvsK3sBuild(DevopsBuild):
|
||||
def __init__(self, project, config):
|
||||
inp = config.copy()
|
||||
inp["name"] = project.name
|
||||
inp["module"] = config.get("module")
|
||||
inp["stage"] = config.get("stage")
|
||||
inp["project_root_path"] = config.get("project_root_path")
|
||||
inp["build_types"] = config.get("build_types", [])
|
||||
inp["mixin_types"] = config.get("mixin_types", [])
|
||||
super().__init__(project, inp)
|
||||
self.execution_api = ExecutionApi()
|
||||
devops = self.devops_repo.get_devops(self.project)
|
||||
if BuildType.K3S not in devops.specialized_builds:
|
||||
raise ValueError("K3SBuild requires BuildType.K3S")
|
||||
|
||||
def update_runtime_config(self, dns_record: DnsRecord):
|
||||
devops = self.devops_repo.get_devops(self.project)
|
||||
devops.specialized_builds[BuildType.K3S].update_runtime_config(dns_record)
|
||||
self.devops_repo.set_devops(self.project, devops)
|
||||
|
||||
def write_provs_config(self):
|
||||
devops = self.devops_repo.get_devops(self.project)
|
||||
k3s = devops.specialized_builds[BuildType.K3S]
|
||||
with open(
|
||||
self.build_path() + "/out_k3sServerConfig.yaml", "w", encoding="utf-8"
|
||||
) as output_file:
|
||||
output_file.write(k3s.provs_config())
|
||||
|
||||
def provs_apply(self, dry_run=False):
|
||||
devops = self.devops_repo.get_devops(self.project)
|
||||
k3s = devops.specialized_builds[BuildType.K3S]
|
||||
self.execution_api.execute_live(k3s.command(devops), dry_run=dry_run)
|
|
@ -1,119 +0,0 @@
|
|||
from string import Template
|
||||
import deprecation
|
||||
from .python_util import execute_live
|
||||
from .devops_build import DevopsBuild
|
||||
|
||||
|
||||
CONFIG_BASE = """
|
||||
fqdn: $fqdn
|
||||
"""
|
||||
CONFIG_IPV4 = """node:
|
||||
ipv4: $ipv4
|
||||
"""
|
||||
CONFIG_IPV6 = """ ipv6: $ipv6
|
||||
"""
|
||||
CONFIG_CERTMANAGER = """certmanager:
|
||||
email: $letsencrypt_email
|
||||
letsencryptEndpoint: $letsencrypt_endpoint
|
||||
"""
|
||||
CONFIG_ECHO = """echo: $echo
|
||||
"""
|
||||
|
||||
|
||||
def add_provs_k3s_mixin_config(config,
|
||||
provision_user='root',
|
||||
echo=None,
|
||||
k3s_config_template=None,
|
||||
letsencrypt_email=None,
|
||||
letsencrypt_endpoint=None,
|
||||
fqdn=None,
|
||||
ipv4=None,
|
||||
ipv6=None,
|
||||
app_filename_to_provision=None):
|
||||
template_text = k3s_config_template
|
||||
if template_text is None:
|
||||
template_text = CONFIG_BASE
|
||||
if letsencrypt_endpoint is not None:
|
||||
template_text += CONFIG_CERTMANAGER
|
||||
if echo is not None:
|
||||
template_text += CONFIG_ECHO
|
||||
if ipv4 is not None:
|
||||
template_text += CONFIG_IPV4
|
||||
if ipv6 is not None:
|
||||
template_text += CONFIG_IPV6
|
||||
|
||||
config.update({'ProvsK3sMixin':
|
||||
{'fqdn': fqdn,
|
||||
'provision_user': provision_user,
|
||||
'ipv4': ipv4,
|
||||
'ipv6': ipv6,
|
||||
'letsencrypt_email': letsencrypt_email,
|
||||
'letsencrypt_endpoint': letsencrypt_endpoint,
|
||||
'echo': echo,
|
||||
'k3s_config_template': template_text,
|
||||
'app_filename_to_provision': app_filename_to_provision}})
|
||||
return config
|
||||
|
||||
|
||||
class ProvsK3sMixin(DevopsBuild):
|
||||
|
||||
def __init__(self, project, config):
|
||||
super().__init__(project, config)
|
||||
provs_k3s_mixin_config = config['ProvsK3sMixin']
|
||||
self.fqdn = provs_k3s_mixin_config['fqdn']
|
||||
self.put('fqdn', self.fqdn)
|
||||
self.provision_user = provs_k3s_mixin_config['provision_user']
|
||||
self.put('provision_user', self.provision_user)
|
||||
self.ipv4 = provs_k3s_mixin_config['ipv4']
|
||||
self.put('ipv4', self.ipv4)
|
||||
self.ipv6 = provs_k3s_mixin_config['ipv6']
|
||||
self.put('ipv6', self.ipv6)
|
||||
self.letsencrypt_email = provs_k3s_mixin_config['letsencrypt_email']
|
||||
self.put('letsencrypt_email', self.letsencrypt_email)
|
||||
self.letsencrypt_endpoint = provs_k3s_mixin_config['letsencrypt_endpoint']
|
||||
self.put('letsencrypt_endpoint', self.letsencrypt_endpoint)
|
||||
self.echo = provs_k3s_mixin_config['echo']
|
||||
self.put('echo', self.echo)
|
||||
self.k3s_config_template_text = provs_k3s_mixin_config['k3s_config_template']
|
||||
self.k3s_config_template = Template(
|
||||
provs_k3s_mixin_config['k3s_config_template'])
|
||||
self.put('k3s_config_template', self.k3s_config_template)
|
||||
self.app_filename_to_provision = provs_k3s_mixin_config['app_filename_to_provision']
|
||||
self.put('app_filename_to_provision', self.app_filename_to_provision)
|
||||
|
||||
def update_runtime_config(self, fqdn, ipv4, ipv6=None):
|
||||
self.fqdn = fqdn
|
||||
self.put('fqdn', fqdn)
|
||||
self.ipv4 = ipv4
|
||||
self.put('ipv4', ipv4)
|
||||
self.ipv6 = ipv6
|
||||
self.put('ipv6', ipv6)
|
||||
template_text = self.k3s_config_template_text
|
||||
if ipv4 is not None:
|
||||
template_text += CONFIG_IPV4
|
||||
if ipv6 is not None:
|
||||
template_text += CONFIG_IPV6
|
||||
self.k3s_config_template_text = template_text
|
||||
self.put('k3s_config_template_text', template_text)
|
||||
template = Template(template_text)
|
||||
self.k3s_config_template = template
|
||||
self.put('k3s_config_template', template)
|
||||
|
||||
def write_provs_config(self):
|
||||
substitutes = self.get_keys(['fqdn', 'ipv4', 'ipv6', 'letsencrypt_email',
|
||||
'letsencrypt_endpoint', 'echo'])
|
||||
with open(self.build_path() + '/out_k3sServerConfig.yaml', "w", encoding="utf-8") as output_file:
|
||||
output_file.write(self.k3s_config_template.substitute(substitutes))
|
||||
|
||||
@deprecation.deprecated(deprecated_in="3.1")
|
||||
def provs_server(self, dry_run=False):
|
||||
self.provs_apply(dry_run)
|
||||
|
||||
def provs_apply(self, dry_run=False):
|
||||
cmd = ['provs-server.jar', 'k3s', self.provision_user + '@' + self.fqdn, '-c',
|
||||
self.build_path() + '/out_k3sServerConfig.yaml',
|
||||
'-a', self.build_path() + '/' + self.app_filename_to_provision]
|
||||
if dry_run:
|
||||
print(" ".join(cmd))
|
||||
else:
|
||||
execute_live(cmd)
|
|
@ -9,7 +9,7 @@ def devops_config(overrides: dict) -> dict:
|
|||
"stage": "test",
|
||||
"project_root_path": "root_path",
|
||||
"build_dir_name": "target",
|
||||
"build_types": ["IMAGE", "C4K"],
|
||||
"build_types": ["IMAGE", "C4K", "K3S"],
|
||||
"mixin_types": ["RELEASE"],
|
||||
"image_dockerhub_user": "dockerhub_user",
|
||||
"image_dockerhub_password": "dockerhub_password",
|
||||
|
@ -19,6 +19,11 @@ def devops_config(overrides: dict) -> dict:
|
|||
"c4k_grafana_cloud_password": "password",
|
||||
"c4k_grafana_cloud_url": "https://prometheus-prod-01-eu-west-0.grafana.net/api/prom/push",
|
||||
"c4k_auth": {},
|
||||
"k3s_provision_user": "k3s_provision_user",
|
||||
"k3s_letsencrypt_email": "k3s_letsencrypt_email",
|
||||
"k3s_letsencrypt_endpoint": "k3s_letsencrypt_endpoint",
|
||||
"k3s_enable_echo": False,
|
||||
"k3s_app_filename_to_provision": "k3s_app.yaml",
|
||||
"release_type": "NONE",
|
||||
"release_main_branch": "main",
|
||||
"release_current_branch": "my_feature",
|
||||
|
|
|
@ -20,7 +20,7 @@ def test_c4k_should_calculate_config():
|
|||
|
||||
sut = build_devops({})
|
||||
c4k = sut.specialized_builds[BuildType.C4K]
|
||||
c4k.update_runtime_config(DnsRecord("fqdn"))
|
||||
c4k.update_runtime_config(DnsRecord("fqdn", ipv6="::1"))
|
||||
assert {
|
||||
"fqdn": "fqdn",
|
||||
"mon-cfg": {
|
||||
|
@ -36,7 +36,7 @@ def test_c4k_should_calculate_config():
|
|||
}
|
||||
)
|
||||
c4k = sut.specialized_builds[BuildType.C4K]
|
||||
c4k.update_runtime_config(DnsRecord("fqdn"))
|
||||
c4k.update_runtime_config(DnsRecord("fqdn", ipv6="::1"))
|
||||
assert {
|
||||
"test": "test",
|
||||
"fqdn": "fqdn",
|
||||
|
|
33
src/test/python/domain/test_provs_k3s.py
Normal file
33
src/test/python/domain/test_provs_k3s.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
import pytest
|
||||
from pathlib import Path
|
||||
from src.main.python.ddadevops.domain import DnsRecord, BuildType, K3s
|
||||
from .helper import build_devops
|
||||
|
||||
|
||||
def test_creation():
|
||||
sut = build_devops({})
|
||||
assert BuildType.K3S in sut.specialized_builds
|
||||
assert sut.specialized_builds[BuildType.K3S]
|
||||
|
||||
|
||||
def test_should_calculate_provs_config():
|
||||
sut = build_devops({}).specialized_builds[BuildType.K3S]
|
||||
sut.update_runtime_config(DnsRecord("example.org", ipv6="::1"))
|
||||
assert "fqdn:" in sut.provs_config()
|
||||
assert not "$" in sut.provs_config()
|
||||
|
||||
|
||||
def test_should_calculate_command():
|
||||
devops = build_devops({})
|
||||
sut = devops.specialized_builds[BuildType.K3S]
|
||||
sut.update_runtime_config(DnsRecord("example.org", ipv6="::1"))
|
||||
assert (
|
||||
"provs-server.jar "
|
||||
+ "k3s "
|
||||
+ "k3s_provision_user@example.org "
|
||||
+ "-c "
|
||||
+ "root_path/target/name/module/out_k3sServerConfig.yaml "
|
||||
+ "-a "
|
||||
+ "root_path/target/name/module/k3s_app.yaml"
|
||||
== sut.command(devops)
|
||||
)
|
Loading…
Reference in a new issue