diff --git a/.gitignore b/.gitignore index 06f8a6aff98..76b9d9124e3 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,4 @@ python/README.rst /.venv /site report/ +/python/.venv diff --git a/.secrets.baseline b/.secrets.baseline index 9d395f08b6f..360b8603c74 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "^.secrets.baseline$", "lines": null }, - "generated_at": "2025-10-24T12:47:22Z", + "generated_at": "2025-10-24T15:33:48Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -502,7 +502,7 @@ "hashed_secret": "2582aea6f911bd00fc04cb25e0ec16d5ead62068", "is_secret": false, "is_verified": false, - "line_number": 336, + "line_number": 342, "type": "Secret Keyword", "verified_result": null } diff --git a/docs/commands/provision-fyre.md b/docs/commands/provision-fyre.md index 556ccdb1921..8e7df1211dd 100644 --- a/docs/commands/provision-fyre.md +++ b/docs/commands/provision-fyre.md @@ -24,7 +24,7 @@ Usage - `--fyre-cluster-size FYRE_CLUSTER_SIZE` When Fyre Quick Burn, defines the size category ("medium" or "large") ### Storage Provisioner Configuration -- `--no-storage` Disable setup of the nfs-client storage class +- `--storage` Configure the storage provider (nfs, odf, or longhorn) - `--nfs-image-registry-size FYRE_NFS_IMAGE_REGISTRY_SIZE` Defines the image registry storage size when configured to use NFS (default 100gb). The size allocated cannot be superior of storage available in the Fyre Infrastructure node. ### Other Commands diff --git a/image/cli/mascli/functions/provision_fyre b/image/cli/mascli/functions/provision_fyre index 1e48aa83651..cfdb75fb032 100644 --- a/image/cli/mascli/functions/provision_fyre +++ b/image/cli/mascli/functions/provision_fyre @@ -37,8 +37,8 @@ Worker Node Configuration (Optional, only takes effect when quota-type is set to --worker-additional-disks ${COLOR_YELLOW}FYRE_WORKER_ADDITIONAL_DISKS${TEXT_RESET} Comma-seperated list of sizes for additional disks to attach (e.g. "200,200" to attach two 400gb additional disks) Storage Provisioner Configuration: + --storage ${COLOR_YELLOW}OCP_STORAGE_PROVIDER${TEXT_RESET} Choose optional storage provider (nfs, odf, or longhorn) --nfs-image-registry-size ${COLOR_YELLOW}FYRE_NFS_IMAGE_REGISTRY_SIZE${TEXT_RESET} Defines the image registry storage size when configured to use NFS (default 100gb). The size allocated cannot be superior of storage available in the Fyre Infrastructure node. - --no-storage Disable setup of the nfs-client storage class Other Commands: --no-confirm Provision the cluster without prompting for confirmation @@ -53,9 +53,6 @@ function provision_fyre_noninteractive() { if [[ -z "$CLUSTER_PLATFORM" ]]; then CLUSTER_PLATFORM=x fi - if [[ -z "$FYRE_NFS_SETUP" ]]; then - FYRE_NFS_SETUP=true - fi while [[ $# -gt 0 ]] do @@ -123,8 +120,8 @@ function provision_fyre_noninteractive() { ;; # Storage Configuration - --no-storage) - FYRE_NFS_SETUP=false + --storage) + OCP_STORAGE_PROVIDER=$1 && shift ;; --nfs-image-registry-size) IMAGE_REGISTRY_STORAGE_SIZE=$1 && shift @@ -275,13 +272,23 @@ function provision_fyre_interactive() { fi fi - prompt_for_confirm_default_yes "Enable NFS storage class (nfs-client) in the cluster?" CONFIGURE_NFS - if [[ "$CONFIGURE_NFS" == "false" ]]; then - export FYRE_NFS_SETUP=false - else - prompt_for_input "Image Registry PVC Size" FYRE_IMAGE_REGISTRY_SIZE "100Gi" + echo + echo "Storage Provider:" + echo " 1. None" + echo " 2. Longhorn" + echo " 3. NFS" + echo " 4. ODF" + prompt_for_input "Select the storage provider to setup" OCP_STORAGE_PROVIDER_SELECTION "1" + + if [[ "$OCP_STORAGE_PROVIDER_SELECTION" == "1" ]]; then + OCP_STORAGE_PROVIDER="" + elif [[ "$OCP_STORAGE_PROVIDER_SELECTION" == "2" ]]; then + OCP_STORAGE_PROVIDER="longhorn" + elif [[ "$OCP_STORAGE_PROVIDER_SELECTION" == "3" ]]; then + OCP_STORAGE_PROVIDER="nfs" + elif [[ "$OCP_STORAGE_PROVIDER_SELECTION" == "4" ]]; then + OCP_STORAGE_PROVIDER="odf" fi - } function provision_fyre() { @@ -324,8 +331,7 @@ function provision_fyre() { export FYRE_CLUSTER_SIZE - export FYRE_NFS_SETUP - export FYRE_IMAGE_REGISTRY_SIZE + export OCP_STORAGE_PROVIDER echo reset_colors @@ -362,10 +368,7 @@ function provision_fyre() { reset_colors echo "${TEXT_DIM}" echo_h2 "Storage" " " - echo_reset_dim "Enable NFS Storage Class .. ${COLOR_MAGENTA}${FYRE_NFS_SETUP}" - if [[ "${FYRE_NFS_SETUP}" == "true" ]]; then - echo_reset_dim "Image Registry Size ....... ${COLOR_MAGENTA}${FYRE_NFS_IMAGE_REGISTRY_SIZE:-Default}" - fi + echo_reset_dim "Storage Provider ............ ${COLOR_MAGENTA}${OCP_STORAGE_PROVIDER}" echo reset_colors diff --git a/python/README.md b/python/README.md index e0b968c2753..09129f4f3af 100644 --- a/python/README.md +++ b/python/README.md @@ -21,7 +21,8 @@ dynClient = dynamic.DynamicClient( ) # Install OpenShift Pipelines Operator -installOpenShiftPipelines(dynamicClient) +success = installOpenShiftPipelines(dynamicClient) +assert success is True # Create the pipelines namespace and install the MAS tekton definitions createNamespace(dynamicClient, pipelinesNamespace) diff --git a/python/src/mas/cli/aiservice/install/app.py b/python/src/mas/cli/aiservice/install/app.py index 3b10acc7c60..02c47cc751a 100644 --- a/python/src/mas/cli/aiservice/install/app.py +++ b/python/src/mas/cli/aiservice/install/app.py @@ -454,8 +454,11 @@ def install(self, argv): wait = False with Halo(text='Validating OpenShift Pipelines installation', spinner=self.spinner) as h: - installOpenShiftPipelines(self.dynamicClient) - h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator is installed and ready to use") + if installOpenShiftPipelines(self.dynamicClient): + h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator is installed and ready to use") + else: + h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator installation failed") + self.fatalError("Installation failed") with Halo(text=f'Preparing namespace ({pipelinesNamespace})', spinner=self.spinner) as h: createNamespace(self.dynamicClient, pipelinesNamespace) diff --git a/python/src/mas/cli/aiservice/upgrade/app.py b/python/src/mas/cli/aiservice/upgrade/app.py index 7aa9989151d..cbc0ab4beb3 100644 --- a/python/src/mas/cli/aiservice/upgrade/app.py +++ b/python/src/mas/cli/aiservice/upgrade/app.py @@ -115,8 +115,11 @@ def upgrade(self, argv): pipelinesNamespace = f"aiservice-{aiserviceInstanceId}-pipelines" with Halo(text='Validating OpenShift Pipelines installation', spinner=self.spinner) as h: - installOpenShiftPipelines(self.dynamicClient) - h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator is installed and ready to use") + if installOpenShiftPipelines(self.dynamicClient): + h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator is installed and ready to use") + else: + h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator installation failed") + self.fatalError("Installation failed") with Halo(text=f'Preparing namespace ({pipelinesNamespace})', spinner=self.spinner) as h: createNamespace(self.dynamicClient, pipelinesNamespace) diff --git a/python/src/mas/cli/cli.py b/python/src/mas/cli/cli.py index 17922ba8ac5..7105f984ea0 100644 --- a/python/src/mas/cli/cli.py +++ b/python/src/mas/cli/cli.py @@ -9,6 +9,7 @@ # ***************************************************************************** import logging +import logging.handlers import urllib3 from argparse import RawTextHelpFormatter diff --git a/python/src/mas/cli/install/app.py b/python/src/mas/cli/install/app.py index d8ca8b8d0b0..f67408d156d 100644 --- a/python/src/mas/cli/install/app.py +++ b/python/src/mas/cli/install/app.py @@ -1263,8 +1263,11 @@ def install(self, argv): pipelinesNamespace = f"mas-{self.getParam('mas_instance_id')}-pipelines" with Halo(text='Validating OpenShift Pipelines installation', spinner=self.spinner) as h: - installOpenShiftPipelines(self.dynamicClient) - h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator is installed and ready to use") + if installOpenShiftPipelines(self.dynamicClient): + h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator is installed and ready to use") + else: + h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator installation failed") + self.fatalError("Installation failed") with Halo(text=f'Preparing namespace ({pipelinesNamespace})', spinner=self.spinner) as h: createNamespace(self.dynamicClient, pipelinesNamespace) diff --git a/python/src/mas/cli/install/settings/db2Settings.py b/python/src/mas/cli/install/settings/db2Settings.py index 482cc41d4df..ddca20638c6 100644 --- a/python/src/mas/cli/install/settings/db2Settings.py +++ b/python/src/mas/cli/install/settings/db2Settings.py @@ -220,8 +220,8 @@ def setDB2DefaultSettings(self) -> None: self.params["db2_cpu_requests"] = "300m" else: - self.setParam("db2_meta_storage_size", "20Gi") - self.setParam("db2_backup_storage_size", "100Gi") - self.setParam("db2_logs_storage_size", "100Gi") - self.setParam("db2_temp_storage_size", "100Gi") - self.setParam("db2_data_storage_size", "100Gi") + self.setParam("db2_meta_storage_size", "10Gi") + self.setParam("db2_backup_storage_size", "50Gi") + self.setParam("db2_logs_storage_size", "10Gi") + self.setParam("db2_temp_storage_size", "10Gi") + self.setParam("db2_data_storage_size", "50Gi") diff --git a/python/src/mas/cli/uninstall/app.py b/python/src/mas/cli/uninstall/app.py index 67386f18c62..5531d36ac07 100644 --- a/python/src/mas/cli/uninstall/app.py +++ b/python/src/mas/cli/uninstall/app.py @@ -164,8 +164,11 @@ def uninstall(self, argv): pipelinesNamespace = f"mas-{instanceId}-pipelines" with Halo(text='Validating OpenShift Pipelines installation', spinner=self.spinner) as h: - installOpenShiftPipelines(self.dynamicClient) - h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator is installed and ready to use") + if installOpenShiftPipelines(self.dynamicClient): + h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator is installed and ready to use") + else: + h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator installation failed") + self.fatalError("Installation failed") with Halo(text=f'Preparing namespace ({pipelinesNamespace})', spinner=self.spinner) as h: createNamespace(self.dynamicClient, pipelinesNamespace) diff --git a/python/src/mas/cli/update/app.py b/python/src/mas/cli/update/app.py index c582287684c..4aa68f5e532 100644 --- a/python/src/mas/cli/update/app.py +++ b/python/src/mas/cli/update/app.py @@ -196,8 +196,11 @@ def update(self, argv): pipelinesNamespace = "mas-pipelines" with Halo(text='Validating OpenShift Pipelines installation', spinner=self.spinner) as h: - installOpenShiftPipelines(self.dynamicClient) - h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator is installed and ready to use") + if installOpenShiftPipelines(self.dynamicClient): + h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator is installed and ready to use") + else: + h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator installation failed") + self.fatalError("Installation failed") with Halo(text=f'Preparing namespace ({pipelinesNamespace})', spinner=self.spinner) as h: createNamespace(self.dynamicClient, pipelinesNamespace) diff --git a/python/src/mas/cli/upgrade/app.py b/python/src/mas/cli/upgrade/app.py index 60fe1f1125b..dd459bb477f 100644 --- a/python/src/mas/cli/upgrade/app.py +++ b/python/src/mas/cli/upgrade/app.py @@ -154,8 +154,12 @@ def upgrade(self, argv): pipelinesNamespace = f"mas-{instanceId}-pipelines" with Halo(text='Validating OpenShift Pipelines installation', spinner=self.spinner) as h: - installOpenShiftPipelines(self.dynamicClient) - h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator is installed and ready to use") + successfullyInstalledPipelines = installOpenShiftPipelines(self.dynamicClient) + if successfullyInstalledPipelines: + h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator is installed and ready to use") + else: + h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator installation failed") + self.fatalError("Installation failed") with Halo(text=f'Preparing namespace ({pipelinesNamespace})', spinner=self.spinner) as h: createNamespace(self.dynamicClient, pipelinesNamespace) diff --git a/python/test/aiservice/install/test_app.py b/python/test/aiservice/install/test_app.py index c8b4cbf5c92..04b68e75df6 100644 --- a/python/test/aiservice/install/test_app.py +++ b/python/test/aiservice/install/test_app.py @@ -45,60 +45,63 @@ def test_install_noninteractive(tmpdir): 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: + 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.launchAiServiceInstallPipeline') as launch_ai_service_install_pipeline + ): dynamic_client_class.return_value = dynamic_client - with mock.patch('mas.cli.cli.getNodes') as get_nodes: - get_nodes.return_value = [{'status': {'nodeInfo': {'architecture': 'amd64'}}}] - with mock.patch('mas.cli.cli.isAirgapInstall') as is_airgap_install: - is_airgap_install.return_value = False - with mock.patch('mas.cli.aiservice.install.app.getCurrentCatalog') as get_current_catalog: - get_current_catalog.return_value = {'catalogId': supportedCatalogs['amd64'][1]} - with mock.patch('mas.cli.aiservice.install.app.updateTektonDefinitions'): - with mock.patch('mas.cli.aiservice.install.app.launchAiServiceInstallPipeline') as launch_ai_service_install_pipeline: - launch_ai_service_install_pipeline.return_value = 'https://pipeline.test.maximo.ibm.com' - with mock.patch('mas.cli.cli.isSNO') as is_sno: - is_sno.return_value = False - app = AiServiceInstallApp() - app.install(['--mas-catalog-version', 'v9-250828-amd64', - '--ibm-entitlement-key', 'testEntitlementKey', - '--aiservice-instance-id', 'testInstanceId', - '--storage-class-rwo', 'nfs-client', - '--storage-class-rwx', 'nfs-client', - '--storage-pipeline', 'nfs-client', - '--storage-accessmode', 'ReadWriteMany', - '--license-file', f'{tmpdir}/authorized_entitlement.lic', - '--uds-email', 'maximo@ibm.com', - '--uds-firstname', 'Test', - '--uds-lastname', 'Test', - '--dro-namespace', 'redhat-marketplace', - '--mongodb-namespace', 'mongoce', - '--aiservice-channel', '9.1.x', - '--s3-accesskey', 'test', - '--s3-secretkey', 'test', - '--s3-host', 'minio-service.minio.svc.cluster.local', - '--s3-port', '9000', - '--s3-ssl', 'false', - '--s3-region', 'none', - '--s3-bucket-prefix', 'aiservice', - '--s3-tenants-bucket', 'km-tenants', - '--s3-templates-bucket', 'km-templates', - '--watsonxai-apikey', 'test', - '--watsonxai-url', 'https://us-south.ml.cloud.ibm.com', - '--watsonxai-project-id', 'test', - '--watsonxai-ca-crt', 'testWxCaCrt', - '--watsonxai-deployment-id', 'testDeploymentId', - '--watsonxai-space-id', 'testSpaceId', - '--minio-root-user', 'test', - '--minio-root-password', 'test', - '--tenant-entitlement-type', 'standard', - '--tenant-entitlement-start-date', '2025-08-28', - '--tenant-entitlement-end-date', '2026-08-28', - '--rsl-url', 'https:/test.rsl.maximo.ibm.com/api/v3/vector/query', - '--rsl-org-id', 'testOrgId', - '--rsl-token', 'testRslToken', - '--rsl-ca-crt', 'testRslCaCert', - '--accept-license', '--no-confirm', - '--skip-pre-check']) + 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' + with mock.patch('mas.cli.cli.isSNO') as is_sno: + is_sno.return_value = False + app = AiServiceInstallApp() + app.install(['--mas-catalog-version', 'v9-250828-amd64', + '--ibm-entitlement-key', 'testEntitlementKey', + '--aiservice-instance-id', 'testInstanceId', + '--storage-class-rwo', 'nfs-client', + '--storage-class-rwx', 'nfs-client', + '--storage-pipeline', 'nfs-client', + '--storage-accessmode', 'ReadWriteMany', + '--license-file', f'{tmpdir}/authorized_entitlement.lic', + '--uds-email', 'maximo@ibm.com', + '--uds-firstname', 'Test', + '--uds-lastname', 'Test', + '--dro-namespace', 'redhat-marketplace', + '--mongodb-namespace', 'mongoce', + '--aiservice-channel', '9.1.x', + '--s3-accesskey', 'test', + '--s3-secretkey', 'test', + '--s3-host', 'minio-service.minio.svc.cluster.local', + '--s3-port', '9000', + '--s3-ssl', 'false', + '--s3-region', 'none', + '--s3-bucket-prefix', 'aiservice', + '--s3-tenants-bucket', 'km-tenants', + '--s3-templates-bucket', 'km-templates', + '--watsonxai-apikey', 'test', + '--watsonxai-url', 'https://us-south.ml.cloud.ibm.com', + '--watsonxai-project-id', 'test', + '--watsonxai-ca-crt', 'testWxCaCrt', + '--watsonxai-deployment-id', 'testDeploymentId', + '--watsonxai-space-id', 'testSpaceId', + '--minio-root-user', 'test', + '--minio-root-password', 'test', + '--tenant-entitlement-type', 'standard', + '--tenant-entitlement-start-date', '2025-08-28', + '--tenant-entitlement-end-date', '2026-08-28', + '--rsl-url', 'https:/test.rsl.maximo.ibm.com/api/v3/vector/query', + '--rsl-org-id', 'testOrgId', + '--rsl-token', 'testRslToken', + '--rsl-ca-crt', 'testRslCaCert', + '--accept-license', '--no-confirm', + '--skip-pre-check']) def test_install_interactive(tmpdir): @@ -128,77 +131,83 @@ def test_install_interactive(tmpdir): 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: + 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.launchAiServiceInstallPipeline') 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 - with mock.patch('mas.cli.cli.getNodes') as get_nodes: - get_nodes.return_value = [{'status': {'nodeInfo': {'architecture': 'amd64'}}}] - with mock.patch('mas.cli.cli.isAirgapInstall') as is_airgap_install: - is_airgap_install.return_value = False - with mock.patch('mas.cli.aiservice.install.app.getCurrentCatalog') as get_current_catalog: - get_current_catalog.return_value = {'catalogId': supportedCatalogs['amd64'][1]} - with mock.patch('mas.cli.aiservice.install.app.updateTektonDefinitions'): - with mock.patch('mas.cli.aiservice.install.app.launchAiServiceInstallPipeline') as launch_ai_service_install_pipeline: - launch_ai_service_install_pipeline.return_value = 'https://pipeline.test.maximo.ibm.com' - with mock.patch('mas.cli.cli.isSNO') as is_sno: - is_sno.return_value = False - with mock.patch('mas.cli.displayMixins.prompt') as mixins_prompt: - def set_mixin_prompt_input(**kwargs): - message = str(kwargs['message']) - if re.match('.*Proceed with this cluster?.*', 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('.*Operational Mode.*', message): - return '1' - if re.match('.*Install Minio.*', message): - return 'y' - 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('.*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 - with mock.patch('mas.cli.aiservice.install.app.prompt') as app_prompt: - 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 - with mock.patch('mas.cli.aiservice.install.app.getStorageClasses') as get_storage_classes: - 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=[]) + 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('.*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('.*Operational Mode.*', message): + return '1' + if re.match('.*Install Minio.*', message): + return 'y' + 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('.*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=[])