mas-cli 20.2.1__tar.gz → 21.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. {mas_cli-20.2.1/src/mas_cli.egg-info → mas_cli-21.1.0}/PKG-INFO +1 -1
  2. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/__init__.py +1 -1
  3. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/aiservice/install/app.py +138 -14
  4. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/aiservice/install/argBuilder.py +8 -0
  5. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/aiservice/install/argParser.py +39 -2
  6. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/aiservice/install/params.py +5 -0
  7. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/aiservice/install/summarizer.py +7 -1
  8. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/aiservice/upgrade/argParser.py +12 -0
  9. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/cli.py +1 -1
  10. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/gencfg.py +46 -0
  11. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/install/app.py +312 -26
  12. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/install/argBuilder.py +14 -0
  13. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/install/argParser.py +43 -0
  14. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/install/params.py +3 -0
  15. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/install/settings/__init__.py +2 -1
  16. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/install/settings/additionalConfigs.py +34 -0
  17. mas_cli-21.1.0/src/mas/cli/install/settings/aiSettings.py +178 -0
  18. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/install/settings/db2Settings.py +14 -0
  19. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/install/settings/kafkaSettings.py +40 -3
  20. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/install/summarizer.py +11 -1
  21. mas_cli-21.1.0/src/mas/cli/pre_install/app.py +197 -0
  22. mas_cli-21.1.0/src/mas/cli/pre_install/argParser.py +80 -0
  23. mas_cli-21.1.0/src/mas/cli/setup_rbac/__init__.py +9 -0
  24. mas_cli-21.1.0/src/mas/cli/templates/aicfg.yml.j2 +38 -0
  25. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/ibm-mas-tekton.yaml +868 -225
  26. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/update/app.py +180 -29
  27. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/update/argParser.py +14 -0
  28. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/upgrade/app.py +70 -3
  29. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas-cli +5 -0
  30. {mas_cli-20.2.1 → mas_cli-21.1.0/src/mas_cli.egg-info}/PKG-INFO +1 -1
  31. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas_cli.egg-info/SOURCES.txt +5 -0
  32. {mas_cli-20.2.1 → mas_cli-21.1.0}/MANIFEST.in +0 -0
  33. {mas_cli-20.2.1 → mas_cli-21.1.0}/README.md +0 -0
  34. {mas_cli-20.2.1 → mas_cli-21.1.0}/pyproject.toml +0 -0
  35. {mas_cli-20.2.1 → mas_cli-21.1.0}/setup.cfg +0 -0
  36. {mas_cli-20.2.1 → mas_cli-21.1.0}/setup.py +0 -0
  37. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/aiservice/install/__init__.py +0 -0
  38. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/aiservice/upgrade/__init__.py +0 -0
  39. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/aiservice/upgrade/app.py +0 -0
  40. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/backup/__init__.py +0 -0
  41. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/backup/app.py +0 -0
  42. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/backup/argParser.py +0 -0
  43. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/displayMixins.py +0 -0
  44. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/install/__init__.py +0 -0
  45. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/install/catalogs.py +0 -0
  46. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/install/settings/manageSettings.py +0 -0
  47. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/install/settings/mongodbSettings.py +0 -0
  48. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/mirror/__init__.py +0 -0
  49. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/mirror/app.py +0 -0
  50. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/mirror/argParser.py +0 -0
  51. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/mirror/config.py +0 -0
  52. {mas_cli-20.2.1/src/mas/cli/setup_rbac → mas_cli-21.1.0/src/mas/cli/pre_install}/__init__.py +0 -0
  53. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/restore/__init__.py +0 -0
  54. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/restore/app.py +0 -0
  55. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/restore/argParser.py +0 -0
  56. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/setup_rbac/app.py +0 -0
  57. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/setup_rbac/argParser.py +0 -0
  58. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/facilities-configs.yml.j2 +0 -0
  59. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/jdbccfg.yml.j2 +0 -0
  60. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-data-dictionary-assetdatadictionary.yml +0 -0
  61. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-bascfg.yml +0 -0
  62. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-coreidp.yml +0 -0
  63. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-actions.yml +0 -0
  64. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-auth.yml +0 -0
  65. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-datapower.yml +0 -0
  66. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-devops.yml +0 -0
  67. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-dm.yml +0 -0
  68. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-dsc.yml +0 -0
  69. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-edgeconfig.yml +0 -0
  70. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-fpl.yml +0 -0
  71. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-guardian.yml +0 -0
  72. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-iot.yml +0 -0
  73. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-mbgx.yml +0 -0
  74. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-mfgx.yml +0 -0
  75. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-monitor.yml +0 -0
  76. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-orgmgmt.yml +0 -0
  77. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-provision.yml +0 -0
  78. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-registry.yml +0 -0
  79. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-state.yml +0 -0
  80. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-webui.yml +0 -0
  81. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-healthextaccelerator.yml +0 -0
  82. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-healthextworkspace.yml +0 -0
  83. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-imagestitching.yml +0 -0
  84. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-manageaccelerators.yml +0 -0
  85. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-manageapp.yml +0 -0
  86. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-manageworkspace.yml +0 -0
  87. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-slackproxy.yml +0 -0
  88. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-pushnotificationcfg.yml +0 -0
  89. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-scimcfg.yml +0 -0
  90. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-slscfg.yml +0 -0
  91. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-smtpcfg.yml +0 -0
  92. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-suite.yml +0 -0
  93. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-visualinspection.yml +0 -0
  94. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-sls-licenseservice.yml +0 -0
  95. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-data-dictionary-assetdatadictionary.yml +0 -0
  96. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-bascfg.yml +0 -0
  97. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-coreidp.yml +0 -0
  98. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-actions.yml +0 -0
  99. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-auth.yml +0 -0
  100. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-datapower.yml +0 -0
  101. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-devops.yml +0 -0
  102. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-dm.yml +0 -0
  103. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-dsc.yml +0 -0
  104. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-edgeconfig.yml +0 -0
  105. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-fpl.yml +0 -0
  106. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-guardian.yml +0 -0
  107. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-iot.yml +0 -0
  108. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-mbgx.yml +0 -0
  109. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-mfgx.yml +0 -0
  110. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-monitor.yml +0 -0
  111. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-orgmgmt.yml +0 -0
  112. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-provision.yml +0 -0
  113. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-registry.yml +0 -0
  114. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-state.yml +0 -0
  115. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-webui.yml +0 -0
  116. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-healthextaccelerator.yml +0 -0
  117. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-healthextworkspace.yml +0 -0
  118. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-imagestitching.yml +0 -0
  119. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-manageaccelerators.yml +0 -0
  120. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-manageapp.yml +0 -0
  121. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-manageworkspace.yml +0 -0
  122. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-slackproxy.yml +0 -0
  123. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-pushnotificationcfg.yml +0 -0
  124. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-scimcfg.yml +0 -0
  125. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-slscfg.yml +0 -0
  126. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-smtpcfg.yml +0 -0
  127. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-suite.yml +0 -0
  128. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-visualinspection.yml +0 -0
  129. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-sls-licenseservice.yml +0 -0
  130. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/templates/suite_mongocfg.yml.j2 +0 -0
  131. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/uninstall/__init__.py +0 -0
  132. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/uninstall/app.py +0 -0
  133. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/uninstall/argParser.py +0 -0
  134. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/update/__init__.py +0 -0
  135. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/upgrade/__init__.py +0 -0
  136. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/upgrade/argParser.py +0 -0
  137. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/upgrade/settings/__init__.py +0 -0
  138. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas/cli/validators.py +0 -0
  139. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas_cli.egg-info/dependency_links.txt +0 -0
  140. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas_cli.egg-info/requires.txt +0 -0
  141. {mas_cli-20.2.1 → mas_cli-21.1.0}/src/mas_cli.egg-info/top_level.txt +0 -0
  142. {mas_cli-20.2.1 → mas_cli-21.1.0}/test/test_baseapp.py +0 -0
  143. {mas_cli-20.2.1 → mas_cli-21.1.0}/test/test_help.py +0 -0
  144. {mas_cli-20.2.1 → mas_cli-21.1.0}/test/test_slack_params.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mas-cli
