-
- # SSL Certificate path
- self.ssl_folder = "/certs"
- self.ssl_crt_name = "ssl_certificate.crt"
- self.ssl_key_name = "ssl_certificate.key"
-
- def _apply_spec(self):
- # Only apply the spec if this unit is a leader.
- unit = self.model.unit
- if not unit.is_leader():
- unit.status = ActiveStatus("ready")
- return
- if not self.state.nbi_host or not self.state.nbi_port:
- unit.status = WaitingStatus("Waiting for NBI")
- return
- unit.status = MaintenanceStatus("Applying new pod spec")
-
- new_spec = self.make_pod_spec()
- if new_spec == self.state.spec:
- unit.status = ActiveStatus("ready")
- return
- self.framework.model.pod.set_spec(new_spec)
- self.state.spec = new_spec
- unit.status = ActiveStatus("ready")
-
- def make_pod_spec(self):
- config = self.framework.model.config
-
- config_spec = {
- "http_port": config["port"],
- "https_port": config["https_port"],
- "server_name": config["server_name"],
- "client_max_body_size": config["client_max_body_size"],
- "nbi_host": self.state.nbi_host or config["nbi_host"],
- "nbi_port": self.state.nbi_port or config["nbi_port"],
- "ssl_crt": "",
- "ssl_crt_key": "",
- }
-
- ssl_certificate = None
- ssl_certificate_key = None
- ssl_enabled = False
-
- if "ssl_certificate" in config and "ssl_certificate_key" in config:
- # Get bytes of cert and key
- cert_b = base64.b64decode(config["ssl_certificate"])
- key_b = base64.b64decode(config["ssl_certificate_key"])
- # Decode key and cert
- ssl_certificate = cert_b.decode("utf-8")
- ssl_certificate_key = key_b.decode("utf-8")
- # Get paths
- cert_path = "{}/{}".format(self.ssl_folder, self.ssl_crt_name)
- key_path = "{}/{}".format(self.ssl_folder, self.ssl_key_name)
-
- config_spec["port"] = "{} ssl".format(config["https_port"])
- config_spec["ssl_crt"] = "ssl_certificate {};".format(cert_path)
- config_spec["ssl_crt_key"] = "ssl_certificate_key {};".format(key_path)
- ssl_enabled = True
- else:
- config_spec["ssl_crt"] = ""
- config_spec["ssl_crt_key"] = ""
-
- files = [
- {
- "name": "configuration",
- "mountPath": "/etc/nginx/sites-available/",
- "files": {
- Path(filename)
- .name: Template(Path(filename).read_text())
- .substitute(config_spec)
- for filename in glob("files/*")
- },
+ return files_builder.build()
+
+ def build_pod_spec(self, image_info):
+ # Validate config
+ config = ConfigModel(**dict(self.config))
+ # Check relations
+ self._check_missing_dependencies(config)
+ # Create Builder for the PodSpec
+ pod_spec_builder = PodSpecV3Builder()
+ # Build Container
+ container_builder = ContainerV3Builder(self.app.name, image_info)
+ container_builder.add_port(name=self.app.name, port=config.port)
+ container = container_builder.build()
+ container_builder.add_tcpsocket_readiness_probe(
+ config.port,
+ initial_delay_seconds=45,
+ timeout_seconds=5,
+ )
+ container_builder.add_tcpsocket_liveness_probe(
+ config.port,
+ initial_delay_seconds=45,
+ timeout_seconds=15,
+ )
+ container_builder.add_volume_config(
+ "configuration",
+ "/etc/nginx/sites-available/",
+ self._build_files(config),
+ )
+ # Add container to pod spec
+ pod_spec_builder.add_container(container)
+ # Add ingress resources to pod spec if site url exists
+ if config.site_url:
+ parsed = urlparse(config.site_url)
+ annotations = {
+ "nginx.ingress.kubernetes.io/proxy-body-size": "{}".format(
+ str(config.max_file_size) + "m"
+ if config.max_file_size > 0
+ else config.max_file_size
+ ),