blob: bb68d4959ca06b5391047da235b993f86aa37c1f [file] [log] [blame]
Mohammed Naser5c804a22022-09-29 21:27:21 -04001import os
2
3import tomli
4from schematics import types
Mohammed Naserad5e2652022-11-25 18:31:36 +00005from schematics.exceptions import ValidationError
Mohammed Naser5c804a22022-09-29 21:27:21 -04006
Mohammed Naser71ebfe82022-12-28 05:28:16 +00007from atmosphere import utils
Mohammed Naser5c804a22022-09-29 21:27:21 -04008from atmosphere.models import base
9
10CONFIG_FILE = os.environ.get("ATMOSPHERE_CONFIG", "/etc/atmosphere/config.toml")
11
12
13class AcmeIssuerSolverConfig(base.Model):
Mohammed Naser57b53392022-09-30 19:39:07 +000014 type = types.StringType(
15 choices=("http", "rfc2136", "route53"), default="http", required=True
16 )
Mohammed Naser5c804a22022-09-29 21:27:21 -040017
18 @classmethod
19 def _claim_polymorphic(cls, data):
20 return data.get("type", cls.type.default) == cls.TYPE
21
22
23class HttpAcmeIssuerSolverConfig(AcmeIssuerSolverConfig):
24 TYPE = "http"
25
26
Mohammed Naser57b53392022-09-30 19:39:07 +000027class Rfc2136AcmeIssuerSolverConfig(AcmeIssuerSolverConfig):
28 TYPE = "rfc2136"
29
30 nameserver = types.StringType(required=True)
31 tsig_algorithm = types.StringType(required=True)
32 tsig_key_name = types.StringType(required=True)
33 tsig_secret = types.StringType(required=True)
34
35
Mohammed Naser5c804a22022-09-29 21:27:21 -040036class Route53AcmeIssuerSolverConfig(AcmeIssuerSolverConfig):
37 TYPE = "route53"
38
Mohammed Naser57b53392022-09-30 19:39:07 +000039 region = types.StringType(default="global", required=True)
40 hosted_zone_id = types.StringType(required=True)
Mohammed Naser5c804a22022-09-29 21:27:21 -040041 access_key_id = types.StringType(required=True)
42 secret_access_key = types.StringType(required=True)
Mohammed Naser5c804a22022-09-29 21:27:21 -040043
44
45class Issuer(base.Model):
46 type = types.StringType(
Mohammed Naser57b53392022-09-30 19:39:07 +000047 choices=("acme", "ca", "self-signed"), default="acme", required=True
Mohammed Naser5c804a22022-09-29 21:27:21 -040048 )
49
50 @classmethod
51 def _claim_polymorphic(cls, data):
52 return data.get("type", cls.type.default) == cls.TYPE
53
54
55class AcmeIssuerConfig(Issuer):
56 TYPE = "acme"
57
58 email = types.StringType(required=True)
59 server = types.URLType(default="https://acme-v02.api.letsencrypt.org/directory")
60 solver = types.PolyModelType(
Mohammed Naser57b53392022-09-30 19:39:07 +000061 [
62 HttpAcmeIssuerSolverConfig,
63 Rfc2136AcmeIssuerSolverConfig,
64 Route53AcmeIssuerSolverConfig,
65 ],
66 default=HttpAcmeIssuerSolverConfig(),
67 required=True,
Mohammed Naser5c804a22022-09-29 21:27:21 -040068 )
69
70
Mohammed Naser57b53392022-09-30 19:39:07 +000071class CaIssuerConfig(Issuer):
72 TYPE = "ca"
73
74 certificate = types.StringType(required=True)
75 private_key = types.StringType(required=True)
76
77
Mohammed Naser5c804a22022-09-29 21:27:21 -040078class SelfSignedIssuerConfig(Issuer):
79 TYPE = "self-signed"
80
81
Mohammed Nasere04907d2022-10-05 21:39:31 +000082class ChartConfig(base.Model):
83 enabled = types.BooleanType(default=True, required=True)
84 overrides = types.DictType(types.BaseType(), default={})
85
86
Mohammed Naser7d3c7972022-11-07 10:54:56 -050087class KubePrometheusStackChartConfig(ChartConfig):
88 namespace = types.StringType(default="monitoring", required=True)
89
90
Mohammed Naser5c804a22022-09-29 21:27:21 -040091class MemcachedImagesConfig(base.Model):
Mohammed Naser71ebfe82022-12-28 05:28:16 +000092 memcached = types.StringType(
93 default=utils.get_image_ref_using_legacy_image_repository("memcached").string()
94 )
95 exporter = types.StringType(
96 default=utils.get_image_ref_using_legacy_image_repository(
97 "prometheus_memcached_exporter"
98 ).string()
99 )
Mohammed Naser5c804a22022-09-29 21:27:21 -0400100
101
Mohammed Nasere04907d2022-10-05 21:39:31 +0000102class MemcachedChartConfig(ChartConfig):
Mohammed Naser661b0b02022-10-07 20:54:59 +0000103 namespace = types.StringType(default="openstack", required=True)
Mohammed Naser5c804a22022-09-29 21:27:21 -0400104 secret_key = types.StringType(required=True)
105 images = types.ModelType(MemcachedImagesConfig, default=MemcachedImagesConfig())
Mohammed Nasere04907d2022-10-05 21:39:31 +0000106
107
Mohammed Nasera7853cb2022-10-07 20:47:57 +0000108class IngressNginxChartConfig(ChartConfig):
Mohammed Naser31e528b2022-10-07 20:57:35 +0000109 namespace = types.StringType(default="openstack", required=True)
Mohammed Naser5c804a22022-09-29 21:27:21 -0400110
111
Mohammed Naserad5e2652022-11-25 18:31:36 +0000112class OpsGenieConfig(base.Model):
113 enabled = types.BooleanType(default=False, required=True)
114 api_key = types.StringType()
115 heartbeat = types.StringType()
116
117 def validate_api_key(self, data, value):
118 if data["enabled"] and not value:
119 raise ValidationError(types.BaseType.MESSAGES["required"])
120 return value
121
122 def validate_heartbeat(self, data, value):
123 if data["enabled"] and not value:
124 raise ValidationError(types.BaseType.MESSAGES["required"])
125 return value
126
127
Mohammed Naser5c804a22022-09-29 21:27:21 -0400128class Config(base.Model):
Mohammed Naser71ebfe82022-12-28 05:28:16 +0000129 image_repository = types.StringType()
Mohammed Naser7d3c7972022-11-07 10:54:56 -0500130 kube_prometheus_stack = types.ModelType(
131 KubePrometheusStackChartConfig, default=KubePrometheusStackChartConfig()
132 )
Mohammed Nasera7853cb2022-10-07 20:47:57 +0000133 ingress_nginx = types.ModelType(
134 IngressNginxChartConfig, default=IngressNginxChartConfig()
135 )
Mohammed Naser62256dc2022-09-29 22:31:50 -0400136 memcached = types.ModelType(
Mohammed Nasere04907d2022-10-05 21:39:31 +0000137 MemcachedChartConfig, default=MemcachedChartConfig(), required=True
Mohammed Naser62256dc2022-09-29 22:31:50 -0400138 )
Mohammed Naser57b53392022-09-30 19:39:07 +0000139 issuer = types.PolyModelType(
140 [AcmeIssuerConfig, CaIssuerConfig, SelfSignedIssuerConfig],
141 default=AcmeIssuerConfig(),
142 required=True,
Mohammed Naser5c804a22022-09-29 21:27:21 -0400143 )
Mohammed Naserad5e2652022-11-25 18:31:36 +0000144 opsgenie = types.ModelType(OpsGenieConfig, default=OpsGenieConfig())
Mohammed Naser5c804a22022-09-29 21:27:21 -0400145
146 @classmethod
Mohammed Naser57b53392022-09-30 19:39:07 +0000147 def from_toml(cls, data, validate=True):
148 c = cls(data, validate=validate)
149 if validate:
150 c.validate()
151 return c
152
153 @classmethod
154 def from_file(cls, path=CONFIG_FILE):
Mohammed Naser5c804a22022-09-29 21:27:21 -0400155 with open(path, "rb") as fd:
156 data = tomli.load(fd)
Mohammed Naser57b53392022-09-30 19:39:07 +0000157 return cls.from_toml(data)
158
159 @classmethod
160 def from_string(cls, data: str, validate=True):
161 data = tomli.loads(data)
162 return cls.from_toml(data, validate)