3
- Version: 20.2.1
3
+ Version: 21.1.0
4
4
  Summary: Python Admin CLI for Maximo Application Suite
5
5
  Home-page: https://github.com/ibm-mas/cli
6
6
  Author: David Parker
@@ -10,4 +10,4 @@
10
10
 
11
11
  from .cli import BaseApp # noqa: F401
12
12
 
13
- __version__ = "20.2.1" # Python module compatible semver
13
+ __version__ = "21.1.0" # Python module compatible semver
@@ -37,9 +37,7 @@ from ...install.catalogs import supportedCatalogs
37
37
  # AI Service utilizes two distinct databases: DB2 is employed by the AiBroker component.
38
38
  # By default, AiService will deploy DB2 within the same namespace as MAS (db2u), but it will be configured as a separate DB2 instance.
39
39
 
40
- from ...install.settings.mongodbSettings import MongoDbSettingsMixin
41
- from ...install.settings.db2Settings import Db2SettingsMixin
42
- from ...install.settings.additionalConfigs import AdditionalConfigsMixin
40
+ from ...install.settings import InstallSettingsMixin
43
41
 
44
42
  from mas.cli.validators import (
45
43
  InstanceIDFormatValidator,
@@ -57,11 +55,12 @@ from mas.devops.data import getCatalog, NoSuchCatalogError
57
55
  from mas.devops.tekton import (
58
56
  installOpenShiftPipelines,
59
57
  updateTektonDefinitions,
60
- prepareAiServicePipelinesNamespace,
61
58
  prepareInstallSecrets,
62
59
  testCLI,
63
60
  launchInstallPipeline
64
61
  )
62
+ from mas.devops.pre_install import applyPreInstallMASRBAC, permissionCheckForRBAC
63
+ from mas.devops.utils import isVersionEqualOrAfter
65
64
 
66
65
  logger = logging.getLogger(__name__)
67
66
 
@@ -75,7 +74,73 @@ def logMethodCall(func):
75
74
  return wrapper
76
75
 
77
76
 
78
- class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceInstallSummarizerMixin, MongoDbSettingsMixin, Db2SettingsMixin, AdditionalConfigsMixin, ConfigGeneratorMixin):
77
+ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceInstallSummarizerMixin, InstallSettingsMixin, ConfigGeneratorMixin):
78
+
79
+ def evaluatePreInstallRBACAccess(self) -> None:
80
+ self.applyPreInstallMASRBAC = False
81
+
82
+ if not isVersionEqualOrAfter('9.2.0', self.getParam("aiservice_channel")):
83
+ return
84
+
85
+ if self.getParam("skip_preinstall_rbac") == "true":
86
+ return
87
+
88
+ permissionResults = permissionCheckForRBAC(self.dynamicClient)
89
+ hasPreInstallRBACAccess = all(result["allowed"] for result in permissionResults)
90
+
91
+ if hasPreInstallRBACAccess:
92
+ self.applyPreInstallMASRBAC = True
93
+ return
94
+
95
+ if self.isInteractiveMode:
96
+ self.printDescription([
97
+ "",
98
+ f"You selected the '{self.getParam('permission_mode')}' permission mode.",
99
+ "The pre-install RBAC required for this permission mode has not been applied by your current cluster login.",
100
+ "This step must be completed by an OpenShift cluster administrator before AI Service installation can continue.",
101
+ "Ask your OpenShift administrator to run 'mas pre-install' for this AI Service instance.",
102
+ "If that has already been done, you can continue the installation without applying it again."
103
+ ])
104
+
105
+ if not self.yesOrNo("Has your OpenShift administrator already run 'mas pre-install' for this AI Service installation"):
106
+ self.fatalError("Installation aborted. Ask your OpenShift administrator to run 'mas pre-install' for this AI Service installation and then run 'mas aiservice-install' again with --skip-preinstall-rbac.")
107
+ else:
108
+ self.fatalError(
109
+ "\n".join([
110
+ f"You selected the '{self.getParam('permission_mode')}' permission mode.",
111
+ "The pre-install RBAC required for this permission mode has not been applied by your current cluster login.",
112
+ "This step must be completed by an OpenShift cluster administrator before AI Service installation can continue.",
113
+ "Ask your OpenShift administrator to run 'mas pre-install' for this installation and then rerun 'mas aiservice-install' with --skip-preinstall-rbac."
114
+ ])
115
+ )
116
+
117
+ def configPermissionMode(self) -> None:
118
+ if self.showAdvancedOptions:
119
+ self.printH1("Configure Permission Mode")
120
+ self.printDescription([
121
+ "Choose how AI Service should be installed with respect to permissions:",
122
+ "",
123
+ " 1. <b>cluster</b> - Install with ClusterRoles (default)",
124
+ " - AI Service has cluster-level access to manage its resources across the cluster",
125
+ " - CLI pre-installs ClusterRoles to grant delegated admin permissions to AI Service service accounts",
126
+ "",
127
+ " 2. <b>namespaced</b> - Install with namespace-scoped Roles only",
128
+ " - No ClusterRoles are installed in this mode",
129
+ " - CLI pre-installs namespace-scoped Roles in prepared namespaces to grant delegated admin permissions",
130
+ " - AI Service can manage resources only in namespaces prepared by the OpenShift admin",
131
+ "",
132
+ " 3. <b>minimal</b> - Install with essential namespace-scoped Roles only",
133
+ " - No ClusterRoles are installed in this mode",
134
+ " - Only essential permissions required for AI Service are applied",
135
+ " - AI Service can manage only the resources covered by these essential permissions"
136
+ ])
137
+
138
+ permissionModeInt = self.promptForInt("Permission Mode", default=1, min=1, max=3)
139
+ permissionModeMap = {1: "cluster", 2: "namespaced", 3: "minimal"}
140
+ self.setParam("permission_mode", permissionModeMap[permissionModeInt])
141
+ elif self.getParam("permission_mode") == "":
142
+ self.setParam("permission_mode", "cluster")
143
+
79
144
  @logMethodCall
