mas-cli 21.4.0__tar.gz → 21.4.1__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 (143) hide show
  1. {mas_cli-21.4.0/src/mas_cli.egg-info → mas_cli-21.4.1}/PKG-INFO +1 -1
  2. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/__init__.py +1 -1
  3. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/aiservice/install/app.py +12 -12
  4. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/aiservice/install/argBuilder.py +3 -3
  5. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/aiservice/install/summarizer.py +3 -3
  6. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/cli.py +71 -23
  7. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/install/app.py +47 -26
  8. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/install/argBuilder.py +8 -3
  9. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/install/argParser.py +9 -0
  10. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/install/summarizer.py +13 -6
  11. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/mirror/app.py +1 -0
  12. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/mirror/config.py +2 -1
  13. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/pre_install/app.py +68 -54
  14. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/pre_install/argParser.py +3 -3
  15. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/ibm-mas-tekton.yaml +231 -440
  16. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/upgrade/app.py +81 -1
  17. {mas_cli-21.4.0 → mas_cli-21.4.1/src/mas_cli.egg-info}/PKG-INFO +1 -1
  18. {mas_cli-21.4.0 → mas_cli-21.4.1}/MANIFEST.in +0 -0
  19. {mas_cli-21.4.0 → mas_cli-21.4.1}/README.md +0 -0
  20. {mas_cli-21.4.0 → mas_cli-21.4.1}/setup.cfg +0 -0
  21. {mas_cli-21.4.0 → mas_cli-21.4.1}/setup.py +0 -0
  22. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/aiservice/install/__init__.py +0 -0
  23. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/aiservice/install/argParser.py +0 -0
  24. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/aiservice/install/params.py +0 -0
  25. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/aiservice/upgrade/__init__.py +0 -0
  26. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/aiservice/upgrade/app.py +0 -0
  27. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/aiservice/upgrade/argParser.py +0 -0
  28. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/backup/__init__.py +0 -0
  29. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/backup/app.py +0 -0
  30. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/backup/argParser.py +0 -0
  31. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/displayMixins.py +0 -0
  32. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/gencfg.py +0 -0
  33. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/install/__init__.py +0 -0
  34. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/install/catalogs.py +0 -0
  35. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/install/params.py +0 -0
  36. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/install/settings/__init__.py +0 -0
  37. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/install/settings/additionalConfigs.py +0 -0
  38. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/install/settings/aiSettings.py +0 -0
  39. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/install/settings/db2Settings.py +0 -0
  40. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/install/settings/kafkaSettings.py +0 -0
  41. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/install/settings/manageSettings.py +0 -0
  42. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/install/settings/mongodbSettings.py +0 -0
  43. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/mirror/__init__.py +0 -0
  44. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/mirror/argParser.py +0 -0
  45. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/pre_install/__init__.py +0 -0
  46. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/restore/__init__.py +0 -0
  47. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/restore/app.py +0 -0
  48. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/restore/argParser.py +0 -0
  49. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/setup_rbac/__init__.py +0 -0
  50. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/setup_rbac/app.py +0 -0
  51. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/setup_rbac/argParser.py +0 -0
  52. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/aicfg.yml.j2 +0 -0
  53. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/facilities-configs.yml.j2 +0 -0
  54. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/jdbccfg.yml.j2 +0 -0
  55. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-data-dictionary-assetdatadictionary.yml +0 -0
  56. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-bascfg.yml +0 -0
  57. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-coreidp.yml +0 -0
  58. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-actions.yml +0 -0
  59. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-auth.yml +0 -0
  60. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-datapower.yml +0 -0
  61. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-devops.yml +0 -0
  62. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-dm.yml +0 -0
  63. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-dsc.yml +0 -0
  64. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-edgeconfig.yml +0 -0
  65. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-fpl.yml +0 -0
  66. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-guardian.yml +0 -0
  67. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-iot.yml +0 -0
  68. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-mbgx.yml +0 -0
  69. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-mfgx.yml +0 -0
  70. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-monitor.yml +0 -0
  71. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-orgmgmt.yml +0 -0
  72. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-provision.yml +0 -0
  73. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-registry.yml +0 -0
  74. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-state.yml +0 -0
  75. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-webui.yml +0 -0
  76. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-healthextaccelerator.yml +0 -0
  77. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-healthextworkspace.yml +0 -0
  78. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-imagestitching.yml +0 -0
  79. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-manageaccelerators.yml +0 -0
  80. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-manageapp.yml +0 -0
  81. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-manageworkspace.yml +0 -0
  82. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-slackproxy.yml +0 -0
  83. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-pushnotificationcfg.yml +0 -0
  84. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-scimcfg.yml +0 -0
  85. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-slscfg.yml +0 -0
  86. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-smtpcfg.yml +0 -0
  87. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-suite.yml +0 -0
  88. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-visualinspection.yml +0 -0
  89. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/best-effort/ibm-sls-licenseservice.yml +0 -0
  90. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-data-dictionary-assetdatadictionary.yml +0 -0
  91. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-bascfg.yml +0 -0
  92. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-coreidp.yml +0 -0
  93. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-actions.yml +0 -0
  94. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-auth.yml +0 -0
  95. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-datapower.yml +0 -0
  96. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-devops.yml +0 -0
  97. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-dm.yml +0 -0
  98. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-dsc.yml +0 -0
  99. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-edgeconfig.yml +0 -0
  100. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-fpl.yml +0 -0
  101. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-guardian.yml +0 -0
  102. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-iot.yml +0 -0
  103. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-mbgx.yml +0 -0
  104. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-mfgx.yml +0 -0
  105. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-monitor.yml +0 -0
  106. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-orgmgmt.yml +0 -0
  107. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-provision.yml +0 -0
  108. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-registry.yml +0 -0
  109. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-state.yml +0 -0
  110. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-webui.yml +0 -0
  111. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-healthextaccelerator.yml +0 -0
  112. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-healthextworkspace.yml +0 -0
  113. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-imagestitching.yml +0 -0
  114. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-manageaccelerators.yml +0 -0
  115. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-manageapp.yml +0 -0
  116. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-manageworkspace.yml +0 -0
  117. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-slackproxy.yml +0 -0
  118. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-pushnotificationcfg.yml +0 -0
  119. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-scimcfg.yml +0 -0
  120. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-slscfg.yml +0 -0
  121. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-smtpcfg.yml +0 -0
  122. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-suite.yml +0 -0
  123. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-visualinspection.yml +0 -0
  124. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/pod-templates/guaranteed/ibm-sls-licenseservice.yml +0 -0
  125. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/templates/suite_mongocfg.yml.j2 +0 -0
  126. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/uninstall/__init__.py +0 -0
  127. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/uninstall/app.py +0 -0
  128. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/uninstall/argParser.py +0 -0
  129. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/update/__init__.py +0 -0
  130. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/update/app.py +0 -0
  131. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/update/argParser.py +0 -0
  132. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/upgrade/__init__.py +0 -0
  133. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/upgrade/argParser.py +0 -0
  134. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/upgrade/settings/__init__.py +0 -0
  135. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas/cli/validators.py +0 -0
  136. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas-cli +0 -0
  137. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas_cli.egg-info/SOURCES.txt +0 -0
  138. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas_cli.egg-info/dependency_links.txt +0 -0
  139. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas_cli.egg-info/requires.txt +0 -0
  140. {mas_cli-21.4.0 → mas_cli-21.4.1}/src/mas_cli.egg-info/top_level.txt +0 -0
  141. {mas_cli-21.4.0 → mas_cli-21.4.1}/test/test_baseapp.py +0 -0
  142. {mas_cli-21.4.0 → mas_cli-21.4.1}/test/test_help.py +0 -0
  143. {mas_cli-21.4.0 → mas_cli-21.4.1}/test/test_slack_params.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mas-cli
