diff --git a/python/src/mas/cli/install/app.py b/python/src/mas/cli/install/app.py index e1719d245f..2f8e4eb691 100644 --- a/python/src/mas/cli/install/app.py +++ b/python/src/mas/cli/install/app.py @@ -37,6 +37,7 @@ from .catalogs import supportedCatalogs from mas.cli.validators import ( + ClusterIssuerValidator, InstanceIDFormatValidator, WorkspaceIDFormatValidator, WorkspaceNameFormatValidator, @@ -51,7 +52,8 @@ createNamespace, getStorageClasses, getClusterVersion, - isClusterVersionInRange + isClusterVersionInRange, + getClusterIssuers ) from mas.devops.mas import ( getCurrentCatalog, @@ -562,7 +564,6 @@ def configDNSAndCerts(self): "Unless you see an error during the ocp-verify stage indicating that the secret can not be determined you do not need to set this and can leave the response empty" ]) self.promptForString("Cluster ingress certificate secret name", "ocp_ingress_tls_secret_name", default="") - self.printH1("Configure Domain & Certificate Management") configureDomainAndCertMgmt = self.yesOrNo('Configure domain & certificate management') if configureDomainAndCertMgmt: @@ -602,13 +603,34 @@ def configDNSAndCerts(self): # Use MAS default self-signed cluster issuer with the default domain self.setParam("dns_provider", "") self.setParam("mas_domain", "") - self.setParam("mas_cluster_issuer", "") self.manualCerts = self.yesOrNo("Configure manual certificates") self.setParam("mas_manual_cert_mgmt", self.manualCerts) if self.getParam("mas_manual_cert_mgmt"): self.manualCertsDir = self.promptForDir("Enter the path containing the manual certificates", mustExist=True) else: self.manualCertsDir = None + else: + # Configuring domain + if self.yesOrNo('Configure custom domain'): + self.promptForString("MAS top-level domain", "mas_domain") + else: + self.setParam("mas_domain", "") + + # Configuring DNS + if self.yesOrNo("Do you want MAS to set up its own (self-signed) cluster issuer?"): + self.setParam("mas_cluster_issuer", "") + else: + self.printDescription([ + "Select the ClusterIssuer to use from the list below:", + ]) + clusterIssuers = getClusterIssuers(self.dynamicClient) + if clusterIssuers is not None and len(clusterIssuers) > 0: + for clusterIssuer in clusterIssuers: + print_formatted_text(HTML(f" - {clusterIssuer.metadata.name}")) + self.params['mas_cluster_issuer'] = prompt(HTML('MAS Cluster Issuer '), validator=ClusterIssuerValidator(), validate_while_typing=False) + else: + print_formatted_text(HTML("No ClusterIssuers found on this cluster. MAS will use self-signed certificates.")) + self.setParam("mas_cluster_issuer", "") @logMethodCall def configDNSAndCertsCloudflare(self): diff --git a/python/src/mas/cli/validators.py b/python/src/mas/cli/validators.py index 446349b63b..202dc432b8 100644 --- a/python/src/mas/cli/validators.py +++ b/python/src/mas/cli/validators.py @@ -19,7 +19,7 @@ from prompt_toolkit.validation import Validator, ValidationError -from mas.devops.ocp import getStorageClass +from mas.devops.ocp import getStorageClass, getClusterIssuer from mas.devops.mas import verifyMasInstance from mas.devops.aiservice import verifyAiServiceInstance, verifyAiServiceTenantInstance @@ -238,3 +238,18 @@ def validate(self, document): if not match(r"^.{1,4}$", bucketPrefix): raise ValidationError(message='Bucket prefix does not meet the requirement', cursor_position=len(bucketPrefix)) + + +class ClusterIssuerValidator(Validator): + def validate(self, document): + """ + Validate that a ClusterIssuer exists on the target cluster + """ + name = document.text + + dynClient = dynamic.DynamicClient( + api_client.ApiClient(configuration=config.load_kube_config()) + ) + + if getClusterIssuer(dynClient, name) is None: + raise ValidationError(message='Specified cluster issuer is not available on this cluster', cursor_position=len(name))