80
145
  def processCatalogChoice(self) -> list:
81
146
  self.catalogDigest = self.chosenCatalog["catalog_digest"]
@@ -131,6 +196,7 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
131
196
  "There are two flavours of the interactive install to choose from: <u>Simplified</u> and <u>Advanced</u>. The simplified option will present fewer dialogs, but you lose the ability to configure the following aspects of the installation:",
132
197
  " - Configure certificate issuer",
133
198
  " - Enable IPv6 SingleStack networking for services",
199
+ " - Customize Scheduling configuration for AI workloads(Training pipeline & Inference services) for AI Service tenant"
134
200
  ])
135
201
  self.showAdvancedOptions = self.yesOrNo("Show advanced installation options")
136
202
 
@@ -148,6 +214,7 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
148
214
 
149
215
  self.storageClassProvider = "custom"
150
216
  self.slsLicenseFileLocal = None
217
+ self.db2LicenseFileLocal = None
151
218
 
152
219
  # Catalog
153
220
  self.configCatalog()
@@ -176,6 +243,14 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
176
243
  self.configMongoDb()
177
244
  self.setDB2DefaultChannel()
178
245
  self.setDB2DefaultSettings()
246
+ self.printDescription([
247
+ "Db2 Universal Operator for v12 onwards requires to add a License activation key",
248
+ "If you don't have a license press enter to continue."
249
+ ])
250
+ self.db2LicenseFileLocal = self.promptForFile("Db2 License file", envVar="DB2_LICENSE_FILE", default="", mustExist=False)
251
+ # Permission mode prompt (especially in dev mode)
252
+ if isVersionEqualOrAfter('9.2.0', self.getParam("aiservice_channel")):
253
+ self.configPermissionMode()
179
254
 
