mas-cli 5.1.4__py3-none-any.whl

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.

Potentially problematic release.


This version of mas-cli might be problematic. Click here for more details.

Files changed (114) hide show
  1. mas/cli/__init__.py +11 -0
  2. mas/cli/aiservice/install/__init__.py +11 -0
  3. mas/cli/aiservice/install/app.py +894 -0
  4. mas/cli/aiservice/install/argBuilder.py +180 -0
  5. mas/cli/aiservice/install/argParser.py +507 -0
  6. mas/cli/aiservice/install/params.py +100 -0
  7. mas/cli/aiservice/install/summarizer.py +134 -0
  8. mas/cli/cli.py +432 -0
  9. mas/cli/displayMixins.py +132 -0
  10. mas/cli/gencfg.py +113 -0
  11. mas/cli/install/__init__.py +11 -0
  12. mas/cli/install/app.py +1316 -0
  13. mas/cli/install/argBuilder.py +465 -0
  14. mas/cli/install/argParser.py +1176 -0
  15. mas/cli/install/catalogs.py +27 -0
  16. mas/cli/install/params.py +172 -0
  17. mas/cli/install/settings/__init__.py +23 -0
  18. mas/cli/install/settings/additionalConfigs.py +227 -0
  19. mas/cli/install/settings/db2Settings.py +252 -0
  20. mas/cli/install/settings/kafkaSettings.py +103 -0
  21. mas/cli/install/settings/manageSettings.py +273 -0
  22. mas/cli/install/settings/mongodbSettings.py +46 -0
  23. mas/cli/install/settings/turbonomicSettings.py +29 -0
  24. mas/cli/install/summarizer.py +398 -0
  25. mas/cli/templates/facilities-configs.yml.j2 +25 -0
  26. mas/cli/templates/ibm-mas-tekton.yaml +49772 -0
  27. mas/cli/templates/jdbccfg.yml.j2 +52 -0
  28. mas/cli/templates/pod-templates/best-effort/ibm-data-dictionary-assetdatadictionary.yml +26 -0
  29. mas/cli/templates/pod-templates/best-effort/ibm-mas-bascfg.yml +56 -0
  30. mas/cli/templates/pod-templates/best-effort/ibm-mas-coreidp.yml +21 -0
  31. mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-actions.yml +28 -0
  32. mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-auth.yml +32 -0
  33. mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-datapower.yml +12 -0
  34. mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-devops.yml +14 -0
  35. mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-dm.yml +22 -0
  36. mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-dsc.yml +40 -0
  37. mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-edgeconfig.yml +10 -0
  38. mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-fpl.yml +24 -0
  39. mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-guardian.yml +20 -0
  40. mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-iot.yml +10 -0
  41. mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-mbgx.yml +18 -0
  42. mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-mfgx.yml +14 -0
  43. mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-monitor.yml +18 -0
  44. mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-orgmgmt.yml +48 -0
  45. mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-provision.yml +28 -0
  46. mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-registry.yml +26 -0
  47. mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-state.yml +40 -0
  48. mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-webui.yml +22 -0
  49. mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-healthextaccelerator.yml +13 -0
  50. mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-healthextworkspace.yml +10 -0
  51. mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-imagestitching.yml +10 -0
  52. mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-manageaccelerators.yml +10 -0
  53. mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-manageapp.yml +46 -0
  54. mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-manageworkspace.yml +48 -0
  55. mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-slackproxy.yml +10 -0
  56. mas/cli/templates/pod-templates/best-effort/ibm-mas-pushnotificationcfg.yml +13 -0
  57. mas/cli/templates/pod-templates/best-effort/ibm-mas-scimcfg.yml +14 -0
  58. mas/cli/templates/pod-templates/best-effort/ibm-mas-slscfg.yml +10 -0
  59. mas/cli/templates/pod-templates/best-effort/ibm-mas-smtpcfg.yml +10 -0
  60. mas/cli/templates/pod-templates/best-effort/ibm-mas-suite.yml +136 -0
  61. mas/cli/templates/pod-templates/best-effort/ibm-mas-visualinspection.yml +34 -0
  62. mas/cli/templates/pod-templates/best-effort/ibm-sls-licenseservice.yml +10 -0
  63. mas/cli/templates/pod-templates/guaranteed/ibm-data-dictionary-assetdatadictionary.yml +56 -0
  64. mas/cli/templates/pod-templates/guaranteed/ibm-mas-bascfg.yml +140 -0
  65. mas/cli/templates/pod-templates/guaranteed/ibm-mas-coreidp.yml +45 -0
  66. mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-actions.yml +70 -0
  67. mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-auth.yml +80 -0
  68. mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-datapower.yml +24 -0
  69. mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-devops.yml +26 -0
  70. mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-dm.yml +52 -0
  71. mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-dsc.yml +106 -0
  72. mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-edgeconfig.yml +16 -0
  73. mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-fpl.yml +62 -0
  74. mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-guardian.yml +44 -0
  75. mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-iot.yml +16 -0
  76. mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-mbgx.yml +42 -0
  77. mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-mfgx.yml +32 -0
  78. mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-monitor.yml +42 -0
  79. mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-orgmgmt.yml +126 -0
  80. mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-provision.yml +70 -0
  81. mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-registry.yml +62 -0
  82. mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-state.yml +106 -0
  83. mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-webui.yml +52 -0
  84. mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-healthextaccelerator.yml +28 -0
  85. mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-healthextworkspace.yml +18 -0
  86. mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-imagestitching.yml +16 -0
  87. mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-manageaccelerators.yml +16 -0
  88. mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-manageapp.yml +106 -0
  89. mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-manageworkspace.yml +126 -0
  90. mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-slackproxy.yml +16 -0
  91. mas/cli/templates/pod-templates/guaranteed/ibm-mas-pushnotificationcfg.yml +25 -0
  92. mas/cli/templates/pod-templates/guaranteed/ibm-mas-scimcfg.yml +26 -0
  93. mas/cli/templates/pod-templates/guaranteed/ibm-mas-slscfg.yml +16 -0
  94. mas/cli/templates/pod-templates/guaranteed/ibm-mas-smtpcfg.yml +16 -0
  95. mas/cli/templates/pod-templates/guaranteed/ibm-mas-suite.yml +340 -0
  96. mas/cli/templates/pod-templates/guaranteed/ibm-mas-visualinspection.yml +76 -0
  97. mas/cli/templates/pod-templates/guaranteed/ibm-sls-licenseservice.yml +16 -0
  98. mas/cli/templates/suite_mongocfg.yml.j2 +55 -0
  99. mas/cli/uninstall/__init__.py +11 -0
  100. mas/cli/uninstall/app.py +197 -0
  101. mas/cli/uninstall/argParser.py +115 -0
  102. mas/cli/update/__init__.py +11 -0
  103. mas/cli/update/app.py +673 -0
  104. mas/cli/update/argParser.py +156 -0
  105. mas/cli/upgrade/__init__.py +11 -0
  106. mas/cli/upgrade/app.py +164 -0
  107. mas/cli/upgrade/argParser.py +68 -0
  108. mas/cli/upgrade/settings/__init__.py +19 -0
  109. mas/cli/validators.py +151 -0
  110. mas_cli-5.1.4.data/scripts/mas-cli +87 -0
  111. mas_cli-5.1.4.dist-info/METADATA +73 -0
  112. mas_cli-5.1.4.dist-info/RECORD +114 -0
  113. mas_cli-5.1.4.dist-info/WHEEL +5 -0
  114. mas_cli-5.1.4.dist-info/top_level.txt +1 -0
