mas-cli 20.1.0__tar.gz → 20.2.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 (139) hide show
  1. {mas_cli-20.1.0/src/mas_cli.egg-info → mas_cli-20.2.0}/PKG-INFO +1 -1
  2. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/__init__.py +3 -1
  3. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/cli.py +7 -1
  4. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/displayMixins.py +37 -8
  5. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/install/app.py +21 -0
  6. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/install/argBuilder.py +3 -0
  7. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/install/argParser.py +18 -4
  8. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/install/catalogs.py +3 -3
  9. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/install/params.py +1 -0
  10. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/install/settings/manageSettings.py +6 -1
  11. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/install/summarizer.py +3 -0
  12. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/mirror/app.py +18 -2
  13. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/mirror/argParser.py +1 -1
  14. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/mirror/config.py +1 -0
  15. mas_cli-20.2.0/src/mas/cli/setup_rbac/__init__.py +9 -0
  16. mas_cli-20.2.0/src/mas/cli/setup_rbac/app.py +64 -0
  17. mas_cli-20.2.0/src/mas/cli/setup_rbac/argParser.py +57 -0
  18. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/ibm-mas-tekton.yaml +406 -218
  19. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/update/app.py +4 -4
  20. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/validators.py +0 -2
  21. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas-cli +32 -10
  22. {mas_cli-20.1.0 → mas_cli-20.2.0/src/mas_cli.egg-info}/PKG-INFO +1 -1
  23. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas_cli.egg-info/SOURCES.txt +3 -0
  24. {mas_cli-20.1.0 → mas_cli-20.2.0}/MANIFEST.in +0 -0
  25. {mas_cli-20.1.0 → mas_cli-20.2.0}/README.md +0 -0
  26. {mas_cli-20.1.0 → mas_cli-20.2.0}/pyproject.toml +0 -0
  27. {mas_cli-20.1.0 → mas_cli-20.2.0}/setup.cfg +0 -0
  28. {mas_cli-20.1.0 → mas_cli-20.2.0}/setup.py +0 -0
  29. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/aiservice/install/__init__.py +0 -0
  30. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/aiservice/install/app.py +0 -0
  31. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/aiservice/install/argBuilder.py +0 -0
  32. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/aiservice/install/argParser.py +0 -0
  33. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/aiservice/install/params.py +0 -0
  34. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/aiservice/install/summarizer.py +0 -0
  35. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/aiservice/upgrade/__init__.py +0 -0
  36. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/aiservice/upgrade/app.py +0 -0
  37. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/aiservice/upgrade/argParser.py +0 -0
  38. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/backup/__init__.py +0 -0
  39. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/backup/app.py +0 -0
  40. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/backup/argParser.py +0 -0
  41. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/gencfg.py +0 -0
  42. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/install/__init__.py +0 -0
  43. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/install/settings/__init__.py +0 -0
  44. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/install/settings/additionalConfigs.py +0 -0
  45. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/install/settings/db2Settings.py +0 -0
  46. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/install/settings/kafkaSettings.py +0 -0
  47. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/install/settings/mongodbSettings.py +0 -0
  48. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/mirror/__init__.py +0 -0
  49. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/restore/__init__.py +0 -0
  50. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/restore/app.py +0 -0
  51. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/restore/argParser.py +0 -0
  52. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/facilities-configs.yml.j2 +0 -0
  53. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/jdbccfg.yml.j2 +0 -0
  54. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-data-dictionary-assetdatadictionary.yml +0 -0
  55. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-bascfg.yml +0 -0
  56. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-coreidp.yml +0 -0
  57. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-actions.yml +0 -0
  58. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-auth.yml +0 -0
  59. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-datapower.yml +0 -0
  60. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-devops.yml +0 -0
  61. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-dm.yml +0 -0
  62. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-dsc.yml +0 -0
  63. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-edgeconfig.yml +0 -0
  64. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-fpl.yml +0 -0
  65. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-guardian.yml +0 -0
  66. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-iot.yml +0 -0
  67. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-mbgx.yml +0 -0
  68. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-mfgx.yml +0 -0
  69. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-monitor.yml +0 -0
  70. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-orgmgmt.yml +0 -0
  71. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-provision.yml +0 -0
  72. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-registry.yml +0 -0
  73. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-state.yml +0 -0
  74. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-webui.yml +0 -0
  75. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-healthextaccelerator.yml +0 -0
  76. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-healthextworkspace.yml +0 -0
  77. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-imagestitching.yml +0 -0
  78. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-manageaccelerators.yml +0 -0
  79. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-manageapp.yml +0 -0
  80. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-manageworkspace.yml +0 -0
  81. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-slackproxy.yml +0 -0
  82. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-pushnotificationcfg.yml +0 -0
  83. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-scimcfg.yml +0 -0
  84. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-slscfg.yml +0 -0
  85. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-smtpcfg.yml +0 -0
  86. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-suite.yml +0 -0
  87. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-mas-visualinspection.yml +0 -0
  88. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/best-effort/ibm-sls-licenseservice.yml +0 -0
  89. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-data-dictionary-assetdatadictionary.yml +0 -0
  90. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-bascfg.yml +0 -0
  91. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-coreidp.yml +0 -0
  92. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-actions.yml +0 -0
  93. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-auth.yml +0 -0
  94. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-datapower.yml +0 -0
  95. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-devops.yml +0 -0
  96. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-dm.yml +0 -0
  97. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-dsc.yml +0 -0
  98. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-edgeconfig.yml +0 -0
  99. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-fpl.yml +0 -0
  100. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-guardian.yml +0 -0
  101. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-iot.yml +0 -0
  102. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-mbgx.yml +0 -0
  103. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-mfgx.yml +0 -0
  104. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-monitor.yml +0 -0
  105. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-orgmgmt.yml +0 -0
  106. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-provision.yml +0 -0
  107. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-registry.yml +0 -0
  108. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-state.yml +0 -0
  109. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-webui.yml +0 -0
  110. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-healthextaccelerator.yml +0 -0
  111. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-healthextworkspace.yml +0 -0
  112. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-imagestitching.yml +0 -0
  113. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-manageaccelerators.yml +0 -0
  114. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-manageapp.yml +0 -0
  115. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-manageworkspace.yml +0 -0
  116. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-slackproxy.yml +0 -0
  117. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-pushnotificationcfg.yml +0 -0
  118. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-scimcfg.yml +0 -0
  119. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-slscfg.yml +0 -0
  120. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-smtpcfg.yml +0 -0
  121. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-suite.yml +0 -0
  122. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-mas-visualinspection.yml +0 -0
  123. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/pod-templates/guaranteed/ibm-sls-licenseservice.yml +0 -0
  124. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/templates/suite_mongocfg.yml.j2 +0 -0
  125. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/uninstall/__init__.py +0 -0
  126. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/uninstall/app.py +0 -0
  127. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/uninstall/argParser.py +0 -0
  128. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/update/__init__.py +0 -0
  129. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/update/argParser.py +0 -0
  130. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/upgrade/__init__.py +0 -0
  131. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/upgrade/app.py +0 -0
  132. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/upgrade/argParser.py +0 -0
  133. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas/cli/upgrade/settings/__init__.py +0 -0
  134. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas_cli.egg-info/dependency_links.txt +0 -0
  135. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas_cli.egg-info/requires.txt +0 -0
  136. {mas_cli-20.1.0 → mas_cli-20.2.0}/src/mas_cli.egg-info/top_level.txt +0 -0
  137. {mas_cli-20.1.0 → mas_cli-20.2.0}/test/test_baseapp.py +0 -0
  138. {mas_cli-20.1.0 → mas_cli-20.2.0}/test/test_help.py +0 -0
  139. {mas_cli-20.1.0 → mas_cli-20.2.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.1.0
3
+ Version: 20.2.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
@@ -8,4 +8,6 @@
8
8
  #
9
9
  # *****************************************************************************
10
10
 
11
- __version__ = "20.1.0" # Python module compatible semver
11
+ from .cli import BaseApp # noqa: F401
12
+
13
+ __version__ = "20.2.0" # Python module compatible semver
@@ -120,12 +120,17 @@ 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.1.0"
123
+ self.version: str = "20.2.0"
124
124
  self.h1count: int = 0
125
125
  self.h2count: int = 0
126
126
 
127
127
  self.localConfigDir: str | None = None
128
+ self.cliRootDir: str = path.join(path.abspath(path.dirname(__file__)), "..", "..", "..", "..")
128
129
  self.templatesDir: str = path.join(path.abspath(path.dirname(__file__)), "templates")
130
+ self.installRBACDir: str = path.join(self.cliRootDir, "rbac", "install")
131
+ if not path.isfile(path.join(self.installRBACDir, "kustomization.yaml")):
132
+ logger.error(f"Could not find install RBAC bundle at {self.installRBACDir}, this is required for the setup-rbac command")
133
+ self.installRBACDir = "/opt/app-root/src/rbac/install"
129
134
  self.tektonDefsWithoutDigestPath: str = path.join(self.templatesDir, "ibm-mas-tekton.yaml")
130
135
  self.tektonDefsWithDigestPath: str = path.join(self.templatesDir, "ibm-mas-tekton-with-digest.yaml")
131
136
 
@@ -155,6 +160,7 @@ class BaseApp(PrintMixin, PromptMixin):
155
160
  "visualinspection": ["9.2.x-feature", "9.1.x"],
156
161
  "iot": ["9.2.x-feature", "9.1.x"],
157
162
  "monitor": ["9.2.x-feature", "9.1.x"],
163
+ "predict": ["9.2.x-feature", "9.1.x"],
158
164
  "facilities": ["9.2.x-feature", "9.1.x"],
159
165
  },
