mas-cli 11.4.0__py3-none-any.whl → 11.5.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 CHANGED
@@ -8,4 +8,4 @@
8
8
  #
9
9
  # *****************************************************************************
10
10
 
11
- __version__ = "11.4.0" # Python module compatible semver
11
+ __version__ = "11.5.0" # Python module compatible semver
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.4.0"
110
+ self.version = "11.5.0"
112
111
  self.h1count = 0
113
112
  self.h2count = 0
114
113
 
@@ -223,7 +222,7 @@ class BaseApp(PrintMixin, PromptMixin):
223
222
  else:
224
223
  return []
225
224
 
226
- def fatalError(self, message: str, exception: Exception=None) -> None:
225
+ def fatalError(self, message: str, exception: Exception = None) -> None:
227
226
  if exception is not None:
228
227
  logger.error(message)
229
228
  logger.exception(exception, stack_info=True)
@@ -289,8 +288,7 @@ class BaseApp(PrintMixin, PromptMixin):
289
288
  print()
290
289
  if not self.noConfirm:
291
290
  # We are already connected to a cluster, but prompt the user if they want to use this connection
292
- continueWithExistingCluster = prompt(HTML('<Yellow>Proceed with this cluster?</Yellow> '), validator=YesNoValidator(), validate_while_typing=False)
293
- promptForNewServer = continueWithExistingCluster in ["n", "no"]
291
+ promptForNewServer = not self.yesOrNo("Proceed with this cluster?")
294
292
  except Exception as e:
295
293
  # We are already connected to a cluster, but the connection is not valid so prompt for connection details
296
294
  logger.debug("Failed looking up OpenShift Console route to verify connection")
@@ -311,7 +309,7 @@ class BaseApp(PrintMixin, PromptMixin):
311
309
  print_formatted_text(HTML("<Red>Unable to connect to cluster. See log file for details</Red>"))
312
310
  exit(1)
313
311
 
314
- def initializeApprovalConfigMap(self, namespace: str, id: str, key: str=None, maxRetries: int=100, delay: int=300, ignoreFailure: bool=True) -> None:
312
+ def initializeApprovalConfigMap(self, namespace: str, id: str, key: str = None, maxRetries: int = 100, delay: int = 300, ignoreFailure: bool = True) -> None:
315
313
  """
316
314
  Set key = None if you don't want approval workflow enabled
317
315
  """
mas/cli/displayMixins.py CHANGED
@@ -8,7 +8,7 @@
8
8
  #
9
9
  # *****************************************************************************
10
10
 
11
- from os import path, getenv
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(' & ', ' &amp; ')}? [y/n]</{PROMPTCOLOR}> ")
72
74
 
75
+
73
76
  def masPromptValue(message):
74
77
  return HTML(f"<{PROMPTCOLOR}>{message.replace(' & ', ' &amp; ')}</{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:
@@ -8,4 +8,4 @@
8
8
  #
9
9
  # *****************************************************************************
10
10
 
11
- from ..cli import BaseApp
11
+ from ..cli import BaseApp # noqa: F401
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
- InstanceIDFormatValidator,
35
- WorkspaceIDFormatValidator,
36
- WorkspaceNameFormatValidator,
37
- TimeoutFormatValidator,
38
- StorageClassValidator,
39
- OptimizerInstallPlanValidator
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", isPassword=True)
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")
@@ -363,7 +363,7 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
363
363
  f"{self.getParam('mas_instance_id')}-cloudflare-le-stg",
364
364
  ""
365
365
  ]
366
- self.setParam("mas_cluster_issuer", certIssuerOptions[certIssuer-1])
366
+ self.setParam("mas_cluster_issuer", certIssuerOptions[certIssuer - 1])
367
367
 
368
368
  def configDNSAndCertsCIS(self):
369
369
  self.setParam("dns_provider", "cis")
@@ -384,7 +384,7 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
384
384
  f"{self.getParam('mas_instance_id')}-cis-le-stg",
385
385
  ""
386
386
  ]
387
- self.setParam("mas_cluster_issuer", certIssuerOptions[certIssuer-1])
387
+ self.setParam("mas_cluster_issuer", certIssuerOptions[certIssuer - 1])
388
388
 
389
389
  def configDNSAndCertsRoute53(self):
390
390
  self.setParam("dns_provider", "route53")
@@ -537,8 +537,8 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
537
537
 
538
538
  def setIoTStorageClasses(self) -> None:
539
539
  if self.installIoT:
540
- self.setParam("mas_app_settings_iot_fpl_pvc_storage_class", self.getParam("storage_class_rwo"))
541
- self.setParam("mas_app_settings_iot_mqttbroker_pvc_storage_class", self.getParam("storage_class_rwo"))
540
+ self.setParam("mas_app_settings_iot_fpl_pvc_storage_class", self.getParam("storage_class_rwo"))
541
+ self.setParam("mas_app_settings_iot_mqttbroker_pvc_storage_class", self.getParam("storage_class_rwo"))
542
542
 
543
543
  def optimizerSettings(self) -> None:
544
544
  if self.installOptimizer:
@@ -617,7 +617,7 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
617
617
  self.interactiveMode = False
618
618
 
619
619
  # Set defaults
620
- self.storageClassProvider="custom"
620
+ self.storageClassProvider = "custom"
621
621
  self.installAssist = False
622
622
  self.installIoT = False
623
623
  self.installMonitor = False
@@ -858,9 +858,9 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
858
858
  self.fatalError(f"{key} must be set")
859
859
  self.pipelineStorageClass = value
860
860
  elif key == "license_file":
861
- if value is None:
862
- self.fatalError(f"{key} must be set")
863
- self.slsLicenseFileLocal = value
861
+ if value is None:
862
+ self.fatalError(f"{key} must be set")
863
+ self.slsLicenseFileLocal = value
864
864
 
865
865
  elif key.startswith("approval_"):
866
866
  if key not in self.approvals:
@@ -876,7 +876,7 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
876
876
  self.approvals[key]["maxRetries"] = int(valueParts[1])
877
877
  self.approvals[key]["retryDelay"] = int(valueParts[2])
878
878
  self.approvals[key]["ignoreFailure"] = bool(valueParts[3])
879
- except:
879
+ except ValueError:
880
880
  self.fatalError(f"Unsupported format for {key} ({value}). Expected string:int:int:boolean")
881
881
 
882
882
  # Arguments that we don't need to do anything with
@@ -965,7 +965,7 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
965
965
  "optimizer": "8.4.10",
966
966
  "predict": "8.8.3",
967
967
  "inspection": "8.8.4"
968
- },
968
+ },
969
969
  {
970
970
  "#": 4,
971
971
  "catalog": "v9-240827-amd64",
@@ -1120,7 +1120,7 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
1120
1120
 
1121
1121
  with Halo(text='Validating OpenShift Pipelines installation', spinner=self.spinner) as h:
1122
1122
  installOpenShiftPipelines(self.dynamicClient)
1123
- h.stop_and_persist(symbol=self.successIcon, text=f"OpenShift Pipelines Operator is installed and ready to use")
1123
+ h.stop_and_persist(symbol=self.successIcon, text="OpenShift Pipelines Operator is installed and ready to use")
1124
1124
 
1125
1125
  with Halo(text=f'Preparing namespace ({pipelinesNamespace})', spinner=self.spinner) as h:
1126
1126
  createNamespace(self.dynamicClient, pipelinesNamespace)
@@ -1144,9 +1144,9 @@ class InstallApp(BaseApp, InstallSettingsMixin, InstallSummarizerMixin, ConfigGe
1144
1144
 
1145
1145
  h.stop_and_persist(symbol=self.successIcon, text=f"Namespace is ready ({pipelinesNamespace})")
1146
1146
 
1147
- with Halo(text=f'Testing availability of MAS CLI image in cluster', spinner=self.spinner) as h:
1147
+ with Halo(text='Testing availability of MAS CLI image in cluster', spinner=self.spinner) as h:
1148
1148
  testCLI()
1149
- h.stop_and_persist(symbol=self.successIcon, text=f"MAS CLI image deployment test completed")
1149
+ h.stop_and_persist(symbol=self.successIcon, text="MAS CLI image deployment test completed")
1150
1150
 
1151
1151
  with Halo(text=f'Installing latest Tekton definitions (v{self.version})', spinner=self.spinner) as h:
1152
1152
  updateTektonDefinitions(pipelinesNamespace, self.tektonDefsPath)