@@ -0,0 +1,252 @@
1
+ # *****************************************************************************
2
+ # Copyright (c) 2024 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
+ from os import path
12
+ from prompt_toolkit import print_formatted_text
13
+
14
+
15
+ class Db2SettingsMixin():
16
+ # In silentMode, no prompts will show up for "happy path" DB2 configuration scenarios. Prompts will still show up when an input is absolutely required
17
+ # Settings under showAdvancedOptions are always prompted
18
+ def configDb2(self, silentMode=False) -> None:
19
+ if not silentMode:
20
+ self.printH1("Configure Databases")
21
+ # The channel used for Db2 used has not changed since the January 2024 catalog update
22
+ self.params["db2_channel"] = "v110509.0"
23
+
24
+ # If neither Iot, Manage or Facilities is being installed, we have nothing to do
25
+ if not self.installIoT and not self.installManage and not self.installFacilities:
26
+ print_formatted_text("No applications have been selected that require a Db2 installation")
27
+ self.setParam("db2_action_system", "none")
28
+ self.setParam("db2_action_manage", "none")
29
+ self.setParam("db2_action_facilities", "none")
30
+ return
31
+
32
+ # For now we are limiting users to bring your own database for Manage on s390x & ppc64le
33
+ # Eventually we will be able to remove this clause and allow the standard logic to work for s390x, ppc64le and amd64
34
+ if (self.architecture == "s390x" or self.architecture == "ppc64le") and self.installManage:
35
+ # silentMode does not apply for s390x/ppc64le because it requires interaction when selecting local config directory
36
+ self.printDescription([
37
+ "Installation of a Db2 instance using the IBM Db2 Universal Operator is not currently supported on s390x /ppc64le, please provide configuration details for the database you wish to use.",
38
+ ])
39
+ instanceId = self.getParam('mas_instance_id')
40
+ workspaceId = self.getParam("mas_workspace_id")
41
+
42
+ self.setParam("mas_appws_bindings_jdbc_manage", "workspace-application")
43
+ self.setParam("db2_action_manage", "byo")
44
+ self.selectLocalConfigDir()
45
+
46
+ # Check if a configuration already exists before creating a new one
47
+ jdbcCfgFile = path.join(self.localConfigDir, f"jdbc-{instanceId}-manage.yaml")
48
+ print_formatted_text(f"Searching for {self.manageAppName} database configuration file in {jdbcCfgFile} ...")
49
+ if path.exists(jdbcCfgFile):
50
+ if self.yesOrNo(f"{self.manageAppName} database configuration file 'jdbc-{instanceId}-manage.yaml' already exists. Do you want to generate a new one"):
51
+ self.generateJDBCCfg(instanceId=instanceId, scope="workspace-application", workspaceId=workspaceId, appId="manage", destination=jdbcCfgFile)
52
+ else:
53
+ print_formatted_text(f"Expected file ({jdbcCfgFile}) was not found, generating a valid {self.manageAppName} database configuration file now ...")
54
+ self.generateJDBCCfg(instanceId=instanceId, scope="workspace-application", workspaceId=workspaceId, appId="manage", destination=jdbcCfgFile)
55
+ return
56
+
57
+ # Proceed as normal
58
+ # We know we are installing either IoT, Manage or Facilities, and on amd64 target architecture
59
+ if not silentMode:
60
+ self.printDescription([
61
+ f"The installer can setup one or more IBM Db2 instances in your OpenShift cluster for the use of applications that require a JDBC datasource (IoT, {self.manageAppName}, Monitor, & Predict, Real Estate and Facilities) or you may choose to configure MAS to use an existing database"
62
+ ])
63
+
64
+ self.setDB2DefaultSettings()
65
+
66
+ instanceId = self.getParam('mas_instance_id')
67
+ # Do we need to set up an IoT database?
68
+ if self.installIoT:
69
+ if not silentMode:
70
+ self.printH2("Database Configuration for Maximo IoT")
71
+ self.printDescription([
72
+ "Maximo IoT requires a shared system-scope Db2 instance because others application in the suite require access to the same database source",
73
+ " - Only IBM Db2 is supported for this database"
74
+ ])
75
+ createSystemDb2UsingUniversalOperator = True
76
+ if not silentMode:
77
+ createSystemDb2UsingUniversalOperator = self.yesOrNo("Create system Db2 instance using the IBM Db2 Universal Operator")
78
+ if createSystemDb2UsingUniversalOperator:
79
+ self.setParam("db2_action_system", "install")
80
+ else:
81
+ self.setParam("db2_action_system", "byo")
82
+
83
+ self.selectLocalConfigDir()
84
+
85
+ # Check if a configuration already exists before creating a new one
86
+ jdbcCfgFile = path.join(self.localConfigDir, f"jdbc-{instanceId}-system.yaml")
87
+ print_formatted_text(f"Searching for system database configuration file in {jdbcCfgFile} ...")
88
+ if path.exists(jdbcCfgFile):
89
+ if self.yesOrNo(f"System database configuration file 'jdbc-{instanceId}-system.yaml' already exists. Do you want to generate a new one"):
90
+ self.generateJDBCCfg(instanceId=instanceId, scope="system", destination=jdbcCfgFile)
91
+ else:
92
+ print_formatted_text(f"Expected file ({jdbcCfgFile}) was not found, generating a valid system database configuration file now ...")
93
+ self.generateJDBCCfg(instanceId=instanceId, scope="system", destination=jdbcCfgFile)
94
+ else:
95
+ self.setParam("db2_action_system", "none")
96
+
97
+ if self.installManage:
98
+ if not silentMode:
99
+ self.printH2(f"Database Configuration for Maximo {self.manageAppName}")
100
+ self.printDescription([
101
+ f"Maximo {self.manageAppName} can be configured to share the system Db2 instance or use it's own dedicated database:",
102
+ " - Use of a shared instance has a significant footprint reduction but is only recommended for development/test/demo installs",
103
+ " - In most production systems you will want to use a dedicated database",
104
+ " - IBM Db2, Oracle Database, & Microsoft SQL Server are all supported database options"
105
+ ])
106
+ # Determine whether to use the system or a dedicated database
107
+ reuseSystemDb2 = False
108
+ if self.installIoT:
109
+ if not silentMode:
110
+ reuseSystemDb2 = self.yesOrNo(f"Re-use System Db2 instance for {self.manageAppName} application")
111
+ if reuseSystemDb2:
112
+ # We are going to bind Manage to the system database, which has already been set up in the previous step
113
+ self.setParam("mas_appws_bindings_jdbc_manage", "system")
114
+ self.setParam("db2_action_manage", "none")
115
+ else:
116
+ self.setParam("mas_appws_bindings_jdbc_manage", "workspace-application")
117
+ createSystemDb2UsingUniversalOperator = True
118
+ if not silentMode:
119
+ createSystemDb2UsingUniversalOperator = self.yesOrNo(f"Create {self.manageAppName} dedicated Db2 instance using the IBM Db2 Universal Operator")
120
+ if createSystemDb2UsingUniversalOperator:
121
+ self.setParam("db2_action_manage", "install")
122
+ if not silentMode:
123
+ self.printDescription([
124
+ f"Available Db2 instance types for {self.manageAppName}:",
125
+ " 1. DB2 Warehouse (Default option)",
126
+ " 2. DB2 Online Transactional Processing (OLTP)"
127
+ ])
128
+ self.promptForListSelect(message=f"Select the {self.manageAppName} dedicated DB2 instance type", options=["db2wh", "db2oltp"], param="db2_type", default="1")
129
+ else:
130
+ self.setParam("db2_type", "db2wh")
131
+ else:
132
+ workspaceId = self.getParam("mas_workspace_id")
133
+ self.setParam("db2_action_manage", "byo")
134
+
135
+ self.selectLocalConfigDir()
136
+
137
+ # Check if a configuration already exists before creating a new one
138
+ jdbcCfgFile = path.join(self.localConfigDir, f"jdbc-{instanceId}-manage.yaml")
139
+ print_formatted_text(f"Searching for {self.manageAppName} database configuration file in {jdbcCfgFile} ...")
140
+ if path.exists(jdbcCfgFile):
141
+ if self.yesOrNo(f"{self.manageAppName} database configuration file 'jdbc-{instanceId}-manage.yaml' already exists. Do you want to generate a new one"):
142
+ self.generateJDBCCfg(instanceId=instanceId, scope="workspace-application", workspaceId=workspaceId, appId="manage", destination=jdbcCfgFile)
143
+ else:
144
+ print_formatted_text(f"Expected file ({jdbcCfgFile}) was not found, generating a valid {self.manageAppName} database configuration file now ...")
145
+ self.generateJDBCCfg(instanceId=instanceId, scope="workspace-application", workspaceId=workspaceId, appId="manage", destination=jdbcCfgFile)
146
+ else:
147
+ self.setParam("db2_action_manage", "none")
148
+
149
+ # Do we need to create and configure a Db2 for Facilities ?
150
+ if self.installFacilities:
151
+ self.printH2("Database Configuration for Maximo Real Estate and Facilities")
152
+ if self.yesOrNo("Create Real Estate and Facilities dedicated Db2 instance using the IBM Db2 Universal Operator"):
153
+ self.setParam("db2_action_facilities", "install")
154
+ else:
155
+ self.setParam("db2_action_facilities", "none")
156
+ instanceId = self.getParam('mas_instance_id')
157
+ workspaceId = self.getParam("mas_workspace_id")
158
+ self.selectLocalConfigDir()
159
+
160
+ # Check if a configuration already exists before creating a new one
161
+ jdbcCfgFile = path.join(self.localConfigDir, f"jdbc-{instanceId}-facilities.yaml")
162
+ print_formatted_text(f"Searching for Real Estate and Facilities database configuration file in {jdbcCfgFile} ...")
163
+ if path.exists(jdbcCfgFile):
164
+ if self.yesOrNo(f"Real Estate and Facilities database configuration file 'jdbc-{instanceId}-facilities.yaml' already exists. Do you want to generate a new one"):
165
+ self.generateJDBCCfg(instanceId=instanceId, scope="workspace-application", workspaceId=workspaceId, appId="facilities", destination=jdbcCfgFile)
166
+ else:
167
+ print_formatted_text(f"Expected file ({jdbcCfgFile}) was not found, generating a valid Real Estate and Facilities database configuration file now ...")
168
+ self.generateJDBCCfg(instanceId=instanceId, scope="workspace-application", workspaceId=workspaceId, appId="facilities", destination=jdbcCfgFile)
169
+ else:
170
+ self.setParam("db2_action_facilities", "none")
171
+
172
+ # Do we need to configure Db2u?
173
+ if self.getParam("db2_action_system") == "install" or self.getParam("db2_action_manage") == "install" or self.getParam("db2_action_facilities") == "install":
174
+ if self.showAdvancedOptions:
175
+ self.printH2("Installation Namespace")
176
+ self.promptForString("Install namespace", "db2_namespace", default="db2u")
177
+
178
+ # Node Affinity & Tolerations
179
+ # -------------------------------------------------------------------------
180
+ self.printH2("Node Affinity and Tolerations")
181
+ self.printDescription([
182
+ f"Note that the same settings are applied to both the IoT and {self.manageAppName} Db2 instances",
183
+ "Use existing node labels and taints to control scheduling of the Db2 workload in your cluster",
184
+ "For more information refer to the Red Hat documentation:",
185
+ " - <Orange><u>https://docs.openshift.com/container-platform/4.18/nodes/scheduling/nodes-scheduler-node-affinity.html</u></Orange>",
186
+ " - <Orange><u>https://docs.openshift.com/container-platform/4.18/nodes/scheduling/nodes-scheduler-taints-tolerations.html</u></Orange>",
187
+ " - <Orange><u>https://docs.openshift.com/container-platform/4.17/nodes/scheduling/nodes-scheduler-node-affinity.html</u></Orange>",
188
+ " - <Orange><u>https://docs.openshift.com/container-platform/4.17/nodes/scheduling/nodes-scheduler-taints-tolerations.html</u></Orange>"
189
+ ])
190
+
191
+ if self.yesOrNo("Configure node affinity"):
192
+ self.promptForString(" + Key", "db2_affinity_key")
193
+ self.promptForString(" + Value", "db2_affinity_value")
194
+
195
+ if self.yesOrNo("Configure node tolerations"):
196
+ self.promptForString(" + Key", "db2_tolerate_key")
197
+ self.promptForString(" + Value", "db2_tolerate_value")
198
+ self.promptForString(" + Effect", "db2_tolerate_effect")
199
+
200
+ self.printH2("Database CPU & Memory")
201
+ self.printDescription([
202
+ f"Note that the same settings are applied to both the IoT and {self.manageAppName} Db2 instances"
203
+ ])
204
+
205
+ if self.yesOrNo("Customize CPU and memory request/limit"):
206
+ self.promptForString(" + CPU Request", "db2_cpu_requests", default=self.getParam("db2_cpu_requests"))
207
+ self.promptForString(" + CPU Limit", "db2_cpu_limits", default=self.getParam("db2_cpu_limits"))
208
+ self.promptForString(" + Memory Request", "db2_memory_requests", default=self.getParam("db2_memory_requests"))
209
+ self.promptForString(" + Memory Limit", "db2_memory_limits", default=self.getParam("db2_memory_limits"))
210
+
211
+ self.printH2("Database Storage Capacity")
212
+ self.printDescription([
213
+ f"Note that the same settings are applied to both the IoT and {self.manageAppName} Db2 instances"
214
+ ])
215
+
216
+ if self.yesOrNo("Customize storage capacity"):
217
+ self.promptForString(" + Data Volume", "db2_data_storage_size", default=self.getParam("db2_data_storage_size"))
218
+ self.promptForString(" + Temporary Volume", "db2_temp_storage_size", default=self.getParam("db2_temp_storage_size"))
219
+ self.promptForString(" + Metadata Volume", "db2_meta_storage_size", default=self.getParam("db2_meta_storage_size"))
220
+ self.promptForString(" + Transaction Logs Volume", "db2_logs_storage_size", default=self.getParam("db2_logs_storage_size"))
221
+ self.promptForString(" + Backup Volume", "db2_backup_storage_size", default=self.getParam("db2_backup_storage_size"))
222
+ else:
223
+ self.setParam("db2_namespace", "db2u")
224
+
225
+ def setDB2DefaultSettings(self) -> None:
226
+
227
+ self.setParam("db2_cpu_requests", "4000m")
228
+ self.setParam("db2_cpu_limits", "6000m")
229
+ self.setParam("db2_memory_requests", "8Gi")
230
+ self.setParam("db2_memory_limits", "12Gi")
231
+
232
+ if self.isSNO():
233
+ # Set smaller defaults for SNO deployments
234
+ self.setParam("db2_meta_storage_size", "10Gi")
235
+ self.setParam("db2_backup_storage_size", "10Gi")
236
+ self.setParam("db2_logs_storage_size", "10Gi")
237
+ self.setParam("db2_temp_storage_size", "10Gi")
238
+ self.setParam("db2_data_storage_size", "20Gi")
239
+
240
+ # Configure the access mode to RWO
241
+ self.params["db2_meta_storage_accessmode"] = "ReadWriteOnce"
242
+ self.params["db2_backup_storage_accessmode"] = "ReadWriteOnce"
243
+ self.params["db2_logs_storage_accessmode"] = "ReadWriteOnce"
244
+ self.params["db2_data_storage_accessmode"] = "ReadWriteOnce"
245
+ self.params["db2_cpu_requests"] = "300m"
246
+
247
+ else:
248
+ self.setParam("db2_meta_storage_size", "20Gi")
249
+ self.setParam("db2_backup_storage_size", "100Gi")
250
+ self.setParam("db2_logs_storage_size", "100Gi")
251
+ self.setParam("db2_temp_storage_size", "100Gi")
252
+ self.setParam("db2_data_storage_size", "100Gi")
@@ -0,0 +1,103 @@
1
+ # *****************************************************************************
2
+ # Copyright (c) 2024 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
+ from os import path
12
+ from prompt_toolkit import print_formatted_text
13
+
14
+
15
+ class KafkaSettingsMixin():
16
+ def configKafka(self) -> None:
17
+ if self.installIoT:
18
+ self.printH1("Configure Kafka")
19
+ self.printDescription([
20
+ "Maximo IoT requires a shared system-scope Kafka instance",
21
+ "Supported Kafka providers: Strimzi, Red Hat AMQ Streams, IBM Cloud Event Streams and AWS MSK",
22
+ "You may also choose to configure MAS to use an existing Kafka instance by providing a pre-existing configuration file"
23
+ ])
24
+ if self.yesOrNo("Create system Kafka instance using one of the supported providers"):
25
+ self.setParam("kafka_action_system", "install")
26
+
27
+ if self.showAdvancedOptions:
28
+ self.printDescription([
29
+ "",
30
+ "Kafka Provider:",
31
+ " 1. Strimzi (opensource)",
32
+ " 2. Red Hat AMQ Streams (requires a separate license)",
33
+ " 3. IBM Cloud Event Streams (paid IBM Cloud service)",
34
+ " 4. AWS MSK (paid AWS service)"
35
+ ])
36
+ self.promptForListSelect("Select Kafka provider", ["strimzi", "redhat", "ibm", "aws"], "kafka_provider")
37
+ else:
38
+ self.setParam("kafka_provider", "strimzi")
39
+
40
+ if self.getParam("kafka_provider") == "strimzi":
41
+ self.printDescription([
42
+ "",
43
+ "Strimzi: Cluster Version",
44
+ "The version of the Strimzi operator available on your cluster will determine the supported versions of Kafka that can be deployed.",
45
+ " - If you are using the latest available operator catalog then the default version below can be accepted",
46
+ " - If you are using older operator catalogs (e.g. in a disconnected install) you should confirm the supported versions in your OperatorHub"
47
+ ])
48
+ if self.showAdvancedOptions:
49
+ self.promptForString("Strimzi namespace", "kafka_namespace", default="strimzi")
50
+ self.promptForString("Kafka version", "kafka_version", default="3.9.0")
51
+
52
+ elif self.getParam("kafka_provider") == "redhat":
53
+ self.printDescription([
54
+ "",
55
+ "Red Hat AMQ Streams: Cluster Version",
56
+ "The version of the Red Hat AMQ Streams operator available on your cluster will determine the supported versions of Kafka that can be deployed.",
57
+ " - If you are using the latest available operator catalog then the default version below can be accepted",
58
+ " - If you are using older operator catalogs (e.g. in a disconnected install) you should confirm the supported versions in your OperatorHub"
59
+ ])
60
+ self.promptForString("Install namespace", "kafka_namespace", default="amq-streams")
61
+ self.promptForString("Kafka version", "kafka_version", default="3.8.0")
62
+
63
+ elif self.getParam("kafka_provider") == "ibm":
64
+ print()
65
+ self.promptForString("IBM Cloud API Key", "ibmcloud_apikey", isPassword=True)
66
+ self.promptForString("IBM Event Streams resource group" "eventstreams_resourcegroup", default="Default")
67
+ self.promptForString("IBM Event Streams instance name", "eventstreams_name", default=f"eventstreams-{self.getParam('mas_instance_id')}")
68
+ self.promptForString("IBM Event Streams location", "eventstreams_location", default="us-east")
69
+
70
+ elif self.getParam("kafka_provider") == "aws":
71
+ self.printDescription([
72
+ "",
73
+ "While provisioning the AWS MSK instance, you will be required to provide the AWS Virtual Private Cloud ID and subnet details",
74
+ "where your instance will be deployed to properly configure inbound and outbound connectivity.",
75
+ "You should be able to find these information inside your VPC and subnet configurations in the target AWS account.",
76
+ "For more details about AWS subnet/CIDR configuration, refer: <Orange><u>https://docs.aws.amazon.com/vpc/latest/userguide/subnet-sizing.html</u></Orange>"
77
+ ])
78
+ self.promptForString("AWS Access Key ID", "aws_access_key_id", isPassword=True)
79
+ self.promptForString("AWS Secret Access Key" "aws_secret_access_key", isPassword=True)
80
+ self.promptForString("AWS Region", "aws_region", default="us-east-1")
81
+ self.promptForString("Virtual Private Cloud (VPC) ID", "vpc_id")
82
+ self.promptForString("MSK Instance Username", "aws_kafka_user_name", default="masuser")
83
+ self.promptForString("MSK Instance Password", "aws_kafka_user_password", isPassword=True)
84
+ self.promptForString("MSK Instance Type", "aws_msk_instance_type", default="kafka.m5.large")
85
+ self.promptForString("MSK Total Number of Broker Nodes", "aws_msk_instance_number", default="3")
86
+ self.promptForString("MSK Storage Size (in GB)", "aws_msk_volume_size", defauklt="100")
87
+ self.promptForString("Availability Zone 1 CIDR", "aws_msk_cidr_az1")
88
+ self.promptForString("Availability Zone 2 CIDR", "aws_msk_cidr_az2")
89
+ self.promptForString("Availability Zone 3 CIDR", "aws_msk_cidr_az3")
90
+ self.promptForString("Ingress CIDR", "aws_msk_ingress_cidr")
91
+ self.promptForString("Egress CIDR", "aws_msk_egress_cidr")
92
+ else:
93
+ self.setParam("kafka_action_system", "byo")
94
+ self.selectLocalConfigDir()
95
+ instanceId = self.getParam('mas_instance_id')
96
+
97
+ # Check if a configuration already exists
98
+ kafkaCfgFile = path.join(self.localConfigDir, f"kafka-{instanceId}-system.yaml")
99
+ print_formatted_text(f"Searching for system kafka configuration file in {kafkaCfgFile} ...")
100
+ if path.exists(kafkaCfgFile):
101
+ print_formatted_text(f"Provided Kafka configuration file {kafkaCfgFile} will be applied")
102
+ else:
103
+ self.fatalError(f"Kafka configuration file does not exist: '{kafkaCfgFile}'. In order to continue, provide an existing Kafka configuration file or choose one of the supported Kafka providers to be installed")
@@ -0,0 +1,273 @@
1
+ # *****************************************************************************
2
+ # Copyright (c) 2024 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 logging
12
+ logger = logging.getLogger(__name__)
13
+
14
+
15
+ class ManageSettingsMixin():
16
+
17
+ def arcgisSettings(self) -> None:
18
+ # If Spatial is selected, then prompt to choose to add IBM Maximo Location Services for Esri, and prompt license
19
+ if "spatial=" in self.getParam("mas_appws_components") and self.getParam("mas_app_channel_manage").startswith("9."):
20
+ self.printDescription([
21
+ "",
22
+ "Maximo Spatial requires a map server provider in order to enable geospatial capabilities",
23
+ "You may choose your preferred map provider later or you can enable IBM Maximo Location Services for Esri now",
24
+ f"This includes ArcGIS Enterprise as part of the {self.manageAppName} and Maximo Spatial bundle (Additional AppPoints required)."
25
+ ])
26
+
27
+ if self.yesOrNo("Include IBM Maximo Location Services for Esri"):
28
+ self.setParam("install_arcgis", "true")
29
+ self.setParam("mas_arcgis_channel", self.getParam("mas_app_channel_manage"))
30
+
31
+ self.printDescription([
32
+ "",
33
+ "IBM Maximo Location Services for Esri License Terms",
34
+ "For information about your IBM Maximo Location Services for Esri License visit: ",
35
+ " - <Orange><u>https://ibm.biz/MAXArcGIS90-License</u></Orange>",
36
+ "To continue with the installation, you must accept these additional license terms"
37
+ ])
38
+
39
+ if not self.yesOrNo("Do you accept the license terms"):
40
+ exit(1)
41
+
42
+ def manageSettings(self) -> None:
43
+ if self.installManage:
44
+ self.printH1(f"Configure Maximo {self.manageAppName}")
45
+ self.printDescription([f"Customize your {self.manageAppName} installation, refer to the product documentation for more information"])
46
+
47
+ self.manageSettingsComponents()
48
+ self.arcgisSettings()
49
+
50
+ self.manageSettingsServerBundleConfig()
51
+ self.manageSettingsJMS()
52
+ self.manageSettingsDatabase()
53
+ self.manageSettingsCustomizationArchive()
54
+ self.manageSettingsOther()
55
+ self.manageStorageAndAccessMode()
56
+
57
+ def manageStorageAndAccessMode(self) -> None:
58
+ # Default to RWX storage classes, but fall back to RWO in SNO or when user
59
+ # has chosen not to provide a RWX storage class
60
+ storageClass = self.getParam("storage_class_rwx")
61
+ accessMode = "ReadWriteMany"
62
+ if self.isSNO() or self.getParam("storage_class_rwx") == "none":
63
+ storageClass = self.getParam("storage_class_rwo")
64
+ accessMode = "ReadWriteOnce"
65
+
66
+ self.setParam("mas_app_settings_doclinks_pvc_storage_class", storageClass)
67
+ self.setParam("mas_app_settings_bim_pvc_storage_class", storageClass)
68
+ self.setParam("mas_app_settings_jms_queue_pvc_storage_class", storageClass)
69
+
70
+ self.setParam("mas_app_settings_doclinks_pvc_accessmode", accessMode)
71
+ self.setParam("mas_app_settings_bim_pvc_accessmode", accessMode)
72
+ self.setParam("mas_app_settings_jms_queue_pvc_accessmode", accessMode)
73
+
74
+ def manageSettingsComponents(self) -> None:
75
+ # Only ask to install Manage components if this is a full Manage installation
76
+ # If this is a Manage Foundation installation, leave mas_appws_components blank
77
+ if self.isManageFoundation:
78
+ self.params["mas_appws_components"] = ""
79
+ else:
80
+ self.printH2(f"Maximo {self.manageAppName} Components")
81
+ self.printDescription([f"The default configuration will install {self.manageAppName} with Health enabled, alternatively choose exactly what industry solutions and add-ons will be configured"])
82
+
83
+ self.params["mas_appws_components"] = "base=latest,health=latest"
84
+ if self.yesOrNo("Select components to enable"):
85
+ self.params["mas_appws_components"] = "base=latest"
86
+ if self.yesOrNo(" - Asset Configuration Manager"):
87
+ self.params["mas_appws_components"] += ",acm=latest"
88
+ if self.yesOrNo(" - Aviation"):
89
+ self.params["mas_appws_components"] += ",aviation=latest"
90
+ if self.yesOrNo(" - Civil Infrastructure"):
91
+ self.params["mas_appws_components"] += ",civil=latest"
92
+ if self.yesOrNo(" - Envizi"):
93
+ self.params["mas_appws_components"] += ",envizi=latest"
94
+ if self.yesOrNo(" - Health"):
95
+ self.params["mas_appws_components"] += ",health=latest"
96
+ if self.yesOrNo(" - Health, Safety and Environment"):
97
+ self.params["mas_appws_components"] += ",hse=latest"
98
+ if self.yesOrNo(" - Maximo IT"):
99
+ self.params["mas_appws_components"] += ",icd=latest"
100
+ if self.yesOrNo(" - Nuclear"):
101
+ self.params["mas_appws_components"] += ",nuclear=latest"
102
+ if self.yesOrNo(" - Oil & Gas"):
103
+ self.params["mas_appws_components"] += ",oilandgas=latest"
104
+ if self.yesOrNo(" - Connector for Oracle Applications"):
105
+ self.params["mas_appws_components"] += ",oracleadapter=latest"
106
+ if self.yesOrNo(" - Connector for SAP Application"):
107
+ self.params["mas_appws_components"] += ",sapadapter=latest"
108
+ if self.yesOrNo(" - Service Provider"):
109
+ self.params["mas_appws_components"] += ",serviceprovider=latest"
110
+ if self.yesOrNo(" - Spatial"):
111
+ self.params["mas_appws_components"] += ",spatial=latest"
112
+ if self.yesOrNo(" - Strategize"):
113
+ self.params["mas_appws_components"] += ",strategize=latest"
114
+ if self.yesOrNo(" - Transportation"):
115
+ self.params["mas_appws_components"] += ",transportation=latest"
116
+ if self.yesOrNo(" - Tririga"):
117
+ self.params["mas_appws_components"] += ",tririga=latest"
118
+ if self.yesOrNo(" - Utilities"):
119
+ self.params["mas_appws_components"] += ",utilities=latest"
120
+ if self.yesOrNo(" - Workday Applications"):
121
+ self.params["mas_appws_components"] += ",workday=latest"
122
+ if self.yesOrNo(" - AIP"):
123
+ self.params["mas_appws_components"] += ",aip=latest"
124
+ logger.debug(f"Generated mas_appws_components = {self.params['mas_appws_components']}")
125
+
126
+ if ",icd=" in self.params["mas_appws_components"]:
127
+ self.printH2("Maximo IT License Terms")
128
+ self.printDescription([
129
+ "For information about your Maximo IT License, see <Orange><u>https://ibm.biz/MAXIT81-License</u></Orange>",
130
+ "To continue with the installation, you must accept these additional license terms"
131
+ ])
132
+
133
+ if not self.yesOrNo("Do you accept the license terms"):
134
+ exit(1)
135
+
136
+ def manageSettingsDatabase(self) -> None:
137
+ if self.showAdvancedOptions:
138
+ self.printH2(f"Maximo {self.manageAppName} Settings - Database")
139
+ self.printDescription([f"Customise the schema, tablespace, indexspace, and encryption settings used by {self.manageAppName}"])
140
+
141
+ if self.yesOrNo("Customize database settings"):
142
+ self.promptForString("Schema", "mas_app_settings_db2_schema", default="maximo")
143
+ self.promptForString("Tablespace", "mas_app_settings_tablespace", default="MAXDATA")
144
+ self.promptForString("Indexspace", "mas_app_settings_indexspace", default="MAXINDEX")
145
+
146
+ if self.yesOrNo("Customize database encryption settings"):
147
+ self.promptForString("MXE_SECURITY_CRYPTO_KEY", "mas_app_settings_crypto_key")
148
+ self.promptForString("MXE_SECURITY_CRYPTOX_KEY", "mas_app_settings_cryptox_key")
149
+ self.promptForString("MXE_SECURITY_OLD_CRYPTO_KEY", "mas_app_settings_old_crypto_key")
150
+ self.promptForString("MXE_SECURITY_OLD_CRYPTOX_KEY", "mas_app_settings_old_cryptox_key")
151
+ self.yesOrNo("Override database encryption secrets with provided keys", "mas_app_settings_override_encryption_secrets_flag")
152
+
153
+ def manageSettingsServerBundleConfig(self) -> None:
154
+ if not self.isManageFoundation:
155
+ if self.showAdvancedOptions:
156
+ self.printH2(f"Maximo {self.manageAppName} Settings - Server Bundles")
157
+ self.printDescription([
158
+ f"Define how you want to configure {self.manageAppName} servers:",
159
+ f" - You can have one or multiple {self.manageAppName} servers distributing workload",
160
+ " - Additionally, you can choose to include JMS server for messaging queues",
161
+ "",
162
+ "Configurations:",
163
+ " 1. Deploy the 'all' server pod only (workload is concentrated in just one server pod but consumes less resource)",
164
+ " 2. Deploy the 'all' and 'jms' bundle pods (workload is concentrated in just one server pod and includes jms server)"
165
+ ])
166
+
167
+ if not self.isSNO():
168
+ self.printDescription([
169
+ " 3. Deploy the 'mea', 'report', 'ui' and 'cron' bundle pods (workload is distributed across multiple server pods)",
170
+ " 4. Deploy the 'mea', 'report', 'ui', 'cron' and 'jms' bundle pods (workload is distributed across multiple server pods and includes jms server)"
171
+ ])
172
+
173
+ manageServerBundleSelection = self.promptForString("Select a server bundle configuration")
174
+
175
+ if manageServerBundleSelection == "1":
176
+ self.setParam("mas_app_settings_server_bundles_size", "dev")
177
+ elif manageServerBundleSelection == "2":
178
+ self.setParam("mas_app_settings_server_bundles_size", "snojms")
179
+ self.setParam("mas_app_settings_persistent_volumes_flag", "true")
180
+ elif manageServerBundleSelection == "3":
181
+ self.setParam("mas_app_settings_server_bundles_size", "small")
182
+ elif manageServerBundleSelection == "4":
183
+ self.setParam("mas_app_settings_server_bundles_size", "jms")
184
+ self.setParam("mas_app_settings_persistent_volumes_flag", "true")
185
+ else:
186
+ self.fatalError("Invalid selection")
187
+ else:
188
+ self.setParam("mas_app_settings_server_bundles_size", "dev")
189
+
190
+ def manageSettingsJMS(self) -> None:
191
+ if self.getParam("mas_app_settings_server_bundles_size") in ["jms", "snojms"]:
192
+ self.printDescription([
193
+ f"Only {self.manageAppName} JMS sequential queues (sqin and sqout) are enabled by default.",
194
+ "However, you can enable both sequential (sqin and sqout) and continuous queues (cqin and cqout)"
195
+ ])
196
+
197
+ self.yesOrNo(f"Enable both {self.manageAppName} JMS sequential and continuous queues", "mas_app_settings_default_jms")
198
+
199
+ def manageSettingsCustomizationArchive(self) -> None:
200
+ # Only ask about customization archive in full Manage installation
201
+ if not self.isManageFoundation:
202
+ self.printH2(f"Maximo {self.manageAppName} Settings - Customization")
203
+ self.printDescription([
204
+ f"Provide a customization archive to be used in the {self.manageAppName} build process"
205
+ ])
206
+
207
+ if self.yesOrNo("Include customization archive"):
208
+ self.promptForString("Customization archive name", "mas_app_settings_customization_archive_name")
209
+ self.promptForString("Customization archive path/url", "mas_app_settings_customization_archive_url")
210
+ if self.yesOrNo("Provide authentication to access customization archive URL"):
211
+ self.promptForString("Username", "mas_app_settings_customization_archive_username")
212
+ self.promptForString("Password", "mas_app_settings_customization_archive_password", isPassword=True) # pragma: allowlist secret
213
+
214
+ def manageSettingsDemodata(self) -> None:
215
+ self.yesOrNo("Create demo data", "mas_app_settings_demodata")
216
+
217
+ def manageSettingsTimezone(self) -> None:
218
+ self.promptForString(f"{self.manageAppName} server timezone", "mas_app_settings_server_timezone", default="GMT")
219
+ # Set Manage dedicated Db2 instance timezone to be same as Manage server timezone
220
+ self.setParam("db2_timezone", self.getParam("mas_app_settings_server_timezone"))
221
+
222
+ def manageSettingsLanguages(self) -> None:
223
+ self.printH2(f"Maximo {self.manageAppName} Settings - Languages")
224
+ self.printDescription([
225
+ f"Define the base language for Maximo {self.manageAppName}"
226
+ ])
227
+ self.promptForString("Base language", "mas_app_settings_base_lang", default="EN")
228
+
229
+ self.printDescription([
230
+ f"Define the additional languages to be configured in Maximo {self.manageAppName}. provide a comma-separated list of supported languages codes, for example: 'JA,DE,AR'",
231
+ "A complete list of available language codes is available online:",
232
+ " <Orange><u>https://www.ibm.com/docs/en/mas-cd/mhmpmh-and-p-u/continuous-delivery?topic=deploy-language-support</u></Orange>"
233
+ ])
234
+
235
+ self.promptForString("Secondary languages", "mas_app_settings_secondary_langs")
236
+
237
+ def manageSettingsCP4D(self) -> None:
238
+ if self.getParam("mas_app_channel_manage") in ["8.7.x", "9.0.x"] and self.showAdvancedOptions:
239
+ self.printDescription([
240
+ f"Integration with Cognos Analytics provides additional support for reporting features in Maximo {self.manageAppName}, for more information refer to the documentation online: ",
241
+ " - <Orange><u>https://ibm.biz/BdMuxs</u></Orange>"
242
+ ])
243
+ self.yesOrNo("Enable integration with Cognos Analytics", "cpd_install_cognos")
244
+ self.yesOrNo("Enable integration with Watson Studio Local", "mas_appws_bindings_health_flag")
245
+
246
+ if self.getParam("cpd_install_cognos") == "true" or self.getParam("mas_appws_bindings_health_flag") == "true":
247
+ self.configCP4D()
248
+
249
+ def manageSettingsOther(self) -> None:
250
+ self.printH2(f"Maximo {self.manageAppName} Settings - Other")
251
+ if self.isManageFoundation:
252
+ self.printDescription([
253
+ "Configure additional settings:",
254
+ " - Base and additional languages",
255
+ " - Server timezone"
256
+ ])
257
+ if self.yesOrNo("Configure Additional Settings"):
258
+ self.manageSettingsTimezone()
259
+ self.manageSettingsLanguages()
260
+ else:
261
+ self.printDescription([
262
+ "Configure additional settings:",
263
+ " - Demo data",
264
+ " - Base and additional languages",
265
+ " - Server timezone",
266
+ " - Cognos integration (install Cloud Pak for Data)",
267
+ " - Watson Studio Local integration (install Cloud Pak for Data)"
268
+ ])
269
+ if self.yesOrNo("Configure Additional Settings"):
270
+ self.manageSettingsDemodata()
271
+ self.manageSettingsTimezone()
272
+ self.manageSettingsLanguages()
273
+ self.manageSettingsCP4D()