160
166
  "9.1.x": {
@@ -12,7 +12,7 @@ from os import getenv
12
12
  from prompt_toolkit import prompt, print_formatted_text, HTML, PromptSession
13
13
  from prompt_toolkit.completion import WordCompleter
14
14
  from prompt_toolkit.validation import Validator
15
- from typing import List
15
+ from typing import List, Union, Optional
16
16
 
17
17
  from .validators import YesNoValidator, IntValidator, FileExistsValidator, DirectoryExistsValidator
18
18
 
@@ -47,7 +47,7 @@ class PrintMixin():
47
47
  content[len(content) - 1] = f"{content[len(content) - 1]}</{DESCRIPTIONCOLOR}>"
48
48
  print_formatted_text(HTML("\n".join(content).replace(' & ', ' &amp; ')))
49
49
 
50
- def printHighlight(self, message: str | list[str]) -> None:
50
+ def printHighlight(self, message: Union[str, List[str]]) -> None:
51
51
  if isinstance(message, list):
52
52
  message = "\n".join(message)
53
53
 
@@ -75,6 +75,37 @@ class PrintMixin():
75
75
  logger.debug(f"Parameter Summary: {param} = {self.getParam(param)}") # type: ignore
76
76
  self.printSummary(message, self.getParam(param)) # type: ignore
77
77
 
78
+ def printTable(self, headers: List[str], rows: List[List[str]]) -> None:
79
+ """
80
+ Print a formatted table with headers and rows.
81
+
82
+ Args:
83
+ headers: List of column headers
84
+ rows: List of rows, where each row is a list of column values
85
+ """
86
+ if not rows:
87
+ return
88
+
89
+ # Calculate column widths
90
+ col_widths = [len(h) for h in headers]
91
+ for row in rows:
92
+ for i, cell in enumerate(row):
93
+ if i < len(col_widths):
94
+ col_widths[i] = max(col_widths[i], len(str(cell)))
95
+
96
+ # Print header
97
+ header_line = " " + " | ".join(h.ljust(col_widths[i]) for i, h in enumerate(headers))
98
+ print_formatted_text(HTML(f"<{SUMMARYCOLOR}>{header_line}</{SUMMARYCOLOR}>"))
99
+
100
+ # Print separator
101
+ separator = " " + "-+-".join("-" * w for w in col_widths)
102
+ print_formatted_text(HTML(f"<{SUMMARYCOLOR}>{separator}</{SUMMARYCOLOR}>"))
103
+
104
+ # Print rows
105
+ for row in rows:
106
+ row_line = " " + " | ".join(str(cell).ljust(col_widths[i]) for i, cell in enumerate(row))
107
+ print_formatted_text(HTML(f"<{SUMMARYCOLOR}>{row_line.replace(' & ', ' & ')}</{SUMMARYCOLOR}>"))
108
+
78
109
 
79
110
  def masPromptYesOrNo(message: str) -> HTML:
80
111
  return HTML(f"<{PROMPTCOLOR}>{message.replace(' & ', ' &amp; ')}? [y/n]</{PROMPTCOLOR}> ")
@@ -85,7 +116,7 @@ def masPromptValue(message: str) -> HTML:
85
116
 
86
117
 
87
118
  class PromptMixin():
88
- def yesOrNo(self, message: str, param: str | None = None) -> bool:
119
+ def yesOrNo(self, message: str, param: Optional[str] = None) -> bool:
89
120
  response = prompt(message=masPromptYesOrNo(message), validator=YesNoValidator(), validate_while_typing=False)
90
121
  responseAsBool = response.lower() in ["y", "yes"]
91
122
 
@@ -93,7 +124,7 @@ class PromptMixin():
93
124
  self.params[param] = "true" if responseAsBool else "false" # type: ignore
94
125
  return responseAsBool
95
126
 
96
- def promptForString(self, message: str, param: str | None = None, default: str = "", isPassword: bool = False, validator: Validator | None = None, completer: WordCompleter | None = None) -> str:
127
+ def promptForString(self, message: str, param: Optional[str] = None, default: str = "", isPassword: bool = False, validator: Optional[Validator] = None, completer: Optional[WordCompleter] = None) -> str:
97
128
  if param is not None and default == "":
98
129
  default = getenv(param.upper(), default="")
99
130
 
@@ -107,7 +138,7 @@ class PromptMixin():
107
138
  self.params[param] = response # type: ignore
108
139
  return response
109
140
 
110
- def promptForInt(self, message: str, param: str | None = None, default: int | None = None, min: int | None = None, max: int | None = None) -> int:
141
+ def promptForInt(self, message: str, param: Optional[str] = None, default: Optional[int] = None, min: Optional[int] = None, max: Optional[int] = None) -> int:
111
142
  if param is not None and default is None:
112
143
  default = getenv(param.upper(), default=None) # type: ignore
113
144
 
@@ -119,7 +150,7 @@ class PromptMixin():
119
150
  self.params[param] = str(response) # type: ignore
120
151
  return response
121
152
 
122
- def promptForListSelect(self, message: str, options: List[str], param: str | None = None, default: int | None = None) -> str:
153
+ def promptForListSelect(self, message: str, options: List[str], param: Optional[str] = None, default: Optional[int] = None) -> str:
123
154
  selection = self.promptForInt(message=message, default=default, min=1, max=len(options))
124
155
  # List indices are 0 origin, so we need to subtract 1 from the selection made to arrive at the correct value
125
156
  result = options[selection - 1]
@@ -140,5 +171,3 @@ class PromptMixin():
140
171
  return prompt(message=masPromptValue(message), validator=DirectoryExistsValidator(), validate_while_typing=False, default=default)
141
172
  else:
142
173
  return prompt(message=masPromptValue(message), default=default)
143
-
144
- # Made with Bob
@@ -64,6 +64,7 @@ from mas.devops.sls import findSLSByNamespace
64
64
  from mas.devops.data import getCatalog, getCatalogEditorial, NoSuchCatalogError
65
65
  from mas.devops.tekton import (
66
66
  installOpenShiftPipelines,
67
+ enablePipelinesConsolePlugin,
67
68
  updateTektonDefinitions,
68
69
  preparePipelinesNamespace,
69
70
  prepareInstallSecrets,
@@ -591,6 +592,7 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
591
592
  self.configCATrust()
592
593
  self.configDNSAndCerts()
593
594
  self.configRoutingMode()
595
+ self.configServiceMesh()
594
596
  self.configSSOProperties()
595
597
  self.configSpecialCharacters()
596
598
  self.configReportAdoptionMetricsFlag()
@@ -836,6 +838,17 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
836
838
  logger.warning(f"User may not have permissions to configure IngressController '{controllerName}': {e}")
837
839
  return False
838
840
 
841
+ @logMethodCall
842
+ def configServiceMesh(self) -> None:
843
+ if self.showAdvancedOptions:
844
+ self.printH1("Configure Service Mesh")
845
+ self.printDescription([
846
+ "By default, Maximo Application Suite does not use Service Mesh for routing."
847
+ ])
848
+ self.yesOrNo("Use Service Mesh", "mas_use_service_mesh")
849
+ else:
850
+ self.setParam("mas_use_service_mesh", "false")
851
+
839
852
  @logMethodCall
840
853
  def configAnnotations(self):
841
854
  if self.operationalMode == 2:
@@ -2111,6 +2124,14 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
2111
2124
  h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator installation failed")
2112
2125
  self.fatalError("Installation failed")
2113
2126
 
2127
+ # Enable console plugin for OCP 4.21+
2128
+ with Halo(text='Enabling Pipelines console plugin', spinner=self.spinner) as h:
2129
+ if enablePipelinesConsolePlugin(self.dynamicClient):
2130
+ h.stop_and_persist(symbol=self.successIcon, text="Pipelines console plugin enabled")
2131
+ else:
2132
+ h.stop_and_persist(symbol=self.warningIcon, text="Failed to enable Pipelines console plugin (non-fatal)")
2133
+ # Note: This is non-fatal as the plugin can be enabled manually
2134
+
2114
2135
  if self.getParam("mas_routing_mode") == "path" and self.getParam("mas_configure_ingress") == "true":
2115
2136
  with Halo(text='Configuring cluster for path-based routing', spinner=self.spinner) as h:
2116
2137
  ingressControllerName = self.getParam("mas_ingress_controller_name") if self.getParam("mas_ingress_controller_name") else "default"
@@ -107,6 +107,9 @@ class installArgBuilderMixin():
107
107
  if self.getParam('mas_configure_ingress').lower() == "true":
108
108
  command += f" --configure-ingress{newline}"
109
109
 
110
+ if self.getParam('mas_use_service_mesh') != "":
111
+ command += f" --servicemesh \"{self.getParam('mas_use_service_mesh')}\"{newline}"
112
+
110
113
  if self.getParam('mas_domain') != "":
111
114
  command += f" --domain \"{self.getParam('mas_domain')}\"{newline}"
112
115
 
@@ -184,6 +184,13 @@ masAdvancedArgGroup.add_argument(
184
184
  required=False,
185
185
  help="Name of the IngressController to use for path-based routing (default: 'default')"
186
186
  )
187
+ masAdvancedArgGroup.add_argument(
188
+ "--servicemesh",
189
+ dest="mas_use_service_mesh",
190
+ required=False,
191
+ help="Configure MAS to use Service Mesh networking (default: false)",
192
+ choices=["true", "false"]
193
+ )
187
194
  masAdvancedArgGroup.add_argument(
188
195
  "--manual-certificates",
189
196
  required=False,
@@ -734,6 +741,7 @@ facilitiesArgGroup.add_argument(
734
741
  dest="mas_ws_facilities_app_om_upgrade_mode",
735
742
  required=False,
736
743
  help="Sets the Application Object Migration Mode",
744
+ default="manual",
737
745
  choices=FACILITIES_APPOMUPGRADEMODE,
738
746
  metavar="{manual,load-only,automatic}"
739
747
  )
@@ -742,6 +750,7 @@ facilitiesArgGroup.add_argument(
742
750
  dest="mas_ws_facilities_size",
743
751
  required=False,
744
752
  help="Size of Facilities deployment",
753
+ default="small",
745
754
  choices=FACILITIES_SIZES,
746
755
  metavar="{small,medium,large}"
747
756
  )
@@ -750,6 +759,7 @@ facilitiesArgGroup.add_argument(
750
759
  dest="mas_ws_facilities_pull_policy",
751
760
  required=False,
752
761
  help="Image pull policy for Facilities",
762
+ default="IfNotPresent",
753
763
  choices=IMAGE_PULL_POLICIES,
754
764
  metavar="{IfNotPresent,Always}"
755
765
  )
@@ -797,13 +807,15 @@ facilitiesArgGroup.add_argument(
797
807
  "--facilities-log-storage-mode",
798
808
  dest="mas_ws_facilities_storage_log_mode",
799
809
  required=False,
800
- help="Storage mode for Facilities logs"
810
+ help="Storage mode for Facilities logs",
811
+ default="ReadWriteMany",
801
812
  )
802
813
  facilitiesArgGroup.add_argument(
803
814
  "--facilities-log-storage-size",
804
815
  dest="mas_ws_facilities_storage_log_size",
805
816
  required=False,
806
- help="Storage size for Facilities logs"
817
+ help="Storage size for Facilities logs",
818
+ default=30
807
819
  )
808
820
  facilitiesArgGroup.add_argument(
809
821
  "--facilities-userfiles-storage-class",
@@ -815,13 +827,15 @@ facilitiesArgGroup.add_argument(
815
827
  "--facilities-userfiles-storage-mode",
816
828
  dest="mas_ws_facilities_storage_userfiles_mode",
817
829
  required=False,
818
- help="Storage mode for Facilities user files"
830
+ help="Storage mode for Facilities user files",
831
+ default="ReadWriteMany",
819
832
  )
820
833
  facilitiesArgGroup.add_argument(
821
834
  "--facilities-userfiles-storage-size",
822
835
  dest="mas_ws_facilities_storage_userfiles_size",
823
836
  required=False,
824
- help="Storage size for Facilities user files"
837
+ help="Storage size for Facilities user files",
838
+ default=50
825
839
  )
826
840
 
827
841
  # Open Data Hub
@@ -9,21 +9,21 @@
9
9
  # *****************************************************************************
10
10
  supportedCatalogs = {
11
11
  "amd64": [
12
+ "v9-260430-amd64",
12
13
  "v9-260326-amd64",
13
14
  "v9-260226-amd64",
14
15
  "v9-260216-amd64",
15
- "v9-260129-amd64",
16
16
  ],
17
17
  "s390x": [
18
+ "v9-260430-s390x",
18
19
  "v9-260326-s390x",
19
20
  "v9-260226-s390x",
20
21
  "v9-260216-s390x",
21
- "v9-260129-s390x",
22
22
  ],
23
23
  "ppc64le": [
24
+ "v9-260430-ppc64le",
24
25
  "v9-260326-ppc64le",
25
26
  "v9-260226-ppc64le",
26
27
  "v9-260216-ppc64le",
27
- "v9-260129-ppc64le",
28
28
  ],
29
29
  }
@@ -38,6 +38,7 @@ optionalParams = [
38
38
  "mas_superuser_password",
39
39
  "mas_trust_default_cas",
40
40
  "mas_routing_mode",
41
+ "mas_use_service_mesh",
41
42
  "mas_ingress_controller_name",
42
43
  "mas_app_settings_server_bundles_size",
43
44
  "mas_app_settings_default_jms",
@@ -15,6 +15,7 @@ from mas.devops.aiservice import listAiServiceTenantInstances, listAiServiceInst
15
15
  from openshift.dynamic.exceptions import ResourceNotFoundError
16
16
  from ...validators import AiserviceTeanantIDValidator
17
17
  from prompt_toolkit import print_formatted_text, HTML
18
+ from mas.devops.utils import isVersionEqualOrAfter
18
19
 
19
20
  import logging
20
21
  logger = logging.getLogger(__name__)
@@ -176,8 +177,12 @@ class ManageSettingsMixin():
176
177
  self.params["mas_appws_components"] += ",aip=latest"
177
178
  if self.yesOrNo(" - Vegetation Management"):
178
179
  self.params["mas_appws_components"] += ",vegm=latest"
180
+ # Collaborate is only available in Manage 9.2 or higher
181
+ manageChannel = self.getParam("mas_app_channel_manage")
182
+ if manageChannel and isVersionEqualOrAfter('9.2.0', manageChannel):
183
+ if self.yesOrNo(" - Collaborate"):
184
+ self.params["mas_appws_components"] += ",collaborate=latest"
179
185
  logger.debug(f"Generated mas_appws_components = {self.params['mas_appws_components']}")
180
-
181
186
  if ",icd=" in self.params["mas_appws_components"]:
182
187
  self.printH2("Maximo IT License Terms")
183
188
  self.printDescription([
@@ -81,6 +81,9 @@ class InstallSummarizerMixin():
81
81
  self.printParamSummary("IngressController Name", "mas_ingress_controller_name")
82
82
  self.printParamSummary("Configure IngressController", "mas_configure_ingress")
83
83
 
84
+ print()
85
+ self.printParamSummary("Use Service Mesh", "mas_use_service_mesh")
86
+
84
87
  print()
85
88
  self.printParamSummary("Configure Suite to run in IPV6", "enable_ipv6")
86
89
 
@@ -35,6 +35,9 @@ from .config import PACKAGE_CONFIGS
35
35
 
36
36
  logger = logging.getLogger(__name__)
37
37
 
38
+ # Constants
39
+ EMPTY_PROGRESS_BAR = " |" + " " * 20 + "|"
40
+
38
41
 
39
42
  def logMethodCall(func):
40
43
  def wrapper(self, *args, **kwargs):
@@ -485,9 +488,8 @@ def mirrorPackage(package: str, version: str, arch: str, mode: str,
485
488
  if not flag:
486
489
  logger.info(f"Skipping {package} version {version} for {arch} architecture")
487
490
  # Add empty progress bar to align with other status messages
488
- emptyBar = " |" + " " * 20 + "|"
489
491
  displayName = f"{package} v{version} ({arch})"
490
- print(f"{displayName}".ljust(50) + f" ⏭️ {emptyBar} Mirroring disabled by user")
492
+ print(f"{displayName.ljust(50)} ⏭️ {EMPTY_PROGRESS_BAR} Mirroring disabled by user")
491
493
  return MirrorResult(images=0, mirrored=0, name=displayName)
492
494
 
493
495
  logger.info(f"Mirroring {package} version {version} for {arch} architecture")
@@ -804,10 +806,24 @@ class MirrorApp(BaseApp):
804
806
  "mas_visualinspection_version"
805
807
  ]
806
808
  if catalogKey in perReleaseVersions:
809
+ # Check if the catalogKey exists in the catalog first
810
+ if catalogKey not in catalog or release not in catalog[catalogKey] or (release == "8.10.x" and packageName == "ibm-mas-manage-icd"):
811
+ logger.info(f"No content available for {packageName} in MAS release {release}")
812
+ displayName = f"{packageName} ({arch})"
813
+ print(f"{displayName.ljust(50)} ⏭️ {EMPTY_PROGRESS_BAR} No content to mirror for MAS release {release}")
814
+ continue
815
+
807
816
  version = catalog[catalogKey][release]
808
817
  else:
809
818
  version = catalog[catalogKey]
810
819
 
820
+ # Check if version is empty or None (content exists in catalog but is empty)
821
+ if not version:
822
+ logger.info(f"No content available for {packageName} in MAS release {release}")
823
+ displayName = f"{packageName} ({arch})"
824
+ print(f"{displayName.ljust(50)} ⏭️ {EMPTY_PROGRESS_BAR} No content to mirror for MAS release {release}")
825
+ continue
826
+
811
827
  if self._isUnsupportedPackage(version, packageName):
812
828
  continue
813
829
 
@@ -75,7 +75,7 @@ mainGroup.add_argument(
75
75
  "--release",
76
76
  required=True,
77
77
  help="MAS release version",
78
- choices=["8.10.x", "8.11.x", "9.0.x", "9.1.x"]
78
+ choices=["8.10.x", "8.11.x", "9.0.x", "9.1.x", "9.2.x-feature"]
79
79
  )
80
80
  mainGroup.add_argument(
81
81
  "--mode",
@@ -26,6 +26,7 @@ PACKAGE_CONFIGS = [
26
26
 
27
27
  ("Maximo Application Suite", "core", "ibm-mas", "mas_core_version"),
28
28
  ("Maximo Application Suite", "assist", "ibm-mas-assist", "mas_assist_version"),
29
+ ("Maximo Application Suite", "assist", "ibm-couchdb", "couchdb_version"),
29
30
  ("Maximo Application Suite", "iot", "ibm-mas-iot", "mas_iot_version"),
30
31
  ("Maximo Application Suite", "facilities", "ibm-mas-facilities", "mas_facilities_version"),
31
32
  ("Maximo Application Suite", "manage", "ibm-mas-manage", "mas_manage_version"),
@@ -0,0 +1,9 @@
1
+ # *****************************************************************************
2
+ # Copyright (c) 2026 IBM Corporation and other Contributors.
3
+ #
4
+ # All rights reserved. This program and the accompanying materials
5
+ # are made available under the terms of the Eclipse Public License v1.0
6
+ # which accompanies this distribution, and is available at
7
+ # http://www.eclipse.org/legal/epl-v10.html
8
+ #
9
+ # *****************************************************************************
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env python
2
+ # *****************************************************************************
3
+ # Copyright (c) 2026 IBM Corporation and other Contributors.
4
+ #
5
+ # All rights reserved. This program and the accompanying materials
6
+ # are made available under the terms of the Eclipse Public License v1.0
7
+ # which accompanies this distribution, and is available at
8
+ # http://www.eclipse.org/legal/epl-v10.html
9
+ #
10
+ # *****************************************************************************
11
+
12
+ import logging
13
+ from halo import Halo
14
+
15
+ from ..cli import BaseApp
16
+ from .argParser import setupRBACArgParser
17
+ from mas.devops.tekton import prepareInstallRBAC
18
+
19
+ logger = logging.getLogger(__name__)
20
+
21
+
22
+ class SetupRBACApp(BaseApp):
23
+ def setupRBAC(self, argv):
24
+ """
25
+ Create the minimal install RBAC resources for MAS installation.
26
+ This is intended to be used in cases where the user does not have permissions to create RBAC resources in the cluster.
27
+ The cluster admin create the necessary RBAC resources for them before they run the install command.
28
+ """
29
+ self.args = setupRBACArgParser.parse_args(args=argv)
30
+ self.noConfirm = self.args.no_confirm
31
+
32
+ self.printH1("Set Target OpenShift Cluster")
33
+ self.connect()
34
+
35
+ instanceId = self.args.mas_instance_id
36
+ installUserSA = f"mas-{instanceId}-install-user"
37
+ installPipelineSA = f"mas-{instanceId}-install-pipeline"
38
+ pipelineNamespace = f"mas-{instanceId}-pipelines"
39
+
40
+ self.printH1("Create RBAC resources for MAS installation")
41
+ self.printDescription(["This will apply the minimal install RBAC bundle for the target MAS instance."
42
+ "",
43
+ "The bundle creates the fine-grained service accounts used to run 'mas install' and the install pipeline."])
44
+ self.printSummary("Instance ID", instanceId)
45
+ self.printSummary("Install Pipeline Namespace", pipelineNamespace)
46
+ self.printSummary("Install User Service Account", installUserSA)
47
+ self.printSummary("Install Pipeline Service Account", installPipelineSA)
48
+
49
+ with Halo(text=f"Applying RBAC resources for {instanceId}...", spinner=self.spinner) as h:
50
+ prepareInstallRBAC(
51
+ dynClient=self.dynamicClient,
52
+ namespace=pipelineNamespace,
53
+ instanceId=instanceId,
54
+ installRBACDir=self.installRBACDir
55
+ )
56
+ h.stop_and_persist(symbol=self.successIcon, text=f"Install RBAC is ready for {instanceId}")
57
+
58
+ self.printH1("Next Steps")
59
+ self.printDescription(["The RBAC resources for the install pipeline have been created. "
60
+ "Use the service accounts created by this command to run MAS install without relying on cluster-admin permissions."])
61
+ self.printHighlight([
62
+ f"1. Log in using the '{installUserSA}' service account token",
63
+ f"2. Run 'mas install' with the '--service-account {installPipelineSA}' flag to use the '{installPipelineSA}' service account for the install pipeline"
64
+ ])
@@ -0,0 +1,57 @@
1
+ # *****************************************************************************
2
+ # Copyright (c) 2026 IBM Corporation and other Contributors.
3
+ #
4
+ # All rights reserved. This program and the accompanying materials
5
+ # are made available under the terms of the Eclipse Public License v1.0
6
+ # which accompanies this distribution, and is available at
7
+ # http://www.eclipse.org/legal/epl-v10.html
8
+ #
9
+ # *****************************************************************************
10
+
11
+ import argparse
12
+
13
+ from .. import __version__ as packageVersion
14
+ from ..cli import getHelpFormatter
15
+
16
+ setupRBACArgParser = argparse.ArgumentParser(
17
+ prog="mas setup-rbac",
18
+ description="\n".join([
19
+ f"IBM Maximo Application Suite Admin CLI v{packageVersion}",
20
+ "Create the minimal install RBAC resources for MAS installation.",
21
+ ]),
22
+ epilog="Refer to the online documentation for more details: https://ibm-mas.github.io/cli/examples/minimal-rbac/",
23
+ formatter_class=getHelpFormatter(),
24
+ add_help=False
25
+ )
26
+
27
+ targetArgGroup = setupRBACArgParser.add_argument_group(
28
+ "Target Cluster Arguments",
29
+ "Specify the target cluster for which to set up the RBAC resources."
30
+ )
31
+
32
+ targetArgGroup.add_argument(
33
+ "-i", "--mas-instance-id",
34
+ dest="mas_instance_id",
35
+ required=True,
36
+ help="The MAS Instance ID to prepare RBAC for"
37
+ )
38
+
39
+ otherArgGroup = setupRBACArgParser.add_argument_group(
40
+ "More",
41
+ "Additional options for setup-rbac."
42
+ )
43
+
44
+ otherArgGroup.add_argument(
45
+ "--no-confirm",
46
+ required=False,
47
+ action="store_true",
48
+ default=False,
49
+ help="Proceed without prompting for cluster confirmation"
50
+ )
51
+
52
+ setupRBACArgParser.add_argument(
53
+ "-h", "--help",
54
+ action="help",
55
+ default=False,
56
+ help="Show this help message and exit"
57
+ )