mas-cli 11.4.0__py3-none-any.whl → 11.6.0__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.
- mas/cli/__init__.py +1 -1
- mas/cli/cli.py +7 -8
- mas/cli/displayMixins.py +18 -14
- mas/cli/gencfg.py +3 -2
- mas/cli/install/__init__.py +1 -1
- mas/cli/install/app.py +96 -46
- mas/cli/install/argBuilder.py +170 -159
- mas/cli/install/argParser.py +194 -2
- mas/cli/install/settings/__init__.py +5 -4
- mas/cli/install/settings/additionalConfigs.py +27 -26
- mas/cli/install/settings/db2Settings.py +2 -2
- mas/cli/install/settings/kafkaSettings.py +1 -0
- mas/cli/install/settings/manageSettings.py +62 -19
- mas/cli/install/settings/turbonomicSettings.py +1 -0
- mas/cli/install/summarizer.py +36 -9
- mas/cli/templates/ibm-mas-tekton.yaml +1920 -360
- mas/cli/uninstall/__init__.py +1 -1
- mas/cli/uninstall/app.py +15 -14
- mas/cli/uninstall/argParser.py +1 -1
- mas/cli/update/__init__.py +1 -1
- mas/cli/update/app.py +39 -39
- mas/cli/update/argParser.py +1 -1
- mas/cli/upgrade/__init__.py +1 -1
- mas/cli/upgrade/app.py +8 -7
- mas/cli/upgrade/argParser.py +1 -1
- {mas_cli-11.4.0.data → mas_cli-11.6.0.data}/scripts/mas-cli +8 -6
- {mas_cli-11.4.0.dist-info → mas_cli-11.6.0.dist-info}/METADATA +2 -2
- {mas_cli-11.4.0.dist-info → mas_cli-11.6.0.dist-info}/RECORD +30 -30
- {mas_cli-11.4.0.dist-info → mas_cli-11.6.0.dist-info}/WHEEL +1 -1
- {mas_cli-11.4.0.dist-info → mas_cli-11.6.0.dist-info}/top_level.txt +0 -0
mas/cli/__init__.py
CHANGED
mas/cli/cli.py
CHANGED
|
@@ -30,7 +30,6 @@ from prompt_toolkit import prompt, print_formatted_text, HTML
|
|
|
30
30
|
from mas.devops.mas import isAirgapInstall
|
|
31
31
|
from mas.devops.ocp import connect, isSNO
|
|
32
32
|
|
|
33
|
-
from .validators import YesNoValidator
|
|
34
33
|
from .displayMixins import PrintMixin, PromptMixin
|
|
35
34
|
|
|
36
35
|
# Configure the logger
|
|
@@ -97,7 +96,7 @@ class BaseApp(PrintMixin, PromptMixin):
|
|
|
97
96
|
|
|
98
97
|
# Set up a log handler (5mb rotating log file)
|
|
99
98
|
ch = logging.handlers.RotatingFileHandler(
|
|
100
|
-
"mas.log", maxBytes=(1048576*5), backupCount=2
|
|
99
|
+
"mas.log", maxBytes=(1048576 * 5), backupCount=2
|
|
101
100
|
)
|
|
102
101
|
ch.setLevel(logging.DEBUG)
|
|
103
102
|
ch.setFormatter(chFormatter)
|
|
@@ -108,7 +107,7 @@ class BaseApp(PrintMixin, PromptMixin):
|
|
|
108
107
|
rootLogger.setLevel(logging.DEBUG)
|
|
109
108
|
|
|
110
109
|
# Supports extended semver, unlike mas.cli.__version__
|
|
111
|
-
self.version = "11.
|
|
110
|
+
self.version = "11.6.0"
|
|
112
111
|
self.h1count = 0
|
|
113
112
|
self.h2count = 0
|
|
114
113
|
|
|
@@ -138,7 +137,8 @@ class BaseApp(PrintMixin, PromptMixin):
|
|
|
138
137
|
"monitor": ["9.0.x", "8.11.x"],
|
|
139
138
|
"optimizer": ["9.0.x", "8.5.x"],
|
|
140
139
|
"predict": ["9.0.x", "8.9.x"],
|
|
141
|
-
"visualinspection": ["9.0.x", "8.9.x"]
|
|
140
|
+
"visualinspection": ["9.0.x", "8.9.x"],
|
|
141
|
+
"aibroker": ["9.0.x"]
|
|
142
142
|
},
|
|
143
143
|
"8.11.x": {
|
|
144
144
|
"assist": ["8.8.x", "8.7.x"],
|
|
@@ -223,7 +223,7 @@ class BaseApp(PrintMixin, PromptMixin):
|
|
|
223
223
|
else:
|
|
224
224
|
return []
|
|
225
225
|
|
|
226
|
-
def fatalError(self, message: str, exception: Exception=None) -> None:
|
|
226
|
+
def fatalError(self, message: str, exception: Exception = None) -> None:
|
|
227
227
|
if exception is not None:
|
|
228
228
|
logger.error(message)
|
|
229
229
|
logger.exception(exception, stack_info=True)
|
|
@@ -289,8 +289,7 @@ class BaseApp(PrintMixin, PromptMixin):
|
|
|
289
289
|
print()
|
|
290
290
|
if not self.noConfirm:
|
|
291
291
|
# We are already connected to a cluster, but prompt the user if they want to use this connection
|
|
292
|
-
|
|
293
|
-
promptForNewServer = continueWithExistingCluster in ["n", "no"]
|
|
292
|
+
promptForNewServer = not self.yesOrNo("Proceed with this cluster?")
|
|
294
293
|
except Exception as e:
|
|
295
294
|
# We are already connected to a cluster, but the connection is not valid so prompt for connection details
|
|
296
295
|
logger.debug("Failed looking up OpenShift Console route to verify connection")
|
|
@@ -311,7 +310,7 @@ class BaseApp(PrintMixin, PromptMixin):
|
|
|
311
310
|
print_formatted_text(HTML("<Red>Unable to connect to cluster. See log file for details</Red>"))
|
|
312
311
|
exit(1)
|
|
313
312
|
|
|
314
|
-
def initializeApprovalConfigMap(self, namespace: str, id: str, key: str=None, maxRetries: int=100, delay: int=300, ignoreFailure: bool=True) -> None:
|
|
313
|
+
def initializeApprovalConfigMap(self, namespace: str, id: str, key: str = None, maxRetries: int = 100, delay: int = 300, ignoreFailure: bool = True) -> None:
|
|
315
314
|
"""
|
|
316
315
|
Set key = None if you don't want approval workflow enabled
|
|
317
316
|
"""
|
mas/cli/displayMixins.py
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
#
|
|
9
9
|
# *****************************************************************************
|
|
10
10
|
|
|
11
|
-
from os import
|
|
11
|
+
from os import getenv
|
|
12
12
|
from prompt_toolkit import prompt, print_formatted_text, HTML
|
|
13
13
|
from prompt_toolkit.completion import WordCompleter
|
|
14
14
|
from prompt_toolkit.validation import Validator
|
|
@@ -18,12 +18,13 @@ from .validators import YesNoValidator, FileExistsValidator, DirectoryExistsVali
|
|
|
18
18
|
import logging
|
|
19
19
|
logger = logging.getLogger(__name__)
|
|
20
20
|
|
|
21
|
-
H1COLOR="SkyBlue"
|
|
22
|
-
H2COLOR="SkyBlue"
|
|
23
|
-
DESCRIPTIONCOLOR="LightSlateGrey"
|
|
24
|
-
SUMMARYCOLOR="SkyBlue"
|
|
25
|
-
UNDEFINEDPARAMCOLOR="LightSlateGrey"
|
|
26
|
-
PROMPTCOLOR="Yellow"
|
|
21
|
+
H1COLOR = "SkyBlue"
|
|
22
|
+
H2COLOR = "SkyBlue"
|
|
23
|
+
DESCRIPTIONCOLOR = "LightSlateGrey"
|
|
24
|
+
SUMMARYCOLOR = "SkyBlue"
|
|
25
|
+
UNDEFINEDPARAMCOLOR = "LightSlateGrey"
|
|
26
|
+
PROMPTCOLOR = "Yellow"
|
|
27
|
+
|
|
27
28
|
|
|
28
29
|
class PrintMixin():
|
|
29
30
|
def printTitle(self, message):
|
|
@@ -67,14 +68,17 @@ class PrintMixin():
|
|
|
67
68
|
else:
|
|
68
69
|
self.printSummary(message, self.getParam(param))
|
|
69
70
|
|
|
71
|
+
|
|
70
72
|
def masPromptYesOrNo(message):
|
|
71
73
|
return HTML(f"<{PROMPTCOLOR}>{message.replace(' & ', ' & ')}? [y/n]</{PROMPTCOLOR}> ")
|
|
72
74
|
|
|
75
|
+
|
|
73
76
|
def masPromptValue(message):
|
|
74
77
|
return HTML(f"<{PROMPTCOLOR}>{message.replace(' & ', ' & ')}</{PROMPTCOLOR}> ")
|
|
75
78
|
|
|
79
|
+
|
|
76
80
|
class PromptMixin():
|
|
77
|
-
def yesOrNo(self, message: str, param: str=None) -> bool:
|
|
81
|
+
def yesOrNo(self, message: str, param: str = None) -> bool:
|
|
78
82
|
response = prompt(masPromptYesOrNo(message), validator=YesNoValidator(), validate_while_typing=False)
|
|
79
83
|
responseAsBool = response.lower() in ["y", "yes"]
|
|
80
84
|
|
|
@@ -82,7 +86,7 @@ class PromptMixin():
|
|
|
82
86
|
self.params[param] = "true" if responseAsBool else "false"
|
|
83
87
|
return responseAsBool
|
|
84
88
|
|
|
85
|
-
def promptForString(self, message: str, param: str=None, default: str="", isPassword: bool=False, validator: Validator=None, completer: WordCompleter=None) -> str:
|
|
89
|
+
def promptForString(self, message: str, param: str = None, default: str = "", isPassword: bool = False, validator: Validator = None, completer: WordCompleter = None) -> str:
|
|
86
90
|
if param is not None and default == "":
|
|
87
91
|
default = getenv(param.upper(), default="")
|
|
88
92
|
|
|
@@ -91,7 +95,7 @@ class PromptMixin():
|
|
|
91
95
|
self.params[param] = response
|
|
92
96
|
return response
|
|
93
97
|
|
|
94
|
-
def promptForInt(self, message: str, param: str=None, default: int=None) -> int:
|
|
98
|
+
def promptForInt(self, message: str, param: str = None, default: int = None) -> int:
|
|
95
99
|
if param is not None and default is None:
|
|
96
100
|
default = getenv(param.upper(), default=None)
|
|
97
101
|
|
|
@@ -103,12 +107,12 @@ class PromptMixin():
|
|
|
103
107
|
self.params[param] = str(response)
|
|
104
108
|
return response
|
|
105
109
|
|
|
106
|
-
def promptForListSelect(self, message: str, options: list, param: str=None, default: int=None) -> str:
|
|
110
|
+
def promptForListSelect(self, message: str, options: list, param: str = None, default: int = None) -> str:
|
|
107
111
|
selection = self.promptForInt(message=message, default=default)
|
|
108
112
|
# List indices are 0 origin, so we need to subtract 1 from the selection made to arrive at the correct value
|
|
109
|
-
self.setParam(param, options[selection-1])
|
|
113
|
+
self.setParam(param, options[selection - 1])
|
|
110
114
|
|
|
111
|
-
def promptForFile(self, message: str, mustExist: bool=True, default: str="", envVar: str="") -> None:
|
|
115
|
+
def promptForFile(self, message: str, mustExist: bool = True, default: str = "", envVar: str = "") -> None:
|
|
112
116
|
if default == "" and envVar != "":
|
|
113
117
|
default = getenv(envVar, "")
|
|
114
118
|
if mustExist:
|
|
@@ -116,7 +120,7 @@ class PromptMixin():
|
|
|
116
120
|
else:
|
|
117
121
|
return prompt(masPromptValue(message), default=default)
|
|
118
122
|
|
|
119
|
-
def promptForDir(self, message: str, mustExist: bool=True, default: str="") -> None:
|
|
123
|
+
def promptForDir(self, message: str, mustExist: bool = True, default: str = "") -> None:
|
|
120
124
|
if mustExist:
|
|
121
125
|
return prompt(masPromptValue(message), validator=DirectoryExistsValidator(), validate_while_typing=False, default=default)
|
|
122
126
|
else:
|
mas/cli/gencfg.py
CHANGED
|
@@ -11,14 +11,15 @@
|
|
|
11
11
|
from os import path
|
|
12
12
|
from jinja2 import Template
|
|
13
13
|
|
|
14
|
+
|
|
14
15
|
class ConfigGeneratorMixin():
|
|
15
16
|
def generateJDBCCfg(
|
|
16
17
|
self,
|
|
17
18
|
instanceId: str,
|
|
18
19
|
scope: str,
|
|
19
20
|
destination: str,
|
|
20
|
-
appId: str="",
|
|
21
|
-
workspaceId: str="") -> None:
|
|
21
|
+
appId: str = "",
|
|
22
|
+
workspaceId: str = "") -> None:
|
|
22
23
|
|
|
23
24
|
templateFile = path.join(self.templatesDir, "jdbccfg.yml.j2")
|
|
24
25
|
with open(templateFile) as tFile:
|
mas/cli/install/__init__.py
CHANGED
mas/cli/install/app.py
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import logging
|
|
13
13
|
import logging.handlers
|
|
14
14
|
from sys import exit
|
|
15
|
-
from os import path
|
|
15
|
+
from os import path, getenv
|
|
16
16
|
import re
|
|
17
17
|
|
|
18
18
|
from openshift.dynamic.exceptions import NotFoundError
|
|
@@ -31,12 +31,12 @@ from .settings import InstallSettingsMixin
|
|
|
31
31
|
from .summarizer import InstallSummarizerMixin
|
|
32
32
|
|
|
33
33
|
from mas.cli.validators import (
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
InstanceIDFormatValidator,
|
|
35
|
+
WorkspaceIDFormatValidator,
|
|
36
|
+
WorkspaceNameFormatValidator,
|
|
37
|
+
TimeoutFormatValidator,
|
|
38
|
+
StorageClassValidator,
|
|
39
|
+
OptimizerInstallPlanValidator
|
|
40
40
|
)
|
|
41
41
|
|
|
42
42
|
from mas.devops.ocp import createNamespace, getStorageClass, getStorageClasses
|
|
@@ -116,19 +116,19 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
116
116
|
|
|
117
117
|
def configICR(self):
|
|
118
118
|
if self.devMode:
|
|
119
|
-
self.setParam("mas_icr_cp", "docker-na-public.artifactory.swg-devops.com/wiotp-docker-local")
|
|
120
|
-
self.setParam("mas_icr_cpopen", "docker-na-public.artifactory.swg-devops.com/wiotp-docker-local/cpopen")
|
|
121
|
-
self.setParam("sls_icr_cpopen", "docker-na-public.artifactory.swg-devops.com/wiotp-docker-local/cpopen")
|
|
119
|
+
self.setParam("mas_icr_cp", getenv("MAS_ICR_CP", "docker-na-public.artifactory.swg-devops.com/wiotp-docker-local"))
|
|
120
|
+
self.setParam("mas_icr_cpopen", getenv("MAS_ICR_CPOPEN", "docker-na-public.artifactory.swg-devops.com/wiotp-docker-local/cpopen"))
|
|
121
|
+
self.setParam("sls_icr_cpopen", getenv("SLS_ICR_CPOPEN", "docker-na-public.artifactory.swg-devops.com/wiotp-docker-local/cpopen"))
|
|
122
122
|
else:
|
|
123
|
-
self.setParam("mas_icr_cp", "cp.icr.io/cp")
|
|
124
|
-
self.setParam("mas_icr_cpopen", "icr.io/cpopen")
|
|
125
|
-
self.setParam("sls_icr_cpopen", "icr.io/cpopen")
|
|
123
|
+
self.setParam("mas_icr_cp", getenv("MAS_ICR_CP", "cp.icr.io/cp"))
|
|
124
|
+
self.setParam("mas_icr_cpopen", getenv("MAS_ICR_CPOPEN", "icr.io/cpopen"))
|
|
125
|
+
self.setParam("sls_icr_cpopen", getenv("SLS_ICR_CPOPEN", "icr.io/cpopen"))
|
|
126
126
|
|
|
127
127
|
def configICRCredentials(self):
|
|
128
128
|
self.printH1("Configure IBM Container Registry")
|
|
129
129
|
self.promptForString("IBM entitlement key", "ibm_entitlement_key", isPassword=True)
|
|
130
130
|
if self.devMode:
|
|
131
|
-
self.promptForString("Artifactory username", "artifactory_username"
|
|
131
|
+
self.promptForString("Artifactory username", "artifactory_username")
|
|
132
132
|
self.promptForString("Artifactory token", "artifactory_token", isPassword=True)
|
|
133
133
|
|
|
134
134
|
def configCertManager(self):
|
|
@@ -145,8 +145,8 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
145
145
|
print(tabulate(self.installOptions, headers="keys", tablefmt="simple_grid"))
|
|
146
146
|
catalogSelection = self.promptForInt("Select catalog and release", default=1)
|
|
147
147
|
|
|
148
|
-
self.setParam("mas_catalog_version", self.installOptions[catalogSelection-1]["catalog"])
|
|
149
|
-
self.setParam("mas_channel", self.installOptions[catalogSelection-1]["release"])
|
|
148
|
+
self.setParam("mas_catalog_version", self.installOptions[catalogSelection - 1]["catalog"])
|
|
149
|
+
self.setParam("mas_channel", self.installOptions[catalogSelection - 1]["release"])
|
|
150
150
|
|
|
151
151
|
def configSLS(self) -> None:
|
|
152
152
|
self.printH1("Configure Product License")
|
|
@@ -234,7 +234,7 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
234
234
|
"By default, Maximo Application Suite is configured with guided tour, you can disable this if it not required"
|
|
235
235
|
])
|
|
236
236
|
if not self.yesOrNo("Enable Guided Tour"):
|
|
237
|
-
self.setParam("mas_enable_walkme","false")
|
|
237
|
+
self.setParam("mas_enable_walkme", "false")
|
|
238
238
|
|
|
239
239
|
def configMAS(self):
|
|
240
240
|
self.printH1("Configure MAS Instance")
|
|
@@ -341,7 +341,8 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
341
341
|
self.setParam("mas_manual_cert_mgmt", self.manualCerts)
|
|
342
342
|
if self.getParam("mas_manual_cert_mgmt"):
|
|
343
343
|
self.manualCertsDir = self.promptForDir("Enter the path containing the manual certificates", mustExist=True)
|
|
344
|
-
|
|
344
|
+
else:
|
|
345
|
+
self.manualCertsDir = None
|
|
345
346
|
|
|
346
347
|
def configDNSAndCertsCloudflare(self):
|
|
347
348
|
# User has chosen to set up DNS integration with Cloudflare
|
|
@@ -363,7 +364,7 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
363
364
|
f"{self.getParam('mas_instance_id')}-cloudflare-le-stg",
|
|
364
365
|
""
|
|
365
366
|
]
|
|
366
|
-
self.setParam("mas_cluster_issuer", certIssuerOptions[certIssuer-1])
|
|
367
|
+
self.setParam("mas_cluster_issuer", certIssuerOptions[certIssuer - 1])
|
|
367
368
|
|
|
368
369
|
def configDNSAndCertsCIS(self):
|
|
369
370
|
self.setParam("dns_provider", "cis")
|
|
@@ -384,7 +385,7 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
384
385
|
f"{self.getParam('mas_instance_id')}-cis-le-stg",
|
|
385
386
|
""
|
|
386
387
|
]
|
|
387
|
-
self.setParam("mas_cluster_issuer", certIssuerOptions[certIssuer-1])
|
|
388
|
+
self.setParam("mas_cluster_issuer", certIssuerOptions[certIssuer - 1])
|
|
388
389
|
|
|
389
390
|
def configDNSAndCertsRoute53(self):
|
|
390
391
|
self.setParam("dns_provider", "route53")
|
|
@@ -453,6 +454,10 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
453
454
|
if self.installInspection:
|
|
454
455
|
self.configAppChannel("visualinspection")
|
|
455
456
|
|
|
457
|
+
self.installAiBroker = self.yesOrNo("Install AI Broker")
|
|
458
|
+
if self.installAiBroker:
|
|
459
|
+
self.configAppChannel("aibroker")
|
|
460
|
+
|
|
456
461
|
def configAppChannel(self, appId):
|
|
457
462
|
versions = self.getCompatibleVersions(self.params["mas_channel"], appId)
|
|
458
463
|
if len(versions) == 0:
|
|
@@ -537,8 +542,8 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
537
542
|
|
|
538
543
|
def setIoTStorageClasses(self) -> None:
|
|
539
544
|
if self.installIoT:
|
|
540
|
-
self.setParam("mas_app_settings_iot_fpl_pvc_storage_class",
|
|
541
|
-
self.setParam("mas_app_settings_iot_mqttbroker_pvc_storage_class",
|
|
545
|
+
self.setParam("mas_app_settings_iot_fpl_pvc_storage_class", self.getParam("storage_class_rwo"))
|
|
546
|
+
self.setParam("mas_app_settings_iot_mqttbroker_pvc_storage_class", self.getParam("storage_class_rwo"))
|
|
542
547
|
|
|
543
548
|
def optimizerSettings(self) -> None:
|
|
544
549
|
if self.installOptimizer:
|
|
@@ -568,7 +573,7 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
568
573
|
self.promptForString("COS Provider [ibm/ocs]", "cos_type")
|
|
569
574
|
if self.getParam("cos_type") == "ibm":
|
|
570
575
|
self.promptForString("IBM Cloud API Key", "ibmcloud_apikey", isPassword=True)
|
|
571
|
-
self.promptForString("IBM Cloud Resource Group", "
|
|
576
|
+
self.promptForString("IBM Cloud Resource Group", "ibmcos_resourcegroup")
|
|
572
577
|
|
|
573
578
|
def interactiveMode(self) -> None:
|
|
574
579
|
# Interactive mode
|
|
@@ -600,6 +605,7 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
600
605
|
self.optimizerSettings()
|
|
601
606
|
self.predictSettings()
|
|
602
607
|
self.assistSettings()
|
|
608
|
+
self.aibrokerSettings()
|
|
603
609
|
|
|
604
610
|
# Dependencies
|
|
605
611
|
self.configMongoDb() # Will only do anything if IoT or Manage have been selected for install
|
|
@@ -617,7 +623,7 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
617
623
|
self.interactiveMode = False
|
|
618
624
|
|
|
619
625
|
# Set defaults
|
|
620
|
-
self.storageClassProvider="custom"
|
|
626
|
+
self.storageClassProvider = "custom"
|
|
621
627
|
self.installAssist = False
|
|
622
628
|
self.installIoT = False
|
|
623
629
|
self.installMonitor = False
|
|
@@ -625,6 +631,7 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
625
631
|
self.installPredict = False
|
|
626
632
|
self.installInspection = False
|
|
627
633
|
self.installOptimizer = False
|
|
634
|
+
self.installAiBroker = False
|
|
628
635
|
self.deployCP4D = False
|
|
629
636
|
self.db2SetAffinity = False
|
|
630
637
|
self.db2SetTolerations = False
|
|
@@ -660,6 +667,10 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
660
667
|
"uds_contact_lastname"
|
|
661
668
|
]
|
|
662
669
|
optionalParams = [
|
|
670
|
+
# Pipeline
|
|
671
|
+
"image_pull_policy",
|
|
672
|
+
# OpenShift
|
|
673
|
+
"ocp_ingress_tls_secret_name",
|
|
663
674
|
# MAS
|
|
664
675
|
"mas_catalog_digest",
|
|
665
676
|
"mas_superuser_username",
|
|
@@ -668,9 +679,7 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
668
679
|
"mas_app_settings_server_bundles_size",
|
|
669
680
|
"mas_app_settings_default_jms",
|
|
670
681
|
"mas_app_settings_persistent_volumes_flag",
|
|
671
|
-
"mas_appws_bindings_jdbc_manage",
|
|
672
682
|
"mas_app_settings_demodata",
|
|
673
|
-
"mas_appws_components",
|
|
674
683
|
"mas_app_settings_customization_archive_name",
|
|
675
684
|
"mas_app_settings_customization_archive_url",
|
|
676
685
|
"mas_app_settings_customization_archive_username",
|
|
@@ -686,7 +695,16 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
686
695
|
"mas_app_settings_base_lang",
|
|
687
696
|
"mas_app_settings_secondary_langs",
|
|
688
697
|
"mas_app_settings_server_timezone",
|
|
689
|
-
"
|
|
698
|
+
"mas_appws_bindings_jdbc_manage",
|
|
699
|
+
"mas_appws_components",
|
|
700
|
+
"mas_domain",
|
|
701
|
+
# DNS Providers
|
|
702
|
+
# TODO: Add CloudFlare and Route53 support
|
|
703
|
+
"dns_provider",
|
|
704
|
+
"cis_email",
|
|
705
|
+
"cis_apikey",
|
|
706
|
+
"cis_crn",
|
|
707
|
+
"cis_subdomain",
|
|
690
708
|
# DRO
|
|
691
709
|
"dro_namespace",
|
|
692
710
|
# MongoDb
|
|
@@ -733,7 +751,7 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
733
751
|
"eventstreams_instance_location",
|
|
734
752
|
# COS
|
|
735
753
|
"cos_type",
|
|
736
|
-
"
|
|
754
|
+
"ibmcos_resourcegroup",
|
|
737
755
|
# ECK
|
|
738
756
|
"eck_action",
|
|
739
757
|
"eck_enable_logstash",
|
|
@@ -760,6 +778,29 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
760
778
|
"mas_arcgis_channel",
|
|
761
779
|
# Guided Tour
|
|
762
780
|
"mas_enable_walkme",
|
|
781
|
+
# Aibroker
|
|
782
|
+
"mas_aibroker_storage_provider",
|
|
783
|
+
"mas_aibroker_storage_accesskey",
|
|
784
|
+
"mas_aibroker_storage_secretkey",
|
|
785
|
+
"mas_aibroker_storage_host",
|
|
786
|
+
"mas_aibroker_storage_port",
|
|
787
|
+
"mas_aibroker_storage_ssl",
|
|
788
|
+
"mas_aibroker_storage_region",
|
|
789
|
+
"mas_aibroker_storage_pipelines_bucket",
|
|
790
|
+
"mas_aibroker_storage_tenants_bucket",
|
|
791
|
+
"mas_aibroker_storage_templates_bucket",
|
|
792
|
+
"mas_aibroker_tenant_name",
|
|
793
|
+
"mas_aibroker_watsonxai_apikey",
|
|
794
|
+
"mas_aibroker_watsonxai_url",
|
|
795
|
+
"mas_aibroker_watsonxai_project_id",
|
|
796
|
+
"mas_aibroker_watsonx_action",
|
|
797
|
+
"mas_aibroker_db_host",
|
|
798
|
+
"mas_aibroker_db_port",
|
|
799
|
+
"mas_aibroker_db_user",
|
|
800
|
+
"mas_aibroker_db_database",
|
|
801
|
+
"mas_aibroker_db_secret_name",
|
|
802
|
+
"mas_aibroker_db_secret_key",
|
|
803
|
+
"mas_aibroker_db_secret_value",
|
|
763
804
|
# Special chars
|
|
764
805
|
"mas_special_characters"
|
|
765
806
|
]
|
|
@@ -808,37 +849,44 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
808
849
|
else:
|
|
809
850
|
self.setParam("mas_pod_templates_dir", value)
|
|
810
851
|
|
|
852
|
+
# We check for both None and "" values for the application channel parameters
|
|
853
|
+
# value = None means the parameter wasn't set at all
|
|
854
|
+
# value = "" means the paramerter was explicitly set to "don't install this application"
|
|
811
855
|
elif key == "assist_channel":
|
|
812
|
-
if value is not None:
|
|
856
|
+
if value is not None and value != "":
|
|
813
857
|
self.setParam("mas_app_channel_assist", value)
|
|
814
858
|
self.installAssist = True
|
|
815
859
|
elif key == "iot_channel":
|
|
816
|
-
if value is not None:
|
|
860
|
+
if value is not None and value != "":
|
|
817
861
|
self.setParam("mas_app_channel_iot", value)
|
|
818
862
|
self.installIoT = True
|
|
819
863
|
elif key == "monitor_channel":
|
|
820
|
-
if value is not None:
|
|
864
|
+
if value is not None and value != "":
|
|
821
865
|
self.setParam("mas_app_channel_monitor", value)
|
|
822
866
|
self.installMonitor = True
|
|
823
867
|
elif key == "manage_channel":
|
|
824
|
-
if value is not None:
|
|
868
|
+
if value is not None and value != "":
|
|
825
869
|
self.setParam("mas_app_channel_manage", value)
|
|
826
870
|
self.installManage = True
|
|
827
871
|
elif key == "predict_channel":
|
|
828
|
-
if value is not None:
|
|
872
|
+
if value is not None and value != "":
|
|
829
873
|
self.setParam("mas_app_channel_predict", value)
|
|
830
874
|
self.installPredict = True
|
|
831
875
|
self.deployCP4D = True
|
|
832
876
|
elif key == "visualinspection_channel":
|
|
833
|
-
if value is not None:
|
|
877
|
+
if value is not None and value != "":
|
|
834
878
|
self.setParam("mas_app_channel_visualinspection", value)
|
|
835
879
|
self.installInspection = True
|
|
880
|
+
elif key == "aibroker_channel":
|
|
881
|
+
if value is not None and value != "":
|
|
882
|
+
self.setParam("mas_app_channel_aibroker", value)
|
|
883
|
+
self.installAiBroker = True
|
|
836
884
|
elif key == "optimizer_channel":
|
|
837
|
-
if value is not None:
|
|
885
|
+
if value is not None and value != "":
|
|
838
886
|
self.setParam("mas_app_channel_optimizer", value)
|
|
839
887
|
self.installOptimizer = True
|
|
840
888
|
elif key == "optimizer_plan":
|
|
841
|
-
if value is not None:
|
|
889
|
+
if value is not None and value != "":
|
|
842
890
|
self.setParam("mas_app_plan_optimizer", value)
|
|
843
891
|
|
|
844
892
|
# Manage advanced settings that need extra processing
|
|
@@ -858,9 +906,9 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
858
906
|
self.fatalError(f"{key} must be set")
|
|
859
907
|
self.pipelineStorageClass = value
|
|
860
908
|
elif key == "license_file":
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
909
|
+
if value is None:
|
|
910
|
+
self.fatalError(f"{key} must be set")
|
|
911
|
+
self.slsLicenseFileLocal = value
|
|
864
912
|
|
|
865
913
|
elif key.startswith("approval_"):
|
|
866
914
|
if key not in self.approvals:
|
|
@@ -876,7 +924,7 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
876
924
|
self.approvals[key]["maxRetries"] = int(valueParts[1])
|
|
877
925
|
self.approvals[key]["retryDelay"] = int(valueParts[2])
|
|
878
926
|
self.approvals[key]["ignoreFailure"] = bool(valueParts[3])
|
|
879
|
-
except:
|
|
927
|
+
except ValueError:
|
|
880
928
|
self.fatalError(f"Unsupported format for {key} ({value}). Expected string:int:int:boolean")
|
|
881
929
|
|
|
882
930
|
# Arguments that we don't need to do anything with
|
|
@@ -886,9 +934,10 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
886
934
|
elif key == "manual_certificates":
|
|
887
935
|
if value is not None:
|
|
888
936
|
self.setParam("mas_manual_cert_mgmt", True)
|
|
889
|
-
self.
|
|
937
|
+
self.manualCertsDir = value
|
|
890
938
|
else:
|
|
891
939
|
self.setParam("mas_manual_cert_mgmt", False)
|
|
940
|
+
self.manualCertsDir = None
|
|
892
941
|
|
|
893
942
|
# Fail if there's any arguments we don't know how to handle
|
|
894
943
|
else:
|
|
@@ -938,7 +987,8 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
938
987
|
"monitor": "9.0.3",
|
|
939
988
|
"optimizer": "9.0.3",
|
|
940
989
|
"predict": "9.0.2",
|
|
941
|
-
"inspection": "9.0.3"
|
|
990
|
+
"inspection": "9.0.3",
|
|
991
|
+
"aibroker": "9.0.2"
|
|
942
992
|
},
|
|
943
993
|
{
|
|
944
994
|
"#": 2,
|
|
@@ -965,7 +1015,7 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
965
1015
|
"optimizer": "8.4.10",
|
|
966
1016
|
"predict": "8.8.3",
|
|
967
1017
|
"inspection": "8.8.4"
|
|
968
|
-
},
|
|
1018
|
+
},
|
|
969
1019
|
{
|
|
970
1020
|
"#": 4,
|
|
971
1021
|
"catalog": "v9-240827-amd64",
|
|
@@ -1120,7 +1170,7 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
1120
1170
|
|
|
1121
1171
|
with Halo(text='Validating OpenShift Pipelines installation', spinner=self.spinner) as h:
|
|
1122
1172
|
installOpenShiftPipelines(self.dynamicClient)
|
|
1123
|
-
h.stop_and_persist(symbol=self.successIcon, text=
|
|
1173
|
+
h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator is installed and ready to use")
|
|
1124
1174
|
|
|
1125
1175
|
with Halo(text=f'Preparing namespace ({pipelinesNamespace})', spinner=self.spinner) as h:
|
|
1126
1176
|
createNamespace(self.dynamicClient, pipelinesNamespace)
|
|
@@ -1144,9 +1194,9 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
|
|
|
1144
1194
|
|
|
1145
1195
|
h.stop_and_persist(symbol=self.successIcon, text=f"Namespace is ready ({pipelinesNamespace})")
|
|
1146
1196
|
|
|
1147
|
-
with Halo(text=
|
|
1197
|
+
with Halo(text='Testing availability of MAS CLI image in cluster', spinner=self.spinner) as h:
|
|
1148
1198
|
testCLI()
|
|
1149
|
-
h.stop_and_persist(symbol=self.successIcon, text=
|
|
1199
|
+
h.stop_and_persist(symbol=self.successIcon, text="MAS CLI image deployment test completed")
|
|
1150
1200
|
|
|
1151
1201
|
with Halo(text=f'Installing latest Tekton definitions (v{self.version})', spinner=self.spinner) as h:
|
|
1152
1202
|
updateTektonDefinitions(pipelinesNamespace, self.tektonDefsPath)
|