diff --git a/core/src/main/java/oracle/weblogic/deploy/util/FileUtils.java b/core/src/main/java/oracle/weblogic/deploy/util/FileUtils.java
index 790558067..c12f57f5b 100644
--- a/core/src/main/java/oracle/weblogic/deploy/util/FileUtils.java
+++ b/core/src/main/java/oracle/weblogic/deploy/util/FileUtils.java
@@ -618,7 +618,7 @@ public static byte[] readInputStreamToByteArray(InputStream input) throws IOExce
}
public static File writeInputStreamToFile(InputStream input, String fileName) throws IOException {
- File tmpdir = new File(System.getProperty("java.io.tmpdir"));
+ File tmpdir = getTmpDir();
File file = new File(tmpdir, fileName);
try (FileOutputStream fos = new FileOutputStream(file)) {
byte[] byteArray = FileUtils.readInputStreamToByteArray(input);
@@ -627,6 +627,9 @@ public static File writeInputStreamToFile(InputStream input, String fileName) th
return file;
}
+ public static File getTmpDir() {
+ return new File(System.getProperty("java.io.tmpdir"));
+ }
public static void extractZipFileContent(WLSDeployArchive archiveFile, String zipEntry, String extractPath) {
final String METHOD = "extractZipFileContent";
diff --git a/core/src/main/java/oracle/weblogic/deploy/util/WLSDeployArchive.java b/core/src/main/java/oracle/weblogic/deploy/util/WLSDeployArchive.java
index aca36b397..88317a059 100644
--- a/core/src/main/java/oracle/weblogic/deploy/util/WLSDeployArchive.java
+++ b/core/src/main/java/oracle/weblogic/deploy/util/WLSDeployArchive.java
@@ -615,6 +615,15 @@ public String addApplication(String appPath) throws WLSDeployArchiveIOException
return newName;
}
+ public String replaceApplication(String appPath, String tempFile) throws WLSDeployArchiveIOException {
+ final String METHOD = "replaceApplication";
+ LOGGER.entering(CLASS, METHOD, appPath);
+ getZipFile().removeZipEntry(appPath);
+ String newName = addApplication(tempFile);
+ LOGGER.exiting(CLASS, METHOD, newName);
+ return newName;
+ }
+
public String addApplicationFolder(String appName, String appPath)
throws WLSDeployArchiveIOException {
final String METHOD = "addApplicationFolder";
diff --git a/core/src/main/python/discover.py b/core/src/main/python/discover.py
index a8f59cdc6..6d5a98703 100644
--- a/core/src/main/python/discover.py
+++ b/core/src/main/python/discover.py
@@ -219,13 +219,14 @@ def __process_domain_home(arg_map, wlst_mode):
arg_map[CommandLineArgUtil.DOMAIN_HOME_SWITCH] = full_path
-def __discover(model_context, aliases, credential_injector, helper):
+def __discover(model_context, aliases, credential_injector, helper, extra_tokens):
"""
Populate the model from the domain.
:param model_context: the model context
:param aliases: aliases instance for discover
:param credential_injector: credential injector instance
:param helper: wlst_helper instance
+ :param extra_tokens: dictionary to store non-credential tokens during credential search
:return: the fully-populated model
:raises DiscoverException: if an error occurred while discover the domain
"""
@@ -233,7 +234,6 @@ def __discover(model_context, aliases, credential_injector, helper):
model = Model()
base_location = LocationContext()
__connect_to_domain(model_context, helper)
-
try:
_add_domain_name(base_location, aliases, helper)
DomainInfoDiscoverer(model_context, model.get_model_domain_info(), base_location, wlst_mode=__wlst_mode,
@@ -243,7 +243,8 @@ def __discover(model_context, aliases, credential_injector, helper):
ResourcesDiscoverer(model_context, model.get_model_resources(), base_location, wlst_mode=__wlst_mode,
aliases=aliases, credential_injector=credential_injector).discover()
DeploymentsDiscoverer(model_context, model.get_model_app_deployments(), base_location, wlst_mode=__wlst_mode,
- aliases=aliases, credential_injector=credential_injector).discover()
+ aliases=aliases, credential_injector=credential_injector,
+ extra_tokens=extra_tokens).discover()
__discover_multi_tenant(model, model_context, base_location, aliases, credential_injector)
except AliasException, ae:
wls_version = WebLogicHelper(__logger).get_actual_weblogic_version()
@@ -448,7 +449,7 @@ def __persist_model(model, model_context):
__logger.exiting(class_name=_class_name, method_name=_method_name)
-def __check_and_customize_model(model, model_context, aliases, credential_injector):
+def __check_and_customize_model(model, model_context, aliases, credential_injector, extra_tokens):
"""
Customize the model dictionary before persisting. Validate the model after customization for informational
purposes. Any validation errors will not stop the discovered model to be persisted.
@@ -456,6 +457,7 @@ def __check_and_customize_model(model, model_context, aliases, credential_inject
:param model_context: configuration from command-line
:param aliases: used for validation if model changes are made
:param credential_injector: injector created to collect and tokenize credentials, possibly None
+ :param extra_tokens: dictionary to handle non-credential tokenized arguments
"""
_method_name = '__check_and_customize_model'
__logger.entering(class_name=_class_name, method_name=_method_name)
@@ -492,9 +494,12 @@ def __check_and_customize_model(model, model_context, aliases, credential_inject
# Apply the injectors specified in model_variable_injector.json, or in the target configuration.
# Include the variable mappings that were collected in credential_cache.
+
variable_injector = VariableInjector(_program_name, model.get_model(), model_context,
WebLogicHelper(__logger).get_actual_weblogic_version(), credential_cache)
+ variable_injector.add_to_cache(dictionary=extra_tokens)
+
inserted, variable_model, variable_file_name = variable_injector.inject_variables_keyword_file()
if inserted:
@@ -589,10 +594,11 @@ def main(model_context):
else:
__logger.info('WLSDPLY-06024', class_name=_class_name, method_name=_method_name)
+ extra_tokens = {}
try:
- model = __discover(model_context, aliases, credential_injector, helper)
+ model = __discover(model_context, aliases, credential_injector, helper, extra_tokens)
- model = __check_and_customize_model(model, model_context, aliases, credential_injector)
+ model = __check_and_customize_model(model, model_context, aliases, credential_injector, extra_tokens)
__remote_report(model_context)
except DiscoverException, ex:
diff --git a/core/src/main/python/wlsdeploy/aliases/model_constants.py b/core/src/main/python/wlsdeploy/aliases/model_constants.py
index 57ebb37b2..00a3cde90 100644
--- a/core/src/main/python/wlsdeploy/aliases/model_constants.py
+++ b/core/src/main/python/wlsdeploy/aliases/model_constants.py
@@ -192,6 +192,7 @@
MESSAGE_LOGGING_PARAMS = 'MessageLoggingParams'
MESSAGING_BRIDGE = 'MessagingBridge'
METHOD = 'Method'
+MODULE_TYPE = 'ModuleType'
MULTICAST = 'Multicast'
MULTICAST_ADDRESS = 'MulticastAddress'
MULTICAST_PORT = 'MulticastPort'
diff --git a/core/src/main/python/wlsdeploy/tool/discover/deployments_discoverer.py b/core/src/main/python/wlsdeploy/tool/discover/deployments_discoverer.py
index 65b9ec1c1..28ef1f7e0 100644
--- a/core/src/main/python/wlsdeploy/tool/discover/deployments_discoverer.py
+++ b/core/src/main/python/wlsdeploy/tool/discover/deployments_discoverer.py
@@ -4,14 +4,22 @@
"""
import os
+from java.io import BufferedReader
+from java.io import BufferedWriter
from java.io import File
+from java.io import FileReader
+from java.io import FileWriter
from java.lang import IllegalArgumentException
+from java.lang import StringBuilder
+from java.util.regex import Pattern
from oracle.weblogic.deploy.util import PyOrderedDict as OrderedDict
+from oracle.weblogic.deploy.util import FileUtils
from oracle.weblogic.deploy.util import StringUtils
from oracle.weblogic.deploy.util import WLSDeployArchiveIOException
from oracle.weblogic.deploy.util import WLSDeployArchive
+from wlsdeploy.aliases.alias_constants import PASSWORD_TOKEN
from wlsdeploy.aliases import model_constants
from wlsdeploy.aliases.location_context import LocationContext
from wlsdeploy.aliases.wlst_modes import WlstModes
@@ -19,6 +27,7 @@
from wlsdeploy.logging.platform_logger import PlatformLogger
from wlsdeploy.tool.discover import discoverer
from wlsdeploy.tool.discover.discoverer import Discoverer
+from wlsdeploy.util import dictionary_utils
from wlsdeploy.util import path_utils
_class_name = 'DeploymentsDiscoverer'
@@ -32,9 +41,10 @@ class DeploymentsDiscoverer(Discoverer):
"""
def __init__(self, model_context, deployments_dictionary, base_location,
- wlst_mode=WlstModes.OFFLINE, aliases=None, credential_injector=None):
+ wlst_mode=WlstModes.OFFLINE, aliases=None, credential_injector=None, extra_tokens=None):
Discoverer.__init__(self, model_context, base_location, wlst_mode, aliases, credential_injector)
self._dictionary = deployments_dictionary
+ self._extra_tokens = extra_tokens
def discover(self):
"""
@@ -241,6 +251,7 @@ def _add_application_to_archive(self, application_name, application_dict):
"""
_method_name = 'add_application_to_archive'
_logger.entering(application_name, class_name=_class_name, method_name=_method_name)
+
archive_file = self._model_context.get_archive_file()
if model_constants.SOURCE_PATH in application_dict:
if model_constants.PLAN_DIR in application_dict and \
@@ -265,6 +276,11 @@ def _add_application_to_archive(self, application_name, application_dict):
method_name=_method_name)
try:
new_source_name = archive_file.addApplication(file_name_path)
+ module_type = dictionary_utils.get_dictionary_element(application_dict,
+ model_constants.MODULE_TYPE)
+ if module_type == 'jdbc':
+ self._jdbc_password_fix(new_source_name)
+
except IllegalArgumentException, iae:
self._disconnect_target(application_name, application_dict, iae.getLocalizedMessage())
except WLSDeployArchiveIOException, wioe:
@@ -325,6 +341,78 @@ def _create_app_folder(self, application_name, application_dict):
_logger.exiting(class_name=_class_name, method_name=_method_name)
+ def _jdbc_password_fix(self, source_name):
+ """
+ This will look for password and userid in the jdbc standalone xml and
+ replace with either fix password token or a token in the xml and variable file.
+ It extracts the jdbc xml from the archive and then replaces it with the updated file.
+ :param source_name: Name of the path and file for the standalone xml file
+ """
+ _method_name = '_jdbc_password_fix'
+ _logger.entering(source_name, class_name=_class_name, method_name=_method_name)
+ archive_file = self._model_context.get_archive_file()
+ tmp_dir = FileUtils.getTmpDir();
+ temp_file = FileUtils.createTempDirectory(tmp_dir, 'jdbc-xml')
+ jdbc_file = archive_file.extractFile(source_name, temp_file)
+ jdbc_out = FileUtils.createTempDirectory(tmp_dir, 'jdbc-out')
+ jdbc_out = archive_file.extractFile(source_name, jdbc_out)
+ bis = BufferedReader(FileReader(jdbc_file))
+ bos = BufferedWriter(FileWriter(jdbc_out))
+ cache = StringBuilder()
+ while bis.ready():
+ cache.append(bis.readLine()).append("\n")
+ bis.close()
+ pattern = Pattern.compile("(\s?)user(\s?)")
+ matcher = pattern.matcher(cache.toString())
+ end = -1
+ if matcher.find():
+ end = matcher.end()
+ result = cache.toString()
+ if end >= 0:
+ pattern = Pattern.compile("(.+?)")
+ matcher = pattern.matcher(result[end:])
+ matcher.find()
+ username = matcher.group()
+ username = username[len(''):len(username) - len('')]
+ pattern = Pattern.compile(matcher.group())
+ matcher = pattern.matcher(cache.toString())
+ result = matcher.replaceFirst(self._get_pass_replacement(jdbc_file, '-user:username',
+ 'value', username=username))
+
+ pattern = Pattern.compile('(.+?)')
+ matcher = pattern.matcher(result)
+ result = matcher.replaceFirst(self._get_pass_replacement(jdbc_file, '-user:password', 'password-encrypted'))
+
+ pattern = Pattern.compile('(\s*)(.+?)(\s*)')
+ matcher = pattern.matcher(result)
+ matcher.find()
+ result = matcher.replaceFirst(self._get_pass_replacement(jdbc_file, '-url', 'url',
+ properties=matcher.group(2)))
+
+ pattern = Pattern.compile('(.+?)')
+ matcher = pattern.matcher(result)
+ result = matcher.replaceFirst(self._get_pass_replacement(jdbc_file, '-ons-pass-encrypt:password',
+ 'ons-wallet-password-encrypted'))
+ bos.write(result)
+ bos.close()
+ archive_file.replaceApplication(source_name, jdbc_out)
+ _logger.exiting(class_name=_class_name, method_name=_method_name)
+
+ def _get_pass_replacement(self, jdbc_file, name, type, properties=None, username=''):
+ if self._credential_injector is not None:
+ head, tail = os.path.split(jdbc_file)
+ token = tail[:len(tail) - len('.xml')]
+ token = token + name
+ if properties is not None:
+ self._extra_tokens[token] = properties
+ result = self._credential_injector.get_property_token(None, token)
+ else:
+ result = self._credential_injector.injection_out_of_model(token, username)
+ else:
+ result = PASSWORD_TOKEN
+ result = '<' + type + '>' + result + '' + type + '>'
+ return result
+
def _test_app_folder(self, source_path, plan_dir):
app_folder = False
app_dir = File(source_path).getParent()
diff --git a/core/src/main/python/wlsdeploy/tool/util/credential_injector.py b/core/src/main/python/wlsdeploy/tool/util/credential_injector.py
index ba3de4976..c30a54732 100644
--- a/core/src/main/python/wlsdeploy/tool/util/credential_injector.py
+++ b/core/src/main/python/wlsdeploy/tool/util/credential_injector.py
@@ -81,6 +81,8 @@ def __init__(self, program_name, model, model_context, version=None, variable_di
VariableInjector.__init__(self, program_name, model, model_context, version=version,
variable_dictionary=variable_dictionary)
self._model_context = model_context
+ self._no_filter_keys_cache = []
+ self._no_filter_keys_cache.append(self.NO_FILTER_KEYS)
def check_and_tokenize(self, model_dict, attribute, location):
"""
@@ -138,6 +140,22 @@ def check_and_tokenize(self, model_dict, attribute, location):
assigns.append('%s=%s' % (key, properties[key]))
model_dict[attribute] = split_value.join(assigns)
+ def injection_out_of_model(self, token, username=''):
+ """
+ This is for tokenizing variables that are not in the model but need to be in the variable file
+ :param token: name for cache to create a token for
+ :param username: usernames appear as part of property value
+ :return: tokenized name
+ """
+ _method_name = 'injection_out_of_model'
+ _logger.entering(token, class_name=_class_name, method_name=_method_name)
+ result = self.get_variable_token(None, token)
+ self.add_to_cache(token_name=token, token_value=username)
+
+ self._no_filter_keys_cache.append(token)
+ _logger.exiting(class_name=_class_name, method_name=_method_name, result=result)
+ return result
+
def get_variable_name(self, attribute_location, attribute, suffix=None):
"""
Override method to possibly create secret token names instead of property names.
@@ -191,6 +209,9 @@ def get_variable_token(self, attribute, variable_name):
else:
return VariableInjector.get_variable_token(self, attribute, variable_name)
+ def get_property_token(self, attribute, variable_name):
+ return VariableInjector.get_variable_token(self, attribute, variable_name)
+
def _check_tokenized(self, attribute_value):
"""
Override to return true if target uses credentials and the value is formatted like @@SECRET:xyz:abc@@.
@@ -222,7 +243,7 @@ def filter_unused_credentials(self, model_dictionary):
cache_keys = self.get_variable_cache().keys()
for key in cache_keys:
- if key in self.NO_FILTER_KEYS:
+ if key in self._no_filter_keys_cache:
continue
if credentials_method == SECRETS_METHOD:
diff --git a/core/src/main/python/wlsdeploy/util/target_configuration_helper.py b/core/src/main/python/wlsdeploy/util/target_configuration_helper.py
index 9d697207a..bfc7c4f0a 100644
--- a/core/src/main/python/wlsdeploy/util/target_configuration_helper.py
+++ b/core/src/main/python/wlsdeploy/util/target_configuration_helper.py
@@ -33,6 +33,15 @@
WEBLOGIC_CREDENTIALS_SECRET_NAME = 'weblogic-credentials'
WEBLOGIC_CREDENTIALS_SECRET_SUFFIX = '-' + WEBLOGIC_CREDENTIALS_SECRET_NAME
+JDBC_CREDENTIALS_SECRET_USER_NAME = 'standalone-jdbc.xml.user'
+JDBC_CREDENTIALS_SECRET_USER_SUFFIX = '-' + JDBC_CREDENTIALS_SECRET_USER_NAME
+
+JDBC_CREDENTIALS_SECRET_PASS_NAME = 'standalone-jdbc.xml.pass.encrypt'
+JDBC_CREDENTIALS_SECRET_PASS_SUFFIX = '-' + JDBC_CREDENTIALS_SECRET_PASS_NAME
+
+JDBC_CREDENTIALS_SECRET_ONS_PASS_NAME = 'standalone-jdbc.xml.ons.pass.encrypt'
+JDBC_CREDENTIALS_SECRET_ONS_PASS_SUFFIX = '-' + JDBC_CREDENTIALS_SECRET_ONS_PASS_NAME
+
RUNTIME_ENCRYPTION_SECRET_NAME = 'runtime-encryption-secret'
RUNTIME_ENCRYPTION_SECRET_SUFFIX = '-' + RUNTIME_ENCRYPTION_SECRET_NAME
@@ -133,6 +142,7 @@ def _prepare_k8s_secrets(model_context, token_dictionary, model_dictionary):
for secret_name in secret_names:
secret_keys = secret_map[secret_name]
user_name = dictionary_utils.get_element(secret_keys, SECRET_USERNAME_KEY)
+
if user_name is None:
secrets.append(_build_secret_hash(secret_name, None, PASSWORD_TAG))
else:
diff --git a/core/src/main/resources/oracle/weblogic/deploy/k8s/create_k8s_secrets.sh b/core/src/main/resources/oracle/weblogic/deploy/k8s/create_k8s_secrets.sh
index c78f950a0..83ca1f055 100644
--- a/core/src/main/resources/oracle/weblogic/deploy/k8s/create_k8s_secrets.sh
+++ b/core/src/main/resources/oracle/weblogic/deploy/k8s/create_k8s_secrets.sh
@@ -34,7 +34,7 @@ function create_paired_k8s_secret {
{{#comments}}
# {{{comment}}}
{{/comments}}
-create_paired_k8s_secret {{{secretName}}} {{{user}}} {{{password}}}
+create_paired_k8s_secret {{{secretName}}} "{{{user}}}" {{{password}}}
{{/pairedSecrets}}
{{#secrets}}