diff --git a/python/src/mas/cli/aiservice/install/app.py b/python/src/mas/cli/aiservice/install/app.py index 4389da5a50a..41ab26ccc8c 100644 --- a/python/src/mas/cli/aiservice/install/app.py +++ b/python/src/mas/cli/aiservice/install/app.py @@ -124,14 +124,29 @@ def configAibroker(self): self.configOperationMode() + @logMethodCall + def chooseInstallFlavour(self) -> None: + self.printH1("Choose Install Mode") + self.printDescription([ + "There are two flavours of the interactive install to choose from: Simplified and Advanced. The simplified option will present fewer dialogs, but you lose the ability to configure the following aspects of the installation:", + " - Configure certificate issuer", + ]) + self.showAdvancedOptions = self.yesOrNo("Show advanced installation options") + @logMethodCall def interactiveMode(self, simplified: bool, advanced: bool) -> None: # Interactive mode self.interactiveMode = True + if simplified: + self.showAdvancedOptions = False + elif advanced: + self.showAdvancedOptions = True + else: + self.chooseInstallFlavour() + self.storageClassProvider = "custom" self.slsLicenseFileLocal = None - self.showAdvancedOptions = True # Catalog self.configCatalog() @@ -150,7 +165,7 @@ def interactiveMode(self, simplified: bool, advanced: bool) -> None: self.configCertManager() self.configAibroker() if self.devMode: - self.configAppChannel("aibroker") + self.configAppChannel() self.aiServiceSettings() self.aiServiceTenantSettings() @@ -505,6 +520,7 @@ def setupApprovals(self, namespace: str) -> None: logger.debug(f"Approval workflow for {approval['id']} will be enabled during install ({approval['maxRetries']} / {approval['retryDelay']}s / {approval['ignoreFailure']})") self.initializeApprovalConfigMap(namespace, approval['id'], True, approval['maxRetries'], approval['retryDelay'], approval['ignoreFailure']) + @logMethodCall def aiServiceSettings(self) -> None: self.printH1("AI Service Settings") @@ -537,6 +553,18 @@ def aiServiceSettings(self) -> None: self.promptForString("Storage tenants bucket", "aiservice_s3_tenants_bucket") self.promptForString("Storage templates bucket", "aiservice_s3_templates_bucket") + # Configure Certificate Issuer + self.configCertIssuer() + + @logMethodCall + def configCertIssuer(self): + if self.showAdvancedOptions: + self.printH1("Configure Certificate Issuer") + configureCertIssuer = self.yesOrNo('Configure certificate issuer') + if configureCertIssuer: + self.promptForString("Certificate issuer name", "aiservice_certificate_issuer") + + @logMethodCall def aiServiceTenantSettings(self) -> None: self.printH1("AI Service Tenant Settings") self.printDescription([ @@ -829,7 +857,7 @@ def configDRO(self) -> None: self.promptForString("IBM Data Reporter Operator (DRO) Namespace", "dro_namespace", default="redhat-marketplace") @logMethodCall - def configAppChannel(self, appId): + def configAppChannel(self): self.params["aiservice_channel"] = prompt(HTML('Custom channel for AI Service ')) @logMethodCall diff --git a/python/src/mas/cli/aiservice/install/argBuilder.py b/python/src/mas/cli/aiservice/install/argBuilder.py index 92c7e677245..c24b43ec763 100644 --- a/python/src/mas/cli/aiservice/install/argBuilder.py +++ b/python/src/mas/cli/aiservice/install/argBuilder.py @@ -103,6 +103,11 @@ def buildCommand(self) -> str: # AI Service Advanced Settings # ----------------------------------------------------------------------------- + + # Certificate Issuer + if self.getParam('aiservice_certificate_issuer') != "": + command += f" --aiservice-certificate-issuer \"{self.getParam('aiservice_certificate_issuer')}\"{newline}" + if self.getParam('aiservice_s3_accesskey') != "": command += f" --s3-accesskey \"{self.getParam('aiservice_s3_accesskey')}\"{newline}" if self.getParam('aiservice_s3_secretkey') != "": diff --git a/python/src/mas/cli/aiservice/install/argParser.py b/python/src/mas/cli/aiservice/install/argParser.py index e99a07b33a7..883a958be79 100644 --- a/python/src/mas/cli/aiservice/install/argParser.py +++ b/python/src/mas/cli/aiservice/install/argParser.py @@ -401,6 +401,12 @@ def isValidFile(parser, arg) -> str: default="non-production", help="Environment type (default: non-production)" ) +aiServiceArgGroup.add_argument( + "--aiservice-certificate-issuer", + dest="aiservice_certificate_issuer", + required=False, + help="Provide the name of the Issuer to configure AI Service to issue certificates", +) # IBM Db2 Universal Operator diff --git a/python/src/mas/cli/aiservice/install/params.py b/python/src/mas/cli/aiservice/install/params.py index 7b6aa428971..39047dc267d 100644 --- a/python/src/mas/cli/aiservice/install/params.py +++ b/python/src/mas/cli/aiservice/install/params.py @@ -97,4 +97,7 @@ "rsl_token", "rsl_ca_crt", "environment_type", + + # Certificate Issuer + "aiservice_certificate_issuer", ] diff --git a/python/src/mas/cli/aiservice/install/summarizer.py b/python/src/mas/cli/aiservice/install/summarizer.py index b560e3d4892..f09d24be3e8 100644 --- a/python/src/mas/cli/aiservice/install/summarizer.py +++ b/python/src/mas/cli/aiservice/install/summarizer.py @@ -47,6 +47,9 @@ def aiServiceSummary(self) -> None: self.printParamSummary("Instance ID", "aiservice_instance_id") self.printParamSummary("Environment Type", "environment_type") + if "aiservice_certificate_issuer" in self.params: + self.printParamSummary("Certificate Issuer", "aiservice_certificate_issuer") + self.printH2("AI Service Tenant Entitlement") self.printParamSummary("Entitlement Type", "tenant_entitlement_type") self.printParamSummary("Start Date", "tenant_entitlement_start_date") diff --git a/python/src/mas/cli/install/app.py b/python/src/mas/cli/install/app.py index 856e003a8ef..306af5024ff 100644 --- a/python/src/mas/cli/install/app.py +++ b/python/src/mas/cli/install/app.py @@ -1026,6 +1026,17 @@ def aiServiceSettings(self) -> None: self.promptForString("Storage tenants bucket", "aiservice_s3_tenants_bucket") self.promptForString("Storage templates bucket", "aiservice_s3_templates_bucket") + # Configure Certificate Issuer + self.configAIServiceCertIssuer() + + @logMethodCall + def configAIServiceCertIssuer(self): + if self.showAdvancedOptions: + self.printH1("Configure Certificate Issuer") + configureCertIssuer = self.yesOrNo('Configure certificate issuer') + if configureCertIssuer: + self.promptForString("Certificate issuer name", "aiservice_certificate_issuer") + @logMethodCall def aiServiceTenantSettings(self) -> None: if self.installAIService: diff --git a/python/src/mas/cli/install/argBuilder.py b/python/src/mas/cli/install/argBuilder.py index ecc367916e1..71ddb0002c8 100644 --- a/python/src/mas/cli/install/argBuilder.py +++ b/python/src/mas/cli/install/argBuilder.py @@ -312,6 +312,11 @@ def buildCommand(self) -> str: command += f" --aiservice-instance-id \"{self.getParam('aiservice_instance_id')}\"{newline}" if self.getParam('aiservice_channel') != "": command += f" --aiservice-channel \"{self.getParam('aiservice_channel')}\"{newline}" + + # Certificate Issuer for AI Service + if self.getParam('aiservice_certificate_issuer') != "": + command += f" --aiservice-certificate-issuer \"{self.getParam('aiservice_certificate_issuer')}\"{newline}" + if self.getParam('aiservice_s3_accesskey') != "" and self.getParam('minio_root_user') == "": command += f" --s3-accesskey \"{self.getParam('aiservice_s3_accesskey')}\"{newline}" if self.getParam('aiservice_s3_secretkey') != "" and self.getParam('minio_root_user') == "": diff --git a/python/src/mas/cli/install/argParser.py b/python/src/mas/cli/install/argParser.py index 6cf8d0aa104..48990e1c932 100644 --- a/python/src/mas/cli/install/argParser.py +++ b/python/src/mas/cli/install/argParser.py @@ -767,11 +767,11 @@ def isValidFile(parser: argparse.ArgumentParser, arg: str) -> str: # S3 Storage # ----------------------------------------------------------------------------- -s3ArgGroup = installArgParser.add_argument_group( +aiServiceS3ArgGroup = installArgParser.add_argument_group( "S3 Storage", "Configure S3-compatible object storage for AI Service including Minio installation or external S3 connection details (host, port, SSL, credentials, bucket, and region)." ) -s3ArgGroup.add_argument( +aiServiceS3ArgGroup.add_argument( "--install-minio", dest="install_minio_aiservice", required=False, @@ -782,13 +782,13 @@ def isValidFile(parser: argparse.ArgumentParser, arg: str) -> str: # S3 - Minio # ----------------------------------------------------------------------------- -s3ArgGroup.add_argument( +aiServiceS3ArgGroup.add_argument( "--minio-root-user", dest="minio_root_user", required=False, help="Root user for minio" ) -s3ArgGroup.add_argument( +aiServiceS3ArgGroup.add_argument( "--minio-root-password", dest="minio_root_password", required=False, @@ -797,43 +797,43 @@ def isValidFile(parser: argparse.ArgumentParser, arg: str) -> str: # S3 - External Connection # ----------------------------------------------------------------------------- -s3ArgGroup.add_argument( +aiServiceS3ArgGroup.add_argument( "--s3-host", dest="aiservice_s3_host", required=False, help="Hostname or IP address of the S3 storage service" ) -s3ArgGroup.add_argument( +aiServiceS3ArgGroup.add_argument( "--s3-port", dest="aiservice_s3_port", required=False, help="Port number for the S3 storage service" ) -s3ArgGroup.add_argument( +aiServiceS3ArgGroup.add_argument( "--s3-ssl", dest="aiservice_s3_ssl", required=False, help="Enable or disable SSL for S3 connection (true/false)" ) -s3ArgGroup.add_argument( +aiServiceS3ArgGroup.add_argument( "--s3-accesskey", dest="aiservice_s3_accesskey", required=False, help="Access key for authenticating with the S3 storage service" ) -s3ArgGroup.add_argument( +aiServiceS3ArgGroup.add_argument( "--s3-secretkey", dest="aiservice_s3_secretkey", required=False, help="Secret key for authenticating with the S3 storage service" ) -s3ArgGroup.add_argument( +aiServiceS3ArgGroup.add_argument( "--s3-region", dest="aiservice_s3_region", required=False, help="Region for the S3 storage service" ) -s3ArgGroup.add_argument( +aiServiceS3ArgGroup.add_argument( "--s3-bucket-prefix", dest="aiservice_s3_bucket_prefix", required=False, @@ -842,14 +842,14 @@ def isValidFile(parser: argparse.ArgumentParser, arg: str) -> str: # S3 - Bucket Naming # ----------------------------------------------------------------------------- -s3ArgGroup.add_argument( +aiServiceS3ArgGroup.add_argument( "--s3-tenants-bucket", dest="aiservice_s3_tenants_bucket", required=False, default="km-tenants", help="Name of the S3 bucket for tenants storage" ) -s3ArgGroup.add_argument( +aiServiceS3ArgGroup.add_argument( "--s3-templates-bucket", dest="aiservice_s3_templates_bucket", required=False, @@ -859,125 +859,132 @@ def isValidFile(parser: argparse.ArgumentParser, arg: str) -> str: # Watsonx # ----------------------------------------------------------------------------- -watsonxArgGroup = installArgParser.add_argument_group( +aiServiceWatsonxArgGroup = installArgParser.add_argument_group( "Watsonx", "Configure IBM Watsonx integration for AI Service including API key, instance ID, project ID, and service URL." ) -watsonxArgGroup.add_argument( +aiServiceWatsonxArgGroup.add_argument( "--watsonxai-apikey", dest="aiservice_watsonxai_apikey", required=False, help="API key for WatsonX" ) -watsonxArgGroup.add_argument( +aiServiceWatsonxArgGroup.add_argument( "--watsonxai-url", dest="aiservice_watsonxai_url", required=False, help="URL endpoint for WatsonX" ) -watsonxArgGroup.add_argument( +aiServiceWatsonxArgGroup.add_argument( "--watsonxai-project-id", dest="aiservice_watsonxai_project_id", required=False, help="Project ID for WatsonX" ) -watsonxArgGroup.add_argument( +aiServiceWatsonxArgGroup.add_argument( "--watsonx-action", dest="aiservice_watsonx_action", required=False, help="Action to perform with WatsonX (install/remove)" ) -watsonxArgGroup.add_argument( +aiServiceWatsonxArgGroup.add_argument( "--watsonxai-ca-crt", dest="aiservice_watsonxai_ca_crt", required=False, help="CA certificate for WatsonX AI (PEM format, optional, only if using self-signed certs)" ) -watsonxArgGroup.add_argument( +aiServiceWatsonxArgGroup.add_argument( "--watsonxai-deployment-id", dest="aiservice_watsonxai_deployment_id", required=False, help="WatsonX deployment ID" ) -watsonxArgGroup.add_argument( +aiServiceWatsonxArgGroup.add_argument( "--watsonxai-space-id", dest="aiservice_watsonxai_space_id", required=False, help="WatsonX space ID" ) -watsonxArgGroup.add_argument( +aiServiceWatsonxArgGroup.add_argument( "--watsonxai-instance-id", dest="aiservice_watsonxai_instance_id", required=False, help="WatsonX instance ID" ) -watsonxArgGroup.add_argument( +aiServiceWatsonxArgGroup.add_argument( "--watsonxai-username", dest="aiservice_watsonxai_username", required=False, help="WatsonX username" ) -watsonxArgGroup.add_argument( +aiServiceWatsonxArgGroup.add_argument( "--watsonxai-version", dest="aiservice_watsonxai_version", required=False, help="WatsonX version" ) -watsonxArgGroup.add_argument( +aiServiceWatsonxArgGroup.add_argument( "--watsonxai-onprem", dest="aiservice_watsonxai_on_prem", required=False, help="WatsonX deployed on prem" ) -# AI Service +# AI Service Tenant # ----------------------------------------------------------------------------- -aiServiceArgGroup = installArgParser.add_argument_group("Maximo AI Service") +aiServiceTenantArgGroup = installArgParser.add_argument_group("Maximo AI Service Tenant") -aiServiceArgGroup.add_argument( +aiServiceTenantArgGroup.add_argument( "--tenant-entitlement-type", dest="tenant_entitlement_type", required=False, default="standard", help="Entitlement type for AI Service tenant" ) -aiServiceArgGroup.add_argument( +aiServiceTenantArgGroup.add_argument( "--tenant-entitlement-start-date", dest="tenant_entitlement_start_date", required=False, help="Start date for AI Service tenant" ) -aiServiceArgGroup.add_argument( +aiServiceTenantArgGroup.add_argument( "--tenant-entitlement-end-date", dest="tenant_entitlement_end_date", required=False, help="End date for AI Service tenant" ) -aiServiceArgGroup.add_argument( +aiServiceTenantArgGroup.add_argument( "--rsl-url", dest="rsl_url", required=False, help="rsl url" ) -aiServiceArgGroup.add_argument( +aiServiceTenantArgGroup.add_argument( "--rsl-org-id", dest="rsl_org_id", required=False, help="org id for rsl" ) -aiServiceArgGroup.add_argument( +aiServiceTenantArgGroup.add_argument( "--rsl-token", dest="rsl_token", required=False, help="token for rsl" ) -aiServiceArgGroup.add_argument( +aiServiceTenantArgGroup.add_argument( "--rsl-ca-crt", dest="rsl_ca_crt", required=False, help="CA certificate for RSL API (PEM format, optional, only if using self-signed certs)" ) + +# AI Service Configuration +# ----------------------------------------------------------------------------- +aiServiceArgGroup = installArgParser.add_argument_group( + "Maximo AI Service", + "Maximo AI Service configuration such as certificate Issuer, environment type" +) aiServiceArgGroup.add_argument( "--environment-type", dest="environment_type", @@ -985,6 +992,12 @@ def isValidFile(parser: argparse.ArgumentParser, arg: str) -> str: default="non-production", help="Environment type (default: non-production)" ) +aiServiceArgGroup.add_argument( + "--aiservice-certificate-issuer", + dest="aiservice_certificate_issuer", + required=False, + help="Provide the name of the Issuer to configure AI Service to issue certificates", +) # IBM Cloud Pak for Data # ----------------------------------------------------------------------------- diff --git a/python/src/mas/cli/install/params.py b/python/src/mas/cli/install/params.py index 2e34c5720f1..bf6b89aefc9 100644 --- a/python/src/mas/cli/install/params.py +++ b/python/src/mas/cli/install/params.py @@ -204,5 +204,8 @@ "rsl_org_id", "rsl_token", "rsl_ca_crt", - "environment_type" + "environment_type", + + # Certificate Issuer + "aiservice_certificate_issuer" ] diff --git a/python/src/mas/cli/install/summarizer.py b/python/src/mas/cli/install/summarizer.py index a881f6e9d51..ee295044c9f 100644 --- a/python/src/mas/cli/install/summarizer.py +++ b/python/src/mas/cli/install/summarizer.py @@ -238,6 +238,9 @@ def aiServiceSummary(self) -> None: self.printParamSummary("Instance ID", "aiservice_instance_id") self.printParamSummary("Environment Type", "environment_type") + if "aiservice_certificate_issuer" in self.params: + self.printParamSummary("Certificate Issuer", "aiservice_certificate_issuer") + self.printH2("AI Service Tenant Entitlement") self.printParamSummary("Entitlement Type", "tenant_entitlement_type") self.printParamSummary("Start Date", "tenant_entitlement_start_date") diff --git a/python/test/aiservice/install/test_app.py b/python/test/aiservice/install/test_app.py index 71e2d61dcf6..cd0c3748ebe 100644 --- a/python/test/aiservice/install/test_app.py +++ b/python/test/aiservice/install/test_app.py @@ -109,7 +109,7 @@ def test_install_noninteractive(tmpdir): '--skip-pre-check']) -def test_install_interactive(tmpdir): +def test_install_interactive_advanced(tmpdir): tmpdir.join('authorized_entitlement.lic').write('testLicense') tmpdir.join('mongodb-system.yaml').write('#') tmpdir.join('cert.crt').write('#') @@ -161,6 +161,132 @@ def set_mixin_prompt_input(**kwargs): message = str(kwargs['message']) if re.match('.*Proceed with this cluster?.*', message): return 'y' + if re.match('.*Show advanced installation options?.*', message): + return 'y' + if re.match('.*Do you accept the license terms?.*', message): + return 'y' + if re.match('.*ReadWriteOnce (RWO) storage class.*', message): + return 'nfs-client' + if re.match('.*ReadWriteMany (RWX) storage class.*', message): + return 'nfs-client' + if re.match('.*SLS Mode.*', message): + return '1' + if re.match('.*License file.*', message): + return f'{tmpdir}/authorized_entitlement.lic' + if re.match('.*Instance ID.*', message): + return 'apmdevops' + if re.match('.*Operational Mode.*', message): + return '1' + if re.match('.*Install Minio.*', message): + return 'y' + if re.match('.*minio root username.*', message): + return 'username' + if re.match('.*minio root password.*', message): + return 'password' + if re.match('.*Configure certificate issuer?.*', message): + return 'y' + if re.match('.*Certificate issuer name.*', message): + return 'cert-issuer' + if re.match('.*RSL url.*', message): + return 'https://rls.maximo.test.ibm.com' + if re.match('.*ORG Id of RSL.*', message): + return 'rslOrgId' + if re.match('.*Token for RSL.*', message): + return 'rslToken' + if re.match('.*Watsonxai machine learning url.*', message): + return 'watsonxUrl' + if re.match('.*Does the RSL API use a self-signed certificate.*', message): + return 'n' + if re.match('.*Does the Watsonxai AI use a self-signed certificate.*', message): + return 'n' + if re.match('.*Create MongoDb cluster.*', message): + return 'n' + if re.match('.*Select Local configuration directory.*', message): + return str(tmpdir) + if re.match('.*MongoDb Username.*', message): + return 'mongodbUser' + if re.match('.*MongoDb Password.*', message): + return 'mongodbPassword' + if re.match('.*Path to certificate file.*', message): + return f'{tmpdir}/cert.crt' + if re.match(".*System mongodb configuration file 'mongodb-system.yaml' already exists", message): + return 'n' + if re.match(".*Proceed with these settings.*", message): + return 'y' + if re.match(".*Wait for PVCs to bind.*", message): + return 'n' + mixins_prompt.side_effect = set_mixin_prompt_input + + def set_app_prompt_input(**kwargs): + message = str(kwargs['message']) + if re.match('.*ReadWriteOnce (RWO) storage class.*', message): + return 'nfs-client' + if re.match('.*ReadWriteMany (RWX) storage class.*', message): + return 'nfs-client' + app_prompt.side_effect = set_app_prompt_input + + storage_class = MagicMock() + get_storage_classes.return_value = [storage_class] + storage_class.metadata = MagicMock() + storage_class.metadata.name = 'nfs-client' + app = AiServiceInstallApp() + app.install(argv=[]) + + +def test_install_interactive_simplified(tmpdir): + tmpdir.join('authorized_entitlement.lic').write('testLicense') + tmpdir.join('mongodb-system.yaml').write('#') + tmpdir.join('cert.crt').write('#') + with mock.patch('mas.cli.cli.config'): + dynamic_client = MagicMock(DynamicClient) + resources = MagicMock() + dynamic_client.resources = resources + routes_api = MagicMock() + catalog_api = MagicMock() + crd_api = MagicMock() + namespace_api = MagicMock() + cluster_role_binding_api = MagicMock() + pvc_api = MagicMock() + secret_api = MagicMock() + storage_class_api = MagicMock() + license_api = MagicMock() + resource_apis = {'CatalogSource': catalog_api, 'Route': routes_api, 'CustomResourceDefinition': crd_api, 'Namespace': namespace_api, + 'ClusterRoleBinding': cluster_role_binding_api, 'PersistentVolumeClaim': pvc_api, 'Secret': secret_api, + 'StorageClass': storage_class_api, 'LicenseService': license_api} + resources.get.side_effect = lambda **kwargs: resource_apis.get(kwargs['kind'], None) + route = MagicMock() + route.spec = MagicMock() + route.spec.host = 'maximo.ibm.com' + route.spec.displayName = supportedCatalogs['amd64'][1] + routes_api.get.return_value = route + catalog_api.get.side_effect = NotFoundError(ApiException(status='404')) + with ( + mock.patch('mas.cli.cli.DynamicClient') as dynamic_client_class, + mock.patch('mas.cli.cli.getNodes') as get_nodes, + mock.patch('mas.cli.cli.isAirgapInstall') as is_airgap_install, + mock.patch('mas.cli.aiservice.install.app.getCurrentCatalog') as get_current_catalog, + mock.patch('mas.cli.aiservice.install.app.installOpenShiftPipelines'), + mock.patch('mas.cli.aiservice.install.app.updateTektonDefinitions'), + mock.patch('mas.cli.aiservice.install.app.prepareAiServicePipelinesNamespace'), + mock.patch('mas.cli.aiservice.install.app.launchInstallPipeline') as launch_ai_service_install_pipeline, + mock.patch('mas.cli.cli.isSNO') as is_sno, + mock.patch('mas.cli.displayMixins.prompt') as mixins_prompt, + mock.patch('mas.cli.aiservice.install.app.prompt') as app_prompt, + mock.patch('mas.cli.aiservice.install.app.getStorageClasses') as get_storage_classes + ): + dynamic_client_class.return_value = dynamic_client + get_nodes.return_value = [{'status': {'nodeInfo': {'architecture': 'amd64'}}}] + is_airgap_install.return_value = False + get_current_catalog.return_value = {'catalogId': supportedCatalogs['amd64'][1]} + launch_ai_service_install_pipeline.return_value = 'https://pipeline.test.maximo.ibm.com' + is_sno.return_value = False + + def set_mixin_prompt_input(**kwargs): + message = str(kwargs['message']) + if re.match('.*Proceed with this cluster?.*', message): + return 'y' + if re.match('.*Show advanced installation options?.*', message): + return 'n' if re.match('.*Do you accept the license terms?.*', message): return 'y' if re.match('.*ReadWriteOnce (RWO) storage class.*', message): @@ -171,10 +297,16 @@ def set_mixin_prompt_input(**kwargs): return '1' if re.match('.*License file.*', message): return f'{tmpdir}/authorized_entitlement.lic' + if re.match('.*Instance ID.*', message): + return 'apmdevops' if re.match('.*Operational Mode.*', message): return '1' if re.match('.*Install Minio.*', message): return 'y' + if re.match('.*minio root username.*', message): + return 'username' + if re.match('.*minio root password.*', message): + return 'password' if re.match('.*RSL url.*', message): return 'https://rls.maximo.test.ibm.com' if re.match('.*ORG Id of RSL.*', message): diff --git a/tekton/src/params/install-aiservice.yml.j2 b/tekton/src/params/install-aiservice.yml.j2 index 54815d4810b..9e57c1f76de 100644 --- a/tekton/src/params/install-aiservice.yml.j2 +++ b/tekton/src/params/install-aiservice.yml.j2 @@ -155,3 +155,9 @@ description: token for RSL default: "" +# MAS Application Configuration - IBM Maximo AI Service - Certificate Issuer +# ----------------------------------------------------------------------------- +- name: aiservice_certificate_issuer + type: string + description: Name of the Issuer to configure AI Service to issue certificates + default: "" diff --git a/tekton/src/pipelines/taskdefs/aiservice/aiservice.yml.j2 b/tekton/src/pipelines/taskdefs/aiservice/aiservice.yml.j2 index 7a9b88f710a..f9c3f9ddab0 100644 --- a/tekton/src/pipelines/taskdefs/aiservice/aiservice.yml.j2 +++ b/tekton/src/pipelines/taskdefs/aiservice/aiservice.yml.j2 @@ -87,6 +87,9 @@ - name: environment_type value: $(params.environment_type) + - name: aiservice_certificate_issuer + value: $(params.aiservice_certificate_issuer) + taskRef: name: mas-devops-aiservice kind: Task diff --git a/tekton/src/tasks/aiservice/aiservice.yml.j2 b/tekton/src/tasks/aiservice/aiservice.yml.j2 index 0732ebf4989..62dc2977e23 100644 --- a/tekton/src/tasks/aiservice/aiservice.yml.j2 +++ b/tekton/src/tasks/aiservice/aiservice.yml.j2 @@ -152,6 +152,10 @@ spec: - name: rsl_token type: string + # Certificate Issuer + - name: aiservice_certificate_issuer + type: string + stepTemplate: env: {{ lookup('template', task_src_dir ~ '/common/cli-env.yml.j2') | indent(6) }} @@ -249,6 +253,10 @@ spec: - name: RSL_TOKEN value: $(params.rsl_token) + # Certificate Issuer + - name: AISERVICE_CERTIFICATE_ISSUER + value: $(params.aiservice_certificate_issuer) + steps: - name: aiservice command: