mas-cli 9.5.0__py3-none-any.whl → 10.0.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 +82 -65
- mas/cli/displayMixins.py +110 -0
- mas/cli/gencfg.py +65 -0
- mas/cli/install/__init__.py +9 -0
- mas/cli/install/argParser.py +792 -0
- mas/cli/install/settings/__init__.py +21 -0
- mas/cli/install/settings/additionalConfigs.py +150 -0
- mas/cli/install/settings/db2Settings.py +173 -0
- mas/cli/install/settings/kafkaSettings.py +103 -0
- mas/cli/install/settings/manageSettings.py +218 -0
- mas/cli/install/settings/turbonomicSettings.py +25 -0
- mas/cli/install/summarizer.py +328 -0
- mas/cli/templates/ibm-mas-tekton.yaml +10813 -0
- mas/cli/templates/jdbccfg.yml.j2 +52 -0
- mas/cli/templates/pod-templates/best-effort/ibm-data-dictionary-assetdatadictionary.yml +26 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-bascfg.yml +56 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-coreidp.yml +21 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-actions.yml +28 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-auth.yml +32 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-datapower.yml +12 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-devops.yml +14 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-dm.yml +22 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-dsc.yml +40 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-edgeconfig.yml +10 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-fpl.yml +24 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-guardian.yml +20 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-iot.yml +10 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-mbgx.yml +18 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-mfgx.yml +14 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-monitor.yml +18 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-orgmgmt.yml +48 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-provision.yml +28 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-registry.yml +26 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-state.yml +40 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-iot-webui.yml +22 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-healthextaccelerator.yml +13 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-healthextworkspace.yml +10 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-imagestitching.yml +10 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-manageaccelerators.yml +10 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-manageapp.yml +46 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-manageworkspace.yml +48 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-manage-slackproxy.yml +10 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-pushnotificationcfg.yml +13 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-scimcfg.yml +14 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-slscfg.yml +10 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-smtpcfg.yml +10 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-suite.yml +136 -0
- mas/cli/templates/pod-templates/best-effort/ibm-mas-visualinspection.yml +34 -0
- mas/cli/templates/pod-templates/best-effort/ibm-sls-licenseservice.yml +10 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-data-dictionary-assetdatadictionary.yml +56 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-bascfg.yml +140 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-coreidp.yml +45 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-actions.yml +70 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-auth.yml +80 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-datapower.yml +24 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-devops.yml +26 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-dm.yml +52 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-dsc.yml +106 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-edgeconfig.yml +16 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-fpl.yml +62 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-guardian.yml +44 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-iot.yml +16 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-mbgx.yml +42 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-mfgx.yml +32 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-monitor.yml +42 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-orgmgmt.yml +126 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-provision.yml +70 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-registry.yml +62 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-state.yml +106 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-iot-webui.yml +52 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-healthextaccelerator.yml +28 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-healthextworkspace.yml +18 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-imagestitching.yml +16 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-manageaccelerators.yml +16 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-manageapp.yml +106 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-manageworkspace.yml +126 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-manage-slackproxy.yml +16 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-pushnotificationcfg.yml +25 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-scimcfg.yml +26 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-slscfg.yml +16 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-smtpcfg.yml +16 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-suite.yml +340 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-mas-visualinspection.yml +76 -0
- mas/cli/templates/pod-templates/guaranteed/ibm-sls-licenseservice.yml +16 -0
- mas/cli/templates/pod-templates/saas-essentials/ibm-mas-visualinspection.yml +46 -0
- mas/cli/validators.py +126 -0
- mas_cli-10.0.0.data/scripts/mas-install +978 -0
- {mas_cli-9.5.0.data → mas_cli-10.0.0.data}/scripts/mas-uninstall +11 -8
- {mas_cli-9.5.0.data → mas_cli-10.0.0.data}/scripts/mas-upgrade +6 -4
- {mas_cli-9.5.0.dist-info → mas_cli-10.0.0.dist-info}/METADATA +2 -1
- mas_cli-10.0.0.dist-info/RECORD +94 -0
- mas_cli-9.5.0.dist-info/RECORD +0 -8
- {mas_cli-9.5.0.dist-info → mas_cli-10.0.0.dist-info}/WHEEL +0 -0
- {mas_cli-9.5.0.dist-info → mas_cli-10.0.0.dist-info}/top_level.txt +0 -0
mas/cli/__init__.py
CHANGED
mas/cli/cli.py
CHANGED
|
@@ -7,9 +7,11 @@
|
|
|
7
7
|
# http://www.eclipse.org/legal/epl-v10.html
|
|
8
8
|
#
|
|
9
9
|
# *****************************************************************************
|
|
10
|
+
|
|
10
11
|
from argparse import RawTextHelpFormatter
|
|
11
12
|
from shutil import which
|
|
12
13
|
from os import path
|
|
14
|
+
from sys import exit
|
|
13
15
|
|
|
14
16
|
# Use of the openshift client rather than the kubernetes client allows us access to "apply"
|
|
15
17
|
from openshift import dynamic
|
|
@@ -17,62 +19,17 @@ from kubernetes import config
|
|
|
17
19
|
from kubernetes.client import api_client
|
|
18
20
|
|
|
19
21
|
from prompt_toolkit import prompt, print_formatted_text, HTML
|
|
20
|
-
from prompt_toolkit.validation import Validator, ValidationError
|
|
21
|
-
|
|
22
|
-
# Available named colours in prompt_toolkit
|
|
23
|
-
# -----------------------------------------------------------------------------
|
|
24
|
-
# AliceBlue AntiqueWhite Aqua Aquamarine Azure Beige Bisque Black BlanchedAlmond Blue BlueViolet
|
|
25
|
-
# Brown BurlyWood CadetBlue Chartreuse Chocolate Coral CornflowerBlue Cornsilk Crimson Cyan
|
|
26
|
-
# DarkBlue DarkCyan DarkGoldenRod DarkGray DarkGreen DarkGrey DarkKhaki DarkMagenta DarkOliveGreen
|
|
27
|
-
# DarkOrange DarkOrchid DarkRed DarkSalmon DarkSeaGreen DarkSlateBlue DarkSlateGray DarkSlateGrey
|
|
28
|
-
# DarkTurquoise DarkViolet DeepPink DeepSkyBlue DimGray DimGrey DodgerBlue FireBrick FloralWhite
|
|
29
|
-
# ForestGreen Fuchsia Gainsboro GhostWhite Gold GoldenRod Gray Green GreenYellow Grey HoneyDew
|
|
30
|
-
# HotPink IndianRed Indigo Ivory Khaki Lavender LavenderBlush LawnGreen LemonChiffon LightBlue
|
|
31
|
-
# LightCoral LightCyan LightGoldenRodYellow LightGray LightGreen LightGrey LightPink LightSalmon
|
|
32
|
-
# LightSeaGreen LightSkyBlue LightSlateGray LightSlateGrey LightSteelBlue LightYellow Lime
|
|
33
|
-
# LimeGreen Linen Magenta Maroon MediumAquaMarine MediumBlue MediumOrchid MediumPurple MediumSeaGreen
|
|
34
|
-
# MediumSlateBlue MediumSpringGreen MediumTurquoise MediumVioletRed MidnightBlue MintCream MistyRose
|
|
35
|
-
# Moccasin NavajoWhite Navy OldLace Olive OliveDrab Orange OrangeRed Orchid PaleGoldenRod PaleGreen
|
|
36
|
-
# PaleTurquoise PaleVioletRed PapayaWhip PeachPuff Peru Pink Plum PowderBlue Purple RebeccaPurple
|
|
37
|
-
# Red RosyBrown RoyalBlue SaddleBrown Salmon SandyBrown SeaGreen SeaShell Sienna Silver SkyBlue
|
|
38
|
-
# SlateBlue SlateGray SlateGrey Snow SpringGreen SteelBlue Tan Teal Thistle Tomato Turquoise
|
|
39
|
-
# Violet Wheat White WhiteSmoke Yellow YellowGreen
|
|
40
|
-
|
|
41
|
-
from mas.cli import __version__ as packageVersion
|
|
42
|
-
from mas.devops.ocp import connect
|
|
43
|
-
from mas.devops.mas import verifyMasInstance
|
|
44
22
|
|
|
45
|
-
from
|
|
23
|
+
from .validators import YesNoValidator
|
|
46
24
|
|
|
47
|
-
import
|
|
25
|
+
from . import __version__ as packageVersion
|
|
26
|
+
from .displayMixins import PrintMixin, PromptMixin
|
|
27
|
+
from mas.devops.ocp import connect, isSNO
|
|
48
28
|
|
|
29
|
+
import logging
|
|
49
30
|
logger = logging.getLogger(__name__)
|
|
50
31
|
|
|
51
32
|
|
|
52
|
-
class InstanceIDValidator(Validator):
|
|
53
|
-
def validate(self, document):
|
|
54
|
-
"""
|
|
55
|
-
Validate that a MAS instance ID exists on the target cluster
|
|
56
|
-
"""
|
|
57
|
-
instanceId = document.text
|
|
58
|
-
|
|
59
|
-
dynClient = dynamic.DynamicClient(
|
|
60
|
-
api_client.ApiClient(configuration=config.load_kube_config())
|
|
61
|
-
)
|
|
62
|
-
if not verifyMasInstance(dynClient, instanceId):
|
|
63
|
-
raise ValidationError(message='Not a valid MAS instance ID on this cluster', cursor_position=len(instanceId))
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
class YesNoValidator(Validator):
|
|
67
|
-
def validate(self, document):
|
|
68
|
-
"""
|
|
69
|
-
Validate that a response is understandable as a yes/no response
|
|
70
|
-
"""
|
|
71
|
-
response = document.text
|
|
72
|
-
if response.lower() not in ["y", "n", "yes", "no"]:
|
|
73
|
-
raise ValidationError(message='Enter a valid response: y(es), n(o)', cursor_position=len(response))
|
|
74
|
-
|
|
75
|
-
|
|
76
33
|
def getHelpFormatter(formatter=RawTextHelpFormatter, w=160, h=50):
|
|
77
34
|
"""
|
|
78
35
|
Return a wider HelpFormatter, if possible.
|
|
@@ -88,7 +45,7 @@ def getHelpFormatter(formatter=RawTextHelpFormatter, w=160, h=50):
|
|
|
88
45
|
return formatter
|
|
89
46
|
|
|
90
47
|
|
|
91
|
-
class BaseApp(
|
|
48
|
+
class BaseApp(PrintMixin, PromptMixin):
|
|
92
49
|
def __init__(self):
|
|
93
50
|
# Set up a log formatter
|
|
94
51
|
chFormatter = logging.Formatter('%(asctime)-25s' + ' %(levelname)-8s %(message)s')
|
|
@@ -107,9 +64,48 @@ class BaseApp(object):
|
|
|
107
64
|
|
|
108
65
|
self.version = packageVersion
|
|
109
66
|
self.h1count = 0
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
67
|
+
self.h2count = 0
|
|
68
|
+
|
|
69
|
+
self.localConfigDir = None
|
|
70
|
+
self.templatesDir = path.join(path.abspath(path.dirname(__file__)), "templates")
|
|
71
|
+
self.tektonDefsPath = path.join(self.templatesDir, "ibm-mas-tekton.yaml")
|
|
72
|
+
|
|
73
|
+
# These dicts will hold the additional-configs and pod-templates secrets
|
|
74
|
+
self.additionalConfigsSecret = None
|
|
75
|
+
self.podTemplatesSecret = None
|
|
76
|
+
|
|
77
|
+
self._isSNO = None
|
|
78
|
+
|
|
79
|
+
self.compatibilityMatrix = {
|
|
80
|
+
"9.0.x": {
|
|
81
|
+
"assist": ["9.0.x", "8.8.x"],
|
|
82
|
+
"iot": ["9.0.x", "8.8.x"],
|
|
83
|
+
"manage": ["9.0.x", "8.7.x"],
|
|
84
|
+
"monitor": ["9.0.x", "8.11.x"],
|
|
85
|
+
"optimizer": ["9.0.x", "8.5.x"],
|
|
86
|
+
"predict": ["9.0.x", "8.9.x"],
|
|
87
|
+
"visualinspection": ["9.0.x", "8.9.x"]
|
|
88
|
+
},
|
|
89
|
+
"8.11.x": {
|
|
90
|
+
"assist": ["8.8.x", "8.7.x"],
|
|
91
|
+
"iot": ["8.8.x", "8.7.x"],
|
|
92
|
+
"manage": ["8.7.x", "8.6.x"],
|
|
93
|
+
"monitor": ["8.11.x", "8.10.x"],
|
|
94
|
+
"optimizer": ["8.5.x", "8.4.x"],
|
|
95
|
+
"predict": ["8.9.x", "8.8.x"],
|
|
96
|
+
"visualinspection": ["8.9.x", "8.8.x"]
|
|
97
|
+
},
|
|
98
|
+
"8.10.x": {
|
|
99
|
+
"assist": ["8.7.x", "8.6.x"],
|
|
100
|
+
"hputilities": ["8.6.x", "8.5.x"],
|
|
101
|
+
"iot": ["8.7.x", "8.6.x"],
|
|
102
|
+
"manage": ["8.6.x", "8.5.x"],
|
|
103
|
+
"monitor": ["8.10.x", "8.9.x"],
|
|
104
|
+
"optimizer": ["8.4.x", "8.3.x"],
|
|
105
|
+
"predict": ["8.8.x", "8.7.x"],
|
|
106
|
+
"visualinspection": ["8.8.x", "8.7.x"]
|
|
107
|
+
}
|
|
108
|
+
}
|
|
113
109
|
|
|
114
110
|
self.spinner = {
|
|
115
111
|
"interval": 80,
|
|
@@ -120,21 +116,42 @@ class BaseApp(object):
|
|
|
120
116
|
|
|
121
117
|
self._dynClient = None
|
|
122
118
|
|
|
123
|
-
self.printTitle(f"
|
|
124
|
-
print_formatted_text(HTML("Powered by <DarkGoldenRod><u>https://github.com/ibm-mas/ansible-devops/</u></DarkGoldenRod> and <DarkGoldenRod><u>https://tekton.dev/</u></DarkGoldenRod
|
|
125
|
-
|
|
119
|
+
self.printTitle(f"\nIBM Maximo Application Suite Admin CLI v{self.version}")
|
|
120
|
+
print_formatted_text(HTML("Powered by <DarkGoldenRod><u>https://github.com/ibm-mas/ansible-devops/</u></DarkGoldenRod> and <DarkGoldenRod><u>https://tekton.dev/</u></DarkGoldenRod>\n"))
|
|
126
121
|
if which("kubectl") is None:
|
|
127
122
|
logger.error("Could not find kubectl on the path")
|
|
128
123
|
print_formatted_text(HTML("\n<Red>Error: Could not find kubectl on the path, see <u>https://kubernetes.io/docs/tasks/tools/#kubectl</u> for installation instructions</Red>\n"))
|
|
129
124
|
exit(1)
|
|
130
125
|
|
|
131
|
-
def
|
|
132
|
-
|
|
126
|
+
def getCompatibleVersions(self, coreChannel: str, appId: str) -> list:
|
|
127
|
+
if coreChannel in self.compatibilityMatrix:
|
|
128
|
+
return self.compatibilityMatrix[coreChannel][appId]
|
|
129
|
+
else:
|
|
130
|
+
return []
|
|
133
131
|
|
|
134
|
-
def
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
132
|
+
def fatalError(self, message: str, exception: Exception=None) -> None:
|
|
133
|
+
if exception is not None:
|
|
134
|
+
print_formatted_text(HTML(f"<Red>Fatal Exception: {message.replace(' & ', ' & ')}: {exception}</Red>"))
|
|
135
|
+
else:
|
|
136
|
+
print_formatted_text(HTML(f"<Red>Fatal Error: {message.replace(' & ', ' & ')}</Red>"))
|
|
137
|
+
exit(1)
|
|
138
|
+
|
|
139
|
+
def isSNO(self):
|
|
140
|
+
if self._isSNO is None:
|
|
141
|
+
self._isSNO = isSNO(self.dynamicClient)
|
|
142
|
+
return self._isSNO
|
|
143
|
+
|
|
144
|
+
def setParam(self, param: str, value: str):
|
|
145
|
+
self.params[param] = value
|
|
146
|
+
|
|
147
|
+
def getParam(self, param: str):
|
|
148
|
+
"""
|
|
149
|
+
Returns the value of a parameter, or an empty string is the parameter has not set at all or is set to None
|
|
150
|
+
"""
|
|
151
|
+
if param in self.params and self.params[param] is not None:
|
|
152
|
+
return self.params[param]
|
|
153
|
+
else:
|
|
154
|
+
return ""
|
|
138
155
|
|
|
139
156
|
@property
|
|
140
157
|
def dynamicClient(self):
|
|
@@ -158,7 +175,7 @@ class BaseApp(object):
|
|
|
158
175
|
logger.warning(f"Error: Unable to connect to OpenShift Container Platform: {e}")
|
|
159
176
|
return None
|
|
160
177
|
|
|
161
|
-
def connect(self
|
|
178
|
+
def connect(self):
|
|
162
179
|
promptForNewServer = False
|
|
163
180
|
self.reloadDynamicClient()
|
|
164
181
|
if self._dynClient is not None:
|
|
@@ -167,7 +184,7 @@ class BaseApp(object):
|
|
|
167
184
|
consoleRoute = routesAPI.get(name="console", namespace="openshift-console")
|
|
168
185
|
print_formatted_text(HTML(f"Already connected to OCP Cluster:\n <u><Orange>https://{consoleRoute.spec.host}</Orange></u>"))
|
|
169
186
|
print()
|
|
170
|
-
if not noConfirm:
|
|
187
|
+
if not self.noConfirm:
|
|
171
188
|
# We are already connected to a cluster, but prompt the user if they want to use this connection
|
|
172
189
|
continueWithExistingCluster = prompt(HTML('<Yellow>Proceed with this cluster?</Yellow> '), validator=YesNoValidator(), validate_while_typing=False)
|
|
173
190
|
promptForNewServer = continueWithExistingCluster in ["n", "no"]
|
mas/cli/displayMixins.py
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
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, getenv
|
|
12
|
+
from prompt_toolkit import prompt, print_formatted_text, HTML
|
|
13
|
+
from prompt_toolkit.validation import Validator
|
|
14
|
+
|
|
15
|
+
from .validators import YesNoValidator, FileExistsValidator, DirectoryExistsValidator
|
|
16
|
+
|
|
17
|
+
import logging
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
H1COLOR="SkyBlue"
|
|
21
|
+
H2COLOR="SkyBlue"
|
|
22
|
+
DESCRIPTIONCOLOR="LightSlateGrey"
|
|
23
|
+
SUMMARYCOLOR="SkyBlue"
|
|
24
|
+
UNDEFINEDPARAMCOLOR="LightSlateGrey"
|
|
25
|
+
PROMPTCOLOR="Yellow"
|
|
26
|
+
|
|
27
|
+
class PrintMixin():
|
|
28
|
+
def printTitle(self, message):
|
|
29
|
+
print_formatted_text(HTML(f"<b><u>{message.replace(' & ', ' & ')}</u></b>"))
|
|
30
|
+
|
|
31
|
+
def printH1(self, message):
|
|
32
|
+
self.h1count += 1
|
|
33
|
+
self.h2count = 0
|
|
34
|
+
print()
|
|
35
|
+
print_formatted_text(HTML(f"<u><{H1COLOR}>{self.h1count}) {message.replace(' & ', ' & ')}</{H1COLOR}></u>"))
|
|
36
|
+
|
|
37
|
+
def printH2(self, message):
|
|
38
|
+
self.h2count += 1
|
|
39
|
+
print()
|
|
40
|
+
print_formatted_text(HTML(f"<u><{H2COLOR}>{self.h1count}.{self.h2count}) {message.replace(' & ', ' & ')}</{H2COLOR}></u>"))
|
|
41
|
+
|
|
42
|
+
def printDescription(self, content: list) -> None:
|
|
43
|
+
content[0] = f"<{DESCRIPTIONCOLOR}>{content[0]}"
|
|
44
|
+
content[len(content) - 1] = f"{content[len(content) - 1]}</{DESCRIPTIONCOLOR}>"
|
|
45
|
+
print_formatted_text(HTML("\n".join(content)))
|
|
46
|
+
|
|
47
|
+
def printSummary(self, title: str, value: str) -> None:
|
|
48
|
+
titleLength = len(title)
|
|
49
|
+
message = f"{title} {'.' * (40 - titleLength)} {value}"
|
|
50
|
+
print_formatted_text(HTML(f" <{SUMMARYCOLOR}>{message.replace(' & ', ' & ')}</{SUMMARYCOLOR}>"))
|
|
51
|
+
|
|
52
|
+
def printParamSummary(self, message: str, param: str) -> None:
|
|
53
|
+
if self.getParam(param) is None:
|
|
54
|
+
self.printSummary(message, f"<{UNDEFINEDPARAMCOLOR}>Undefined</{UNDEFINEDPARAMCOLOR}>")
|
|
55
|
+
elif self.getParam(param) == "":
|
|
56
|
+
self.printSummary(message, f"<{UNDEFINEDPARAMCOLOR}>Default</{UNDEFINEDPARAMCOLOR}>")
|
|
57
|
+
else:
|
|
58
|
+
self.printSummary(message, self.getParam(param))
|
|
59
|
+
|
|
60
|
+
def masPromptYesOrNo(message):
|
|
61
|
+
return HTML(f"<{PROMPTCOLOR}>{message.replace(' & ', ' & ')}? [y/n]</{PROMPTCOLOR}> ")
|
|
62
|
+
|
|
63
|
+
def masPromptValue(message):
|
|
64
|
+
return HTML(f"<{PROMPTCOLOR}>{message.replace(' & ', ' & ')}</{PROMPTCOLOR}> ")
|
|
65
|
+
|
|
66
|
+
class PromptMixin():
|
|
67
|
+
def yesOrNo(self, message: str, param: str=None) -> bool:
|
|
68
|
+
response = prompt(masPromptYesOrNo(message), validator=YesNoValidator(), validate_while_typing=False)
|
|
69
|
+
responseAsBool = response.lower() in ["y", "yes"]
|
|
70
|
+
if param is not None:
|
|
71
|
+
self.params[param] = "true" if responseAsBool else "false"
|
|
72
|
+
return responseAsBool
|
|
73
|
+
|
|
74
|
+
def promptForString(self, message: str, param: str=None, default: str="", isPassword: bool=False, validator: Validator=None) -> str:
|
|
75
|
+
if param is not None and default == "":
|
|
76
|
+
default = getenv(param.upper(), default="")
|
|
77
|
+
|
|
78
|
+
response = prompt(masPromptValue(message), is_password=isPassword, default=default, validator=validator, validate_while_typing=False)
|
|
79
|
+
if param is not None:
|
|
80
|
+
self.params[param] = response
|
|
81
|
+
return response
|
|
82
|
+
|
|
83
|
+
def promptForInt(self, message: str, param: str=None, default: int=None) -> int:
|
|
84
|
+
if param is not None and default is None:
|
|
85
|
+
default = getenv(param.upper(), default=None)
|
|
86
|
+
|
|
87
|
+
if default is None:
|
|
88
|
+
response = int(prompt(masPromptValue(message)))
|
|
89
|
+
else:
|
|
90
|
+
response = int(prompt(masPromptValue(message), default=str(default)))
|
|
91
|
+
if param is not None:
|
|
92
|
+
self.params[param] = str(response)
|
|
93
|
+
return response
|
|
94
|
+
|
|
95
|
+
def promptForListSelect(self, message: str, options: list, param: str=None, default: int=None) -> str:
|
|
96
|
+
selection = self.promptForInt(message=message, default=default)
|
|
97
|
+
# List indices are 0 origin, so we need to subtract 1 from the selection made to arrive at the correct value
|
|
98
|
+
self.setParam(param, options[selection-1])
|
|
99
|
+
|
|
100
|
+
def promptForFile(self, message: str, mustExist: bool=True, default: str="") -> None:
|
|
101
|
+
if mustExist:
|
|
102
|
+
return prompt(masPromptValue(message), validator=FileExistsValidator(), validate_while_typing=False, default=default)
|
|
103
|
+
else:
|
|
104
|
+
return prompt(masPromptValue(message), default=default)
|
|
105
|
+
|
|
106
|
+
def promptForDir(self, message: str, mustExist: bool=True, default: str="") -> None:
|
|
107
|
+
if mustExist:
|
|
108
|
+
return prompt(masPromptValue(message), validator=DirectoryExistsValidator(), validate_while_typing=False, default=default)
|
|
109
|
+
else:
|
|
110
|
+
return prompt(masPromptValue(message), default=default)
|
mas/cli/gencfg.py
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
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 jinja2 import Template
|
|
13
|
+
|
|
14
|
+
class ConfigGeneratorMixin():
|
|
15
|
+
def generateJDBCCfg(
|
|
16
|
+
self,
|
|
17
|
+
instanceId: str,
|
|
18
|
+
scope: str,
|
|
19
|
+
destination: str,
|
|
20
|
+
appId: str="",
|
|
21
|
+
workspaceId: str="") -> None:
|
|
22
|
+
|
|
23
|
+
templateFile = path.join(self.templatesDir, "jdbccfg.yml.j2")
|
|
24
|
+
with open(templateFile) as tFile:
|
|
25
|
+
template = Template(tFile.read())
|
|
26
|
+
|
|
27
|
+
if scope == "workspace-application":
|
|
28
|
+
assert appId != ""
|
|
29
|
+
assert workspaceId != ""
|
|
30
|
+
|
|
31
|
+
name = self.promptForString("Configuration Display Name")
|
|
32
|
+
url = self.promptForString("JDBC Connection String")
|
|
33
|
+
|
|
34
|
+
username = self.promptForString("JDBC Username")
|
|
35
|
+
password = self.promptForString("JDBC Password", isPassword=True)
|
|
36
|
+
|
|
37
|
+
sslEnabled = self.yesOrNo("Enable SSL Connection")
|
|
38
|
+
|
|
39
|
+
if sslEnabled:
|
|
40
|
+
sslCertFile = self.promptForFile("Path to certificate file")
|
|
41
|
+
with open(sslCertFile) as cFile:
|
|
42
|
+
certLocalFileContent = cFile.read()
|
|
43
|
+
else:
|
|
44
|
+
certLocalFileContent = ""
|
|
45
|
+
|
|
46
|
+
cfg = template.render(
|
|
47
|
+
scope=scope,
|
|
48
|
+
|
|
49
|
+
mas_instance_id=instanceId,
|
|
50
|
+
mas_workspace_id=workspaceId,
|
|
51
|
+
mas_application_id=appId,
|
|
52
|
+
|
|
53
|
+
cfg_display_name=name,
|
|
54
|
+
|
|
55
|
+
jdbc_url=url,
|
|
56
|
+
jdbc_username=username,
|
|
57
|
+
jdbc_password=password,
|
|
58
|
+
|
|
59
|
+
jdbc_ssl_enabled=sslEnabled,
|
|
60
|
+
jdbc_cert_local_file_content=certLocalFileContent
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
with open(destination, 'w') as f:
|
|
64
|
+
f.write(cfg)
|
|
65
|
+
f.write('\n')
|
|
@@ -0,0 +1,9 @@
|
|
|
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
|
+
# *****************************************************************************
|