3
- Version: 21.4.0
3
+ Version: 21.4.1
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__ = "21.4.0" # Python module compatible semver
13
+ __version__ = "21.4.1" # Python module compatible semver
@@ -77,7 +77,7 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
77
77
  if not isVersionEqualOrAfter("9.2.0", self.getParam("aiservice_channel")):
78
78
  return
79
79
 
80
- if self.getParam("skip_preinstall_rbac") == "true":
80
+ if self.skip_preinstall_rbac:
81
81
  return
82
82
 
83
83
  permissionResults = permissionCheckForRBAC(self.dynamicClient)
@@ -91,7 +91,7 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
91
91
  self.printDescription(
92
92
  [
93
93
  "",
94
- f"You selected the '{self.getParam('permission_mode')}' permission mode.",
94
+ f"You selected the '{self.permission_mode}' permission mode.",
95
95
  "The pre-install RBAC required for this permission mode has not been applied by your current cluster login.",
96
96
  "This step must be completed by an OpenShift cluster administrator before AI Service installation can continue.",
97
97
  "Ask your OpenShift administrator to run 'mas pre-install' for this AI Service instance.",
@@ -107,7 +107,7 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
107
107
  self.fatalError(
108
108
  "\n".join(
109
109
  [
110
- f"You selected the '{self.getParam('permission_mode')}' permission mode.",
110
+ f"You selected the '{self.permission_mode}' permission mode.",
111
111
  "The pre-install RBAC required for this permission mode has not been applied by your current cluster login.",
112
112
  "This step must be completed by an OpenShift cluster administrator before AI Service installation can continue.",
113
113
  "Ask your OpenShift administrator to run 'mas pre-install' for this installation and then rerun 'mas aiservice-install' with --skip-preinstall-rbac.",
@@ -140,9 +140,9 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
140
140
 
141
141
  permissionModeInt = self.promptForInt("Permission Mode", default=1, min=1, max=3)
142
142
  permissionModeMap = {1: "cluster", 2: "namespaced", 3: "minimal"}
143
- self.setParam("permission_mode", permissionModeMap[permissionModeInt])
144
- elif self.getParam("permission_mode") == "":
145
- self.setParam("permission_mode", "cluster")
143
+ self.permission_mode = permissionModeMap[permissionModeInt]
144
+ elif self.permission_mode == "":
145
+ self.permission_mode = "cluster"
146
146
 
147
147
  @logMethodCall
148
148
  def processCatalogChoice(self) -> list:
@@ -466,12 +466,12 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
466
466
  self.validateCatalogSource()
467
467
  self.licensePrompt()
468
468
 
469
- if self.getParam("permission_mode") != "" and not isVersionEqualOrAfter("9.2.0", self.getParam("aiservice_channel")):
469
+ if self.permission_mode != "" and not isVersionEqualOrAfter("9.2.0", self.getParam("aiservice_channel")):
470
470
  self.fatalError("--permission-mode is supported only for AI Service releases aligned to MAS 9.2.0 and later")
471
471
 
472
472
  # Set default permission_mode for 9.2.0+ if not provided
473
- if isVersionEqualOrAfter("9.2.0", self.getParam("aiservice_channel")) and self.getParam("permission_mode") == "":
474
- self.setParam("permission_mode", "cluster")
473
+ if isVersionEqualOrAfter("9.2.0", self.getParam("aiservice_channel")) and self.permission_mode == "":
474
+ self.permission_mode = "cluster"
475
475
 
476
476
  @logMethodCall
477
477
  def install(self, argv):
@@ -487,6 +487,7 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
487
487
  self.noConfirm = args.no_confirm
488
488
  self.licenseAccepted = args.accept_license
489
489
  self.devMode = args.dev_mode
490
+ self.permission_mode = args.permission_mode if args.permission_mode else ""
490
491
 
491
492
  self.printDescription(
492
493
  [
@@ -514,8 +515,7 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
514
515
  if args.skip_pre_check:
515
516
  self.setParam("skip_pre_check", "true")
516
517
 
517
- if hasattr(args, "skip_preinstall_rbac") and args.skip_preinstall_rbac:
518
- self.setParam("skip_preinstall_rbac", "true")
518
+ self.skip_preinstall_rbac = hasattr(args, "skip_preinstall_rbac") and args.skip_preinstall_rbac
519
519
 
520
520
  if instanceId is None:
521
521
  self.printH1("Set Target OpenShift Cluster")
@@ -625,7 +625,7 @@ class AiServiceInstallApp(BaseApp, aiServiceInstallArgBuilderMixin, aiServiceIns
625
625
  dynClient=self.dynamicClient,
626
626
  masVersion=".".join(self.getParam("aiservice_channel").split(".")[:2]),
627
627
  masInstanceId=self.getParam("aiservice_instance_id"),
628
- permissionMode=self.getParam("permission_mode"),
628
+ permissionMode=self.permission_mode,
629
629
  selectedApps=["aiservice"],
630
630
  )
631
631
  h.stop_and_persist(symbol=self.successIcon, text=f"Pre-install RBAC for AI Service is ready for {self.getParam('aiservice_instance_id')}")
@@ -96,9 +96,9 @@ 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") != "":
99
+ if self.permission_mode != "":
100
+ command += f' --permission-mode "{self.permission_mode}"{newline}'
101
+ if self.skip_preinstall_rbac:
102
102
  command += f" --skip-preinstall-rbac{newline}"
103
103
  if self.getParam("image_pull_policy") != "":
104
104
  command += f" --image-pull-policy {self.getParam('image_pull_policy')}{newline}"
@@ -46,9 +46,9 @@ 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
+ if self.permission_mode not in [None, ""]:
50
+ self.printSummary("Permission Mode", self.permission_mode)
51
+ self.printSummary("Skip Pre-Install RBAC", "Yes" if self.skip_preinstall_rbac else "No")
52
52
 
53
53
  if "aiservice_certificate_issuer" in self.params:
54
54
  self.printParamSummary("Certificate Issuer", "aiservice_certificate_issuer")
@@ -119,7 +119,7 @@ class BaseApp(PrintMixin, PromptMixin):
119
119
  logging.getLogger("asyncio").setLevel(logging.INFO)
120
120
 
121
121
  # Supports extended semver, unlike mas.cli.__version__
122
- self.version: str = "21.4.0"
122
+ self.version: str = "21.4.1"
123
123
  self.h1count: int = 0
124
124
  self.h2count: int = 0
125
125
 
@@ -147,6 +147,8 @@ class BaseApp(PrintMixin, PromptMixin):
147
147
 
148
148
  self._isSNO: bool | None = None
149
149
  self._isAirgap: bool | None = None
150
+ self.useCliDigest: bool = False
151
+ self.cliDigest: str | None = None
150
152
 
151
153
  # Until we connect to the cluster we don't know what architecture it's worker nodes are
152
154
  self.architecture: str | None = None
@@ -255,44 +257,90 @@ class BaseApp(PrintMixin, PromptMixin):
255
257
  if path.exists(self.tektonDefsWithDigestPath):
256
258
  logger.debug(f"We have already generated {self.tektonDefsWithDigestPath}")
257
259
  self.tektonDefsPath = self.tektonDefsWithDigestPath
258
- elif isAirgapInstall(self.dynamicClient):
259
- # We need to modify the tekton definitions to
260
+ elif isAirgapInstall(self.dynamicClient) or self.useCliDigest:
261
+ # We need to modify the tekton definitions to use image digest
260
262
  imageWithoutDigest = f"quay.io/ibmmas/cli:{self.version}"
261
- self.printH1("Disconnected OpenShift Preparation")
262
- self.printDescription(
263
- [f"Unless the {imageWithoutDigest} image is accessible from your cluster the MAS CLI container image must be present in your mirror registry"]
264
- )
265
- cmdArray = ["skopeo", "inspect", f"docker://{imageWithoutDigest}"]
266
- logger.info(f"Skopeo inspect command: {' '.join(cmdArray)}")
267
- skopeoResult = runCmd(cmdArray)
268
- if skopeoResult.successful():
269
- skopeoData = json.loads(skopeoResult.out)
270
- logger.info(f"Skopeo Data for {imageWithoutDigest}: {skopeoData}")
271
- if "Digest" not in skopeoData:
272
- self.fatalError("Recieved bad data inspecting CLI manifest to determine digest")
273
- cliImageDigest = skopeoData["Digest"]
263
+
264
+ if self.useCliDigest:
265
+ self.printH1("CLI Digest Preparation")
266
+ self.printDescription(
267
+ [f"Converting Tekton pipeline definitions to use {imageWithoutDigest} image digest instead of tag to avoid registry QPS issues"]
268
+ )
269
+
270
+ # Check if user provided a specific digest
271
+ if self.cliDigest:
272
+ logger.info(f"Using user-provided CLI image digest: {self.cliDigest}")
273
+ cliImageDigest = self.cliDigest
274
+ else:
275
+ logger.info(f"--use-cli-digest flag is set, will lookup digest for {imageWithoutDigest}")
276
+ # Auto-lookup the digest
277
+ cmdArray = ["skopeo", "inspect", f"docker://{imageWithoutDigest}"]
278
+ logger.info(f"Skopeo inspect command: {' '.join(cmdArray)}")
279
+ skopeoResult = runCmd(cmdArray)
280
+ if skopeoResult.successful():
281
+ skopeoData = json.loads(skopeoResult.out)
282
+ logger.debug(f"Skopeo Data for {imageWithoutDigest}: {skopeoData}")
283
+ if "Digest" not in skopeoData:
284
+ self.fatalError("Recieved bad data inspecting CLI manifest to determine digest")
285
+ cliImageDigest = skopeoData["Digest"]
286
+ logger.info(f"Successfully retrieved CLI image digest: {cliImageDigest}")
287
+ else:
288
+ warning = f"Unable to retrieve image digest for {imageWithoutDigest} ({skopeoResult.rc})"
289
+ self.printWarning(warning)
290
+ logger.warning(warning)
291
+ logger.warning(skopeoResult.err)
292
+ if self.noConfirm:
293
+ self.fatalError("Unable to automatically determine CLI image digest and --no-confirm flag has been set")
294
+ else:
295
+ cliImageDigest = self.promptForString(f"Enter {imageWithoutDigest} image digest")
296
+ logger.info(f"User provided CLI image digest: {cliImageDigest}")
274
297
  else:
275
- warning = f"Unable to retrieve image digest for {imageWithoutDigest} ({skopeoResult.rc})"
276
- self.printWarning(warning)
277
- logger.warning(warning)
278
- logger.warning(skopeoResult.err)
279
- if self.noConfirm:
280
- self.fatalError("Unable to automatically determine CLI image digest and --no-confirm flag has been set")
298
+ # Airgap install
299
+ self.printH1("Disconnected OpenShift Preparation")
300
+ self.printDescription(
301
+ [
302
+ f"Unless the {imageWithoutDigest} image is accessible from your cluster the MAS CLI container image must be present in your mirror registry"
303
+ ]
304
+ )
305
+ logger.info(f"Airgap install detected, will lookup digest for {imageWithoutDigest}")
306
+
307
+ cmdArray = ["skopeo", "inspect", f"docker://{imageWithoutDigest}"]
308
+ logger.info(f"Skopeo inspect command: {' '.join(cmdArray)}")
309
+ skopeoResult = runCmd(cmdArray)
310
+ if skopeoResult.successful():
311
+ skopeoData = json.loads(skopeoResult.out)
312
+ logger.debug(f"Skopeo Data for {imageWithoutDigest}: {skopeoData}")
313
+ if "Digest" not in skopeoData:
314
+ self.fatalError("Recieved bad data inspecting CLI manifest to determine digest")
315
+ cliImageDigest = skopeoData["Digest"]
316
+ logger.info(f"Successfully retrieved CLI image digest: {cliImageDigest}")
281
317
  else:
282
- cliImageDigest = self.promptForString(f"Enter {imageWithoutDigest} image digest")
318
+ warning = f"Unable to retrieve image digest for {imageWithoutDigest} ({skopeoResult.rc})"
319
+ self.printWarning(warning)
320
+ logger.warning(warning)
321
+ logger.warning(skopeoResult.err)
322
+ if self.noConfirm:
323
+ self.fatalError("Unable to automatically determine CLI image digest and --no-confirm flag has been set")
324
+ else:
325
+ cliImageDigest = self.promptForString(f"Enter {imageWithoutDigest} image digest")
326
+ logger.info(f"User provided CLI image digest: {cliImageDigest}")
283
327
 
284
328
  # Overwrite the tekton definitions with one that uses the looked up image digest
285
329
  imageWithDigest = f"quay.io/ibmmas/cli@{cliImageDigest}"
286
330
  self.printHighlight(f"\nConverting Tekton definitions to use {imageWithDigest}")
331
+ logger.info(f"Converting from tag-based image ({imageWithoutDigest}) to digest-based image ({imageWithDigest})")
332
+
287
333
  with open(self.tektonDefsPath, "r") as file:
288
334
  tektonDefsWithoutDigest = file.read()
289
335
 
290
336
  tektonDefsWithDigest = tektonDefsWithoutDigest.replace(imageWithoutDigest, imageWithDigest)
291
337
 
338
+ logger.info(f"Writing Tekton definitions with digest to {self.tektonDefsWithDigestPath}")
292
339
  with open(self.tektonDefsWithDigestPath, "w") as file:
293
340
  file.write(tektonDefsWithDigest)
294
341
 
295
342
  self.tektonDefsPath = self.tektonDefsWithDigestPath
343
+ logger.info("Successfully created Tekton definitions with CLI digest")
296
344
 
297
345
  @logMethodCall
298
346
  def getCompatibleVersions(self, coreChannel: str, appId: str) -> List[str]:
@@ -123,12 +123,10 @@ class InstallApp(
123
123
  if not isVersionEqualOrAfter("9.2.0", self.getParam("mas_channel")):
124
124
  return
125
125
 
126
- # TODO: Sort out the openshift-ingress exception properly.
127
- # For now, keep continue pre-install RBAC for minimal mode here.
128
- # if self.getParam("mas_permission_mode") == "minimal":
129
- # return
126
+ if self.mas_permission_mode == "minimal":
127
+ return
130
128
 
131
- if self.getParam("skip_preinstall_rbac") == "true":
129
+ if self.skip_preinstall_rbac:
132
130
  return
133
131
 
134
132
  permissionResults = permissionCheckForRBAC(self.dynamicClient)
@@ -142,26 +140,26 @@ class InstallApp(
142
140
  self.printDescription(
143
141
  [
144
142
  "",
145
- f"You selected the '{self.getParam('mas_permission_mode')}' permission mode.",
143
+ f"You selected the '{self.mas_permission_mode}' permission mode.",
146
144
  "The pre-install RBAC required for this permission mode has not been applied by your current cluster login.",
147
145
  "This step must be completed by an OpenShift cluster administrator before MAS installation can continue.",
148
- "Ask your OpenShift administrator to run 'mas pre-install' for this MAS instance, MAS version, permission mode, and selected apps.",
146
+ "Ask your OpenShift administrator to run 'mas pre-install' for this MAS instance, MAS channel, permission mode, and selected apps.",
149
147
  "If that has already been done, you can continue the installation without applying it again.",
150
148
  ]
151
149
  )
152
150
 
153
151
  if not self.yesOrNo("Has your OpenShift administrator already run 'mas pre-install' for this installation"):
154
152
  self.fatalError(
155
- "Installation aborted. Ask your OpenShift administrator to run 'mas pre-install' for this installation and then run mas install again with --skip-preinstall-rbac."
153
+ "Installation aborted. Ask your OpenShift administrator to run 'mas pre-install' for this installation and then run 'mas install' again with --skip-preinstall-rbac using the same permission mode that was used in 'mas pre-install'."
156
154
  )
157
155
  else:
158
156
  self.fatalError(
159
157
  "\n".join(
160
158
  [
161
- f"You selected the '{self.getParam('mas_permission_mode')}' permission mode.",
159
+ f"You selected the '{self.mas_permission_mode}' permission mode.",
162
160
  "The pre-install RBAC required for this permission mode has not been applied by your current cluster login.",
163
161
  "This step must be completed by an OpenShift cluster administrator before MAS installation can continue.",
164
- "Ask your OpenShift administrator to run 'mas pre-install' for this installation and then rerun 'mas install' with --skip-preinstall-rbac.",
162
+ "Ask your OpenShift administrator to run 'mas pre-install' for this installation and then rerun 'mas install' with --skip-preinstall-rbac using the same permission mode that was used in 'mas pre-install'.",
165
163
  ]
166
164
  )
167
165
  )
@@ -776,9 +774,9 @@ class InstallApp(
776
774
 
777
775
  permissionModeInt = self.promptForInt("Permission Mode", default=1, min=1, max=3)
778
776
  permissionModeMap = {1: "cluster", 2: "namespaced", 3: "minimal"}
779
- self.setParam("mas_permission_mode", permissionModeMap[permissionModeInt])
777
+ self.mas_permission_mode = permissionModeMap[permissionModeInt]
780
778
 
781
- if self.getParam("mas_permission_mode") in ["namespaced", "minimal"]:
779
+ if self.mas_permission_mode in ["namespaced", "minimal"]:
782
780
  self.setParam("mas_issuer_kind", "Issuer")
783
781
  else:
784
782
  self.printDescription(
@@ -795,18 +793,18 @@ class InstallApp(
795
793
  )
796
794
  issuerKindChoice = self.promptForInt("Certificate issuer kind", min=1, max=2, default=2)
797
795
  self.setParam("mas_issuer_kind", "ClusterIssuer" if issuerKindChoice == 2 else "Issuer")
798
- elif self.getParam("mas_permission_mode") == "":
799
- self.setParam("mas_permission_mode", "cluster")
796
+ elif self.mas_permission_mode == "":
797
+ self.mas_permission_mode = "cluster"
800
798
  self.setParam("mas_issuer_kind", "ClusterIssuer")
801
799
 
802
800
  def _handleDNSIntegrationRestriction(self):
803
801
  if not isVersionEqualOrAfter("9.2.0", self.getParam("mas_channel")):
804
802
  return False
805
803
 
806
- if self.getParam("mas_permission_mode") in ["namespaced", "minimal"]:
804
+ if self.mas_permission_mode in ["namespaced", "minimal"]:
807
805
  self.printDescription(
808
806
  [
809
- f"You are using the {self.getParam('mas_permission_mode')} permission mode.",
807
+ f"You are using the {self.mas_permission_mode} permission mode.",
810
808
  "DNS integration is not available in this mode.",
811
809
  "If you use a custom domain, you need to configure DNS manually.",
812
810
  ]
@@ -2226,6 +2224,7 @@ class InstallApp(
2226
2224
  "advanced",
2227
2225
  "simplified",
2228
2226
  "mas_configure_ingress",
2227
+ "use_cli_digest",
2229
2228
  ]:
2230
2229
  pass
2231
2230
 
@@ -2340,17 +2339,17 @@ class InstallApp(
2340
2339
  if self.getParam("mas_issuer_kind") != "" and not isVersionEqualOrAfter("9.2.0", self.getParam("mas_channel")):
2341
2340
  self.fatalError(f"--mas-issuer-kind is only supported for MAS 9.2+ (selected channel: {self.getParam('mas_channel')})")
2342
2341
 
2343
- if self.getParam("mas_permission_mode") != "":
2342
+ if self.mas_permission_mode != "":
2344
2343
  if not isVersionEqualOrAfter("9.2.0", self.getParam("mas_channel")):
2345
2344
  self.fatalError(f"--permission-mode is only supported for MAS 9.2+ (selected channel: {self.getParam('mas_channel')})")
2346
2345
  else:
2347
2346
  if self.getParam("mas_issuer_kind") == "":
2348
- if self.getParam("mas_permission_mode") == "cluster":
2347
+ if self.mas_permission_mode == "cluster":
2349
2348
  self.setParam("mas_issuer_kind", "ClusterIssuer")
2350
2349
  else:
2351
2350
  self.setParam("mas_issuer_kind", "Issuer")
2352
2351
 
2353
- if self.getParam("mas_issuer_kind") == "ClusterIssuer" and self.getParam("mas_permission_mode") != "cluster":
2352
+ if self.getParam("mas_issuer_kind") == "ClusterIssuer" and self.mas_permission_mode != "cluster":
2354
2353
  self.fatalError(
2355
2354
  "\n".join(
2356
2355
  [
@@ -2361,21 +2360,21 @@ class InstallApp(
2361
2360
  )
2362
2361
 
2363
2362
  if self.getParam("dns_provider") != "":
2364
- if self.getParam("mas_permission_mode") in [
2363
+ if self.mas_permission_mode in [
2365
2364
  "namespaced",
2366
2365
  "minimal",
2367
2366
  ]:
2368
2367
  self.fatalError(
2369
2368
  "\n".join(
2370
2369
  [
2371
- f"Invalid configuration for permission mode '{self.getParam('mas_permission_mode')}'",
2370
+ f"Invalid configuration for permission mode '{self.mas_permission_mode}'",
2372
2371
  "DNS integration is not available in this mode.",
2373
2372
  "Remove DNS integration option --dns-provider, or switch to --permission-mode cluster and use --mas-issuer-kind ClusterIssuer.",
2374
2373
  ]
2375
2374
  )
2376
2375
  )
2377
2376
 
2378
- if self.getParam("mas_permission_mode") == "cluster" and self.getParam("mas_issuer_kind") == "Issuer":
2377
+ if self.mas_permission_mode == "cluster" and self.getParam("mas_issuer_kind") == "Issuer":
2379
2378
  self.fatalError(
2380
2379
  "\n".join(
2381
2380
  [
@@ -2386,7 +2385,7 @@ class InstallApp(
2386
2385
  )
2387
2386
  )
2388
2387
  elif isVersionEqualOrAfter("9.2.0", self.getParam("mas_channel")):
2389
- self.setParam("mas_permission_mode", "cluster")
2388
+ self.mas_permission_mode = "cluster"
2390
2389
  if self.getParam("mas_issuer_kind") == "":
2391
2390
  self.setParam("mas_issuer_kind", "ClusterIssuer")
2392
2391
 
@@ -2464,6 +2463,7 @@ class InstallApp(
2464
2463
  self.licenseAccepted = args.accept_license
2465
2464
  self.devMode = args.dev_mode
2466
2465
  self.skipGrafanaInstall = args.skip_grafana_install
2466
+ self.mas_permission_mode = args.mas_permission_mode if args.mas_permission_mode else ""
2467
2467
 
2468
2468
  # Set image_pull_policy of the CLI in interactive mode
2469
2469
  if args.image_pull_policy and args.image_pull_policy != "":
@@ -2478,8 +2478,29 @@ class InstallApp(
2478
2478
  if args.skip_pre_check:
2479
2479
  self.setParam("skip_pre_check", "true")
2480
2480
 
2481
- if hasattr(args, "skip_preinstall_rbac") and args.skip_preinstall_rbac:
2482
- self.setParam("skip_preinstall_rbac", "true")
2481
+ self.skip_preinstall_rbac = hasattr(args, "skip_preinstall_rbac") and args.skip_preinstall_rbac
2482
+
2483
+ # Handle --use-cli-digest parameter which can be:
2484
+ # - False (not provided)
2485
+ # - True (provided without value, auto-lookup digest)
2486
+ # - "sha256:..." (provided with specific digest value)
2487
+ if hasattr(args, "use_cli_digest"):
2488
+ use_cli_digest_value = args.use_cli_digest
2489
+ if use_cli_digest_value is False:
2490
+ # Flag not provided
2491
+ self.useCliDigest = False
2492
+ self.cliDigest = None
2493
+ elif use_cli_digest_value is True:
2494
+ # Flag provided without value - auto-lookup digest
2495
+ self.useCliDigest = True
2496
+ self.cliDigest = None
2497
+ else:
2498
+ # Flag provided with digest value
2499
+ self.useCliDigest = True
2500
+ self.cliDigest = use_cli_digest_value
2501
+ else:
2502
+ self.useCliDigest = False
2503
+ self.cliDigest = None
2483
2504
 
2484
2505
  if hasattr(args, "mas_configure_ingress") and args.mas_configure_ingress:
2485
2506
  self.setParam("mas_configure_ingress", "true")
@@ -2687,7 +2708,7 @@ class InstallApp(
2687
2708
  dynClient=self.dynamicClient,
2688
2709
  masVersion=".".join(self.getParam("mas_channel").split(".")[:2]),
2689
2710
  masInstanceId=self.getParam("mas_instance_id"),
2690
- permissionMode=self.getParam("mas_permission_mode"),
2711
+ permissionMode=self.mas_permission_mode,
2691
2712
  selectedApps=self.getSelectedApps(),
2692
2713
  )
2693
2714
  h.stop_and_persist(symbol=self.successIcon, text="Pre-install MAS RBAC applied")
@@ -92,8 +92,8 @@ class installArgBuilderMixin:
92
92
  if self.operationalMode == 2:
93
93
  command += f" --non-prod{newline}"
94
94
 
95
- if self.getParam("mas_permission_mode") != "":
96
- command += f" --permission-mode {self.getParam('mas_permission_mode')}{newline}"
95
+ if self.mas_permission_mode != "":
96
+ command += f" --permission-mode {self.mas_permission_mode}{newline}"
97
97
 
98
98
  if self.getParam("mas_trust_default_cas").lower() == "false":
99
99
  command += f" --disable-ca-trust{newline}"
@@ -608,12 +608,17 @@ class installArgBuilderMixin:
608
608
  command += f" --dev-mode{newline}"
609
609
  if self.getParam("skip_pre_check") is True:
610
610
  command += f" --skip-pre-check{newline}"
611
- if self.getParam("skip_preinstall_rbac") == "true":
611
+ if self.skip_preinstall_rbac:
612
612
  command += f" --skip-preinstall-rbac{newline}"
613
613
  if self.getParam("image_pull_policy") != "":
614
614
  command += f" --image-pull-policy {self.getParam('image_pull_policy')}{newline}"
615
615
  if self.getParam("service_account_name") != "":
616
616
  command += f" --service-account {self.getParam('service_account_name')}{newline}"
617
+ if self.useCliDigest:
618
+ if self.cliDigest:
619
+ command += f" --use-cli-digest {self.cliDigest}{newline}"
620
+ else:
621
+ command += f" --use-cli-digest{newline}"
617
622
 
618
623
  command += " --accept-license --no-confirm"
619
624
  return command
@@ -1571,5 +1571,14 @@ otherArgGroup.add_argument(
1571
1571
  required=False,
1572
1572
  help="Custom service account for install pipeline (disables default 'pipeline' service account creation)",
1573
1573
  )
1574
+ otherArgGroup.add_argument(
1575
+ "--use-cli-digest",
1576
+ dest="use_cli_digest",
1577
+ required=False,
1578
+ nargs="?",
1579
+ const=True,
1580
+ default=False,
1581
+ help="Use CLI image digest instead of tag in Tekton pipelines. Optionally provide a specific digest (e.g., sha256:abc123...), or omit the value to auto-lookup the digest.",
1582
+ )
1574
1583
 
1575
1584
  otherArgGroup.add_argument("-h", "--help", action="help", default=False, help="Show this help message and exit")
@@ -72,6 +72,12 @@ class InstallSummarizerMixin:
72
72
  self.printH2("Pipeline Configuration")
73
73
  self.printParamSummary("Service Account", "service_account_name")
74
74
  self.printParamSummary("Image Pull Policy", "image_pull_policy")
75
+ if self.useCliDigest:
76
+ if self.cliDigest:
77
+ self.printSummary("Use CLI Digest", self.cliDigest)
78
+ else:
79
+ self.printParamSummary("Use CLI Digest", "Yes (auto-lookup)")
80
+
75
81
  self.printSummary(
76
82
  "Skip Pre-Install Healthcheck",
77
83
  "Yes" if self.getParam("skip_pre_check") == "true" else "No",
@@ -101,14 +107,15 @@ class InstallSummarizerMixin:
101
107
 
102
108
  print()
103
109
  self.printSummary("Operational Mode", operationalModeNames[self.operationalMode])
104
- if self.getParam("mas_permission_mode") != "":
105
- self.printParamSummary("Permission Mode", "mas_permission_mode")
110
+ if self.mas_permission_mode != "":
111
+ self.printSummary("Permission Mode", self.mas_permission_mode)
112
+ # Only show "Apply Pre-Install MAS RBAC" when permission mode is defined
113
+ self.printSummary(
114
+ "Apply Pre-Install MAS RBAC",
115
+ "No" if self.skip_preinstall_rbac else "Yes",
116
+ )
106
117
  if self.getParam("mas_issuer_kind") != "":
107
118
  self.printParamSummary("Mas Certificate Issuer Kind", "mas_issuer_kind")
108
- self.printSummary(
109
- "Apply Pre-Install MAS RBAC",
110
- "No" if self.getParam("skip_preinstall_rbac") == "true" else "Yes",
111
- )
112
119
  if self.isAirgap():
113
120
  self.printSummary("Install Mode", "Disconnected Install")
114
121
  else:
@@ -819,6 +819,7 @@ class MirrorApp(BaseApp):
819
819
  # Get version from catalog - handle both direct keys and release-specific keys
820
820
  perReleaseVersions = [
821
821
  "aiservice_version",
822
+ "aiservice_tenant_version",
822
823
  "mas_core_version",
823
824
  "mas_assist_version",
824
825
  "mas_iot_version",
@@ -13,7 +13,8 @@ PACKAGE_CONFIGS = [
13
13
  ("Required Dependencies", "tsm", "ibm-truststore-mgr", "tsm_version"),
14
14
  ("Optional Dependencies", "amlen", "amlen", "amlen_extras_version"),
15
15
  ("Optional Dependencies", "aiservice", "ibm-aiservice", "aiservice_version"),
16
- ("Optional Dependencies", "aiservice", "ibm-aiservice-tenant", "aiservice_version"),
16
+ ("Optional Dependencies", "aiservice", "ibm-aiservice-tenant", "aiservice_tenant_version"),
17
+ ("Optional Dependencies", "aiservice", "opendatahub", "odh_version"),
17
18
  ("Optional Dependencies", "data-dictionary", "ibm-data-dictionary", "dd_version"),
18
19
  ("Optional Dependencies", "db2u-s11", "ibm-db2uoperator-s11", "db2u_version"),
19
20
  ("Optional Dependencies", "db2u-s12", "ibm-db2uoperator-s12", "db2u_version"),