180
255
  @logMethodCall
181
256
  def nonInteractiveMode(self) -> None:
@@ -188,6 +263,9 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
188
263
 
189
264
  self.storageClassProvider = "custom"
190
265
  self.slsLicenseFileLocal = None
266
+ self.db2LicenseFileLocal = None
267
+
268
+ self.aiserviceTenantSchedulingConfigFileLocal = None
191
269
 
192
270
  self.approvals = {
193
271
  "approval_aiservice": {"id": "aiservice"},
@@ -250,6 +328,11 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
250
328
  if len(value) == 0 or len(value) > 4:
251
329
  self.fatalError(f"Unsupported value for --s3-bucket-prefix(Must be 1-4 characters long): {value}")
252
330
 
331
+ elif key == "tenant_scheduling_config_file":
332
+ # No need to perform validation if file exist here, as it has been already validated by argParser type check.
333
+ if value is not None and value != "":
334
+ self.aiserviceTenantSchedulingConfigFileLocal = value
335
+
253
336
  elif key == "non_prod":
254
337
  if not value:
255
338
  self.operationalMode = 1
@@ -297,6 +380,9 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
297
380
  if value is not None and value != "":
298
381
  self.slsLicenseFileLocal = value
299
382
  self.setParam("sls_action", "install")
383
+ elif key == "db2_license_file":
384
+ if value is not None and value != "":
385
+ self.db2LicenseFileLocal = value
300
386
  elif key == "dedicated_sls":
301
387
  if value:
302
388
  self.setParam("sls_namespace", f"mas-{self.args.aiservice_instance_id}-sls")
@@ -328,7 +414,7 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
328
414
  self.fatalError(f"Unsupported format for {key} ({value}). Expected int:int:boolean")
329
415
 
330
416
  # Arguments that we don't need to do anything with
331
- elif key in ["accept_license", "dev_mode", "skip_pre_check", "skip_grafana_install", "no_confirm", "help", "advanced", "simplified"]:
417
+ elif key in ["accept_license", "dev_mode", "skip_pre_check", "skip_preinstall_rbac", "skip_grafana_install", "no_confirm", "help", "advanced", "simplified"]:
332
418
  pass
333
419
 
334
420
  elif key == "manual_certificates":
@@ -364,6 +450,13 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
364
450
  self.validateCatalogSource()
365
451
  self.licensePrompt()
366
452
 
453
+ if self.getParam("permission_mode") != "" and not isVersionEqualOrAfter('9.2.0', self.getParam("aiservice_channel")):
454
+ self.fatalError("--permission-mode is supported only for AI Service releases aligned to MAS 9.2.0 and later")
455
+
456
+ # Set default permission_mode for 9.2.0+ if not provided
457
+ if isVersionEqualOrAfter('9.2.0', self.getParam("aiservice_channel")) and self.getParam("permission_mode") == "":
458
+ self.setParam("permission_mode", "cluster")
459
+
367
460
  @logMethodCall
368
461
  def install(self, argv):
369
462
  """
@@ -403,6 +496,9 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
403
496
  if args.skip_pre_check:
404
497
  self.setParam("skip_pre_check", "true")
405
498
 
499
+ if hasattr(args, 'skip_preinstall_rbac') and args.skip_preinstall_rbac:
500
+ self.setParam("skip_preinstall_rbac", "true")
501
+
406
502
  if instanceId is None:
407
503
  self.printH1("Set Target OpenShift Cluster")
408
504
  # Connect to the target cluster
@@ -444,8 +540,13 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
444
540
  else:
445
541
  self.nonInteractiveMode()
446
542
 
447
- # Set up the sls license file
543
+ self.evaluatePreInstallRBACAccess()
544
+
545
+ # Set up the sls and db2 license file
448
546
  self.slsLicenseFile()
547
+ self.db2LicenseFile()
548
+
549
+ self.aiserviceConfig()
449
550
 
450
551
  # Show a summary of the installation configuration
451
552
  self.printH1("Non-Interactive Install Command")
@@ -480,20 +581,15 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
480
581
 
481
582
  with Halo(text=f'Preparing namespace ({pipelinesNamespace})', spinner=self.spinner) as h:
482
583
  createNamespace(self.dynamicClient, pipelinesNamespace)
483
- prepareAiServicePipelinesNamespace(
484
- dynClient=self.dynamicClient,
485
- instanceId=self.getParam("aiservice_instance_id"),
486
- storageClass=self.pipelineStorageClass,
487
- accessMode=self.pipelineStorageAccessMode,
488
- configureRBAC=(self.getParam("service_account_name") == "")
489
- )
490
584
  prepareInstallSecrets(
491
585
  dynClient=self.dynamicClient,
492
586
  namespace=pipelinesNamespace,
493
587
  slsLicenseFile=self.slsLicenseFileSecret,
588
+ db2LicenseFile=self.db2LicenseFileSecret,
494
589
  additionalConfigs=self.additionalConfigsSecret,
495
590
  podTemplates=self.podTemplatesSecret,
496
591
  certs=self.certsSecret,
592
+ aiserviceConfig=self.aiserviceConfigSecret,
497
593
  slack_token=self.getParam("slack_token"),
498
594
  slack_channel=self.getParam("slack_channel")
499
595
  )
@@ -502,6 +598,17 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
502
598
 
503
599
  h.stop_and_persist(symbol=self.successIcon, text=f"Namespace is ready ({pipelinesNamespace})")
504
600
 
601
+ if self.applyPreInstallMASRBAC:
602
+ with Halo(text=f"Setting up pre-install RBAC for AI Service instance {self.getParam('aiservice_instance_id')}...", spinner=self.spinner) as h:
603
+ applyPreInstallMASRBAC(
604
+ dynClient=self.dynamicClient,
605
+ masVersion=".".join(self.getParam("aiservice_channel").split(".")[:2]),
606
+ masInstanceId=self.getParam("aiservice_instance_id"),
607
+ permissionMode=self.getParam("permission_mode"),
608
+ selectedApps=["aiservice"]
609
+ )
610
+ h.stop_and_persist(symbol=self.successIcon, text=f"Pre-install RBAC for AI Service is ready for {self.getParam('aiservice_instance_id')}")
611
+
505
612
  with Halo(text='Testing availability of MAS CLI image in cluster', spinner=self.spinner) as h:
506
613
  testCLI()
507
614
  h.stop_and_persist(symbol=self.successIcon, text="MAS CLI image deployment test completed")
@@ -598,6 +705,23 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
598
705
  self.setParam("tenant_entitlement_start_date", today.strftime('%Y-%m-%d'))
599
706
  self.promptForString("Entitlement end date (YYYY-MM-DD)", "tenant_entitlement_end_date", default=oneyear.strftime('%Y-%m-%d'))
600
707
 
708
+ self.aiserviceTenantSchedulingConfigFileLocal = None
709
+ self.configSchedulingConstraints()
710
+
711
+ @logMethodCall
712
+ def configSchedulingConstraints(self):
713
+ if self.showAdvancedOptions:
714
+ self.printH1("Scheduling configuration for AI Workloads")
715
+ self.printDescription(content=[
716
+ "AI Service supports configuring tolerations and nodeSelector per tenant to schedule AI workloads(training pipelines & Inference services) on dedicated nodes.",
717
+ "To configure tolerations and nodeSelector, create a YAML configuration file",
718
+ "The YAML file must contain `pipeline` and/or `predictor` objects. Each object can have:",
719
+ " `tolerations`: List of Kubernetes tolerations (required fields: `key`, `operator`, `effect`)",
720
+ " `nodeSelector`: Dictionary of node label key-value pairs",
721
+ ])
722
+
723
+ self.aiserviceTenantSchedulingConfigFileLocal = self.promptForFile("Scheduling configuration YAML file", mustExist=True, envVar="AISERVICE_TENANT_SCHEDULING_CONFIG_FILE")
724
+
601
725
  def _setMinioStorageDefaults(self) -> None:
602
726
  """
603
727
  Set MinIO storage defaults when MinIO is being installed in-cluster.
@@ -96,6 +96,10 @@ class aiServiceInstallArgBuilderMixin():
96
96
  command += f" --dev-mode{newline}"
97
97
  if self.getParam('skip_pre_check') is True:
98
98
  command += f" --skip-pre-check{newline}"
99
+ if self.getParam('permission_mode') != "":
100
+ command += f" --permission-mode \"{self.getParam('permission_mode')}\"{newline}"
101
+ if self.getParam('skip_preinstall_rbac') != "":
102
+ command += f" --skip-preinstall-rbac{newline}"
99
103
  if self.getParam('image_pull_policy') != "":
100
104
  command += f" --image-pull-policy {self.getParam('image_pull_policy')}{newline}"
101
105
  if self.getParam('service_account_name') != "":
@@ -172,6 +176,8 @@ class aiServiceInstallArgBuilderMixin():
172
176
  command += f" --tenant-entitlement-start-date \"{self.getParam('tenant_entitlement_start_date')}\"{newline}"
173
177
  if self.getParam('tenant_entitlement_end_date') != "":
174
178
  command += f" --tenant-entitlement-end-date \"{self.getParam('tenant_entitlement_end_date')}\"{newline}"
179
+ if self.aiserviceTenantSchedulingConfigFileLocal:
180
+ command += f" --tenant-scheduling-config-file \"{self.aiserviceTenantSchedulingConfigFileLocal}\"{newline}"
175
181
 
176
182
  if self.getParam('rsl_url') != "":
177
183
  command += f" --rsl-url \"{self.getParam('rsl_url')}\"{newline}"
@@ -184,6 +190,8 @@ class aiServiceInstallArgBuilderMixin():
184
190
 
185
191
  if self.getParam('db2_channel') != "":
186
192
  command += f" --db2-channel \"{self.getParam('db2_channel')}\"{newline}"
193
+ if self.db2LicenseFileLocal:
194
+ command += f" --db2-license-file \"{self.db2LicenseFileLocal}\""
187
195
 
188
196
  command += " --accept-license --no-confirm"
189
197
  return command
@@ -23,7 +23,7 @@ def isValidFile(parser, arg) -> str:
23
23
 
24
24
 
25
25
  aiServiceinstallArgParser = argparse.ArgumentParser(
26
- prog="mas install-aiservice",
26
+ prog="mas aiservice-install",
27
27
  description="\n".join([
28
28
  f"IBM Maximo Application Suite Admin CLI v{packageVersion}",
29
29
  "Install Aiservice by configuring and launching the Tekton Pipeline.\n",
@@ -435,6 +435,20 @@ aiserviceAdvancedArgGroup.add_argument(
435
435
  required=False,
436
436
  help="Provide the name of the Issuer to configure AI Service to issue certificates",
437
437
  )
438
+ aiserviceAdvancedArgGroup.add_argument(
439
+ "--permission-mode",
440
+ dest="permission_mode",
441
+ required=False,
442
+ choices=["cluster", "namespaced", "minimal"],
443
+ help="The permission mode used to determine which pre-install RBAC manifests are applied for AI Service (MAS 9.2+ advanced option)"
444
+ )
445
+ aiserviceAdvancedArgGroup.add_argument(
446
+ "--skip-preinstall-rbac",
447
+ dest="skip_preinstall_rbac",
448
+ required=False,
449
+ action="store_true",
450
+ help="Skip pre-install RBAC setup (non-interactive mode only)"
451
+ )
438
452
  aiserviceAdvancedArgGroup.add_argument(
439
453
  "--enable-ipv6",
440
454
  dest="enable_ipv6",
@@ -444,6 +458,13 @@ aiserviceAdvancedArgGroup.add_argument(
444
458
  action="store_const",
445
459
  const="true"
446
460
  )
461
+ aiserviceAdvancedArgGroup.add_argument(
462
+ "--tenant-scheduling-config-file",
463
+ dest="tenant_scheduling_config_file",
464
+ required=False,
465
+ help="Path to the YAML file that contains the scheduling configuration for tenant",
466
+ type=lambda x: isValidFile(aiServiceinstallArgParser, x)
467
+ )
447
468
 
448
469
 
449
470
  # IBM Db2 Universal Operator
@@ -460,7 +481,11 @@ db2ArgGroup.add_argument(
460
481
  required=False,
461
482
  help="Subscription channel for Db2u"
462
483
  )
463
-
484
+ db2ArgGroup.add_argument(
485
+ "--db2-license-file",
486
+ required=False,
487
+ help="Db2 License File for Db2"
488
+ )
464
489
 
465
490
  # Development Mode
466
491
  # -----------------------------------------------------------------------------
@@ -538,6 +563,18 @@ otherArgGroup.add_argument(
538
563
  required=False,
539
564
  help="Run the install pipeline under a custom service account (also disables creation of the default 'pipeline' service account)",
540
565
  )
566
+ otherArgGroup.add_argument(
567
+ "--slack-token",
568
+ dest="slack_token",
569
+ required=False,
570
+ help="Slack bot token for sending pipeline notifications"
571
+ )
572
+ otherArgGroup.add_argument(
573
+ "--slack-channel",
574
+ dest="slack_channel",
575
+ required=False,
576
+ help="Slack channel(s) for notifications (comma-separated for multiple channels)"
577
+ )
541
578
 
542
579
  otherArgGroup.add_argument(
543
580
  "-h", "--help",
@@ -40,6 +40,7 @@ optionalParams = [
40
40
  "db2_timezone",
41
41
  "db2_namespace",
42
42
  "db2_channel",
43
+ "db2_license_file",
43
44
  "db2_affinity_key",
44
45
  "db2_affinity_value",
45
46
  "db2_tolerate_key",
@@ -100,10 +101,14 @@ optionalParams = [
100
101
  "rsl_token",
101
102
  "rsl_ca_crt",
102
103
  "environment_type",
104
+ "configure_aiassistant",
103
105
 
104
106
  # Certificate Issuer
105
107
  "aiservice_certificate_issuer",
106
108
 
109
+ # permission mode
110
+ "permission_mode",
111
+
107
112
  # Enable IPv6 networking
108
113
  "enable_ipv6",
109
114
 
@@ -46,17 +46,23 @@ class aiServiceInstallSummarizerMixin():
46
46
  self.printParamSummary("Release", "aiservice_channel")
47
47
  self.printParamSummary("Instance ID", "aiservice_instance_id")
48
48
  self.printParamSummary("Environment Type", "environment_type")
49
+ if self.getParam("permission_mode") not in [None, ""]:
50
+ self.printParamSummary("Permission Mode", "permission_mode")
51
+ self.printSummary("Skip Pre-Install RBAC", "Yes" if self.getParam('skip_preinstall_rbac') == "true" else "No")
49
52
 
50
53
  if "aiservice_certificate_issuer" in self.params:
51
54
  self.printParamSummary("Certificate Issuer", "aiservice_certificate_issuer")
52
55
 
53
56
  self.printParamSummary("Configure AI Service to run in IPv6 mode", "enable_ipv6")
54
57
 
55
- self.printH2("AI Service Tenant Entitlement")
58
+ self.printH2("AI Service Tenant Configuration")
56
59
  self.printParamSummary("Entitlement Type", "tenant_entitlement_type")
57
60
  self.printParamSummary("Start Date", "tenant_entitlement_start_date")
58
61
  self.printParamSummary("End Date", "tenant_entitlement_end_date")
59
62
 
63
+ if self.aiserviceTenantSchedulingConfigFileLocal:
64
+ self.printSummary("Scheduling configuration file", self.aiserviceTenantSchedulingConfigFileLocal)
65
+
60
66
  self.printH2("S3 Configuration")
61
67
  # self.printParamSummary("Storage provider", "aiservice_s3_provider")
62
68
  if self.getParam("minio_root_user") is not None and self.getParam("minio_root_user") != "":
@@ -61,6 +61,18 @@ otherArgGroup.add_argument(
61
61
  default=False,
62
62
  help="Configure upgrade for development mode",
63
63
  )
64
+ otherArgGroup.add_argument(
65
+ "--slack-token",
66
+ dest="slack_token",
67
+ required=False,
68
+ help="Slack bot token for sending pipeline notifications"
69
+ )
70
+ otherArgGroup.add_argument(
71
+ "--slack-channel",
72
+ dest="slack_channel",
73
+ required=False,
74
+ help="Slack channel(s) for notifications (comma-separated for multiple channels)"
75
+ )
64
76
  otherArgGroup.add_argument(
65
77
  '-h', "--help",
66
78
  action='help',
@@ -120,7 +120,7 @@ class BaseApp(PrintMixin, PromptMixin):
120
120
  logging.getLogger('asyncio').setLevel(logging.INFO)
121
121
 
122
122
  # Supports extended semver, unlike mas.cli.__version__
123
- self.version: str = "20.2.1"
123
+ self.version: str = "21.1.0"
124
124
  self.h1count: int = 0
125
125
  self.h2count: int = 0
126
126
 
@@ -60,6 +60,52 @@ class ConfigGeneratorMixin():
60
60
  f.write(cfg)
61
61
  f.write('\n')
62
62
 
63
+ def generateAiCfg(self, instanceId: str, scope: str, destination: str, workspaceId: str = "") -> None:
64
+ templateFile = path.join(self.templatesDir, "aicfg.yml.j2")
65
+ with open(templateFile) as tFile:
66
+ template = Template(tFile.read())
67
+
68
+ if scope == "workspace":
69
+ assert workspaceId != ""
70
+
71
+ name = self.promptForString("Configuration Display Name", default="AI Service Configuration")
72
+ url = self.promptForString("AI Service URL")
73
+ tenantId = self.promptForString("AI Service Tenant ID")
74
+ apikey = self.promptForString("AI Service API Key", isPassword=True)
75
+
76
+ enabled = self.yesOrNo("Enable AI Service (set aiService.enabled to true)")
77
+ aiAssistantEnabled = self.yesOrNo("Enable AI Assistant Agent (AI assistant for MAS)")
78
+ sslEnabled = self.yesOrNo("Enable SSL Connection")
79
+
80
+ if sslEnabled:
81
+ sslCertFile = self.promptForFile("Path to certificate file")
82
+ with open(sslCertFile) as cFile:
83
+ certLocalFileContent = cFile.read()
84
+ else:
85
+ certLocalFileContent = ""
86
+
87
+ cfg = template.render(
88
+ scope=scope,
89
+
90
+ mas_instance_id=instanceId,
91
+ mas_workspace_id=workspaceId,
92
+
93
+ cfg_display_name=name,
94
+
95
+ ai_url=url,
96
+ ai_tenant_id=tenantId,
97
+ ai_apikey=apikey,
98
+ ai_enabled=enabled,
99
+ ai_assistant_enabled=aiAssistantEnabled,
100
+
101
+ ai_ssl_enabled=sslEnabled,
102
+ ai_cert_local_file_content=certLocalFileContent
103
+ )
104
+
105
+ with open(destination, 'w') as f:
106
+ f.write(cfg)
107
+ f.write('\n')
108
+
63
109
  def generateMongoCfg(self, instanceId: str, destination: str) -> None:
64
110
  templateFile = path.join(self.templatesDir, "suite_mongocfg.yml.j2")
65
111