Skip to content

Commit 0c405c6

Browse files
Jira#wdt 418 encrypt multiple models (#647)
* Encrypt multiple model files and one variable file * add details to the encryptModel shell scripts
1 parent 3c2a4ad commit 0c405c6

File tree

8 files changed

+322
-56
lines changed

8 files changed

+322
-56
lines changed

core/src/main/python/encrypt.py

Lines changed: 39 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from wlsdeploy.logging.platform_logger import PlatformLogger
2929
from wlsdeploy.tool.encrypt import encryption_utils
3030
from wlsdeploy.tool.util.alias_helper import AliasHelper
31+
from wlsdeploy.util import cla_utils
3132
from wlsdeploy.util import getcreds
3233
from wlsdeploy.util import variables as variable_helper
3334
from wlsdeploy.util.cla_utils import CommandLineArgUtil
@@ -62,6 +63,7 @@ def __process_args(args):
6263
_method_name = '__process_args'
6364

6465
cla_util = CommandLineArgUtil(_program_name, __required_arguments, __optional_arguments)
66+
cla_util.set_allow_multiple_models(True)
6567
argument_map = cla_util.process_args(args)
6668

6769
__validate_mode_args(argument_map)
@@ -92,17 +94,8 @@ def __validate_mode_args(optional_arg_map):
9294
"""
9395
_method_name = '__validate_mode_args'
9496

95-
if CommandLineArgUtil.MODEL_FILE_SWITCH in optional_arg_map:
96-
model_file_name = optional_arg_map[CommandLineArgUtil.MODEL_FILE_SWITCH]
97-
try:
98-
FileUtils.validateExistingFile(model_file_name)
99-
except IllegalArgumentException, iae:
100-
ex = exception_helper.create_cla_exception('WLSDPLY-20006', _program_name, model_file_name,
101-
iae.getLocalizedMessage(), error=iae)
102-
ex.setExitCode(CommandLineArgUtil.ARG_VALIDATION_ERROR_EXIT_CODE)
103-
__logger.throwing(ex, class_name=_class_name, method_name=_method_name)
104-
raise ex
105-
elif CommandLineArgUtil.ENCRYPT_MANUAL_SWITCH not in optional_arg_map:
97+
if CommandLineArgUtil.MODEL_FILE_SWITCH not in optional_arg_map \
98+
and CommandLineArgUtil.ENCRYPT_MANUAL_SWITCH not in optional_arg_map:
10699
ex = exception_helper.create_cla_exception('WLSDPLY-04202', _program_name, CommandLineArgUtil.MODEL_FILE_SWITCH,
107100
CommandLineArgUtil.ENCRYPT_MANUAL_SWITCH)
108101
ex.setExitCode(CommandLineArgUtil.USAGE_ERROR_EXIT_CODE)
@@ -152,13 +145,15 @@ def __encrypt_model_and_variables(model_context):
152145
"""
153146
_method_name = '__encrypt_model_and_variables'
154147

155-
model_file = model_context.get_model_file()
156-
try:
157-
model = FileToPython(model_file, True).parse()
158-
except TranslateException, te:
159-
__logger.severe('WLSDPLY-04206', _program_name, model_file, te.getLocalizedMessage(), error=te,
160-
class_name=_class_name, method_name=_method_name)
161-
return CommandLineArgUtil.PROG_ERROR_EXIT_CODE
148+
model_files = cla_utils.get_model_files(model_context.get_model_file())
149+
models = dict()
150+
for model_file in model_files:
151+
try:
152+
models[model_file] = FileToPython(model_file, True).parse()
153+
except TranslateException, te:
154+
__logger.severe('WLSDPLY-04206', _program_name, model_file, te.getLocalizedMessage(), error=te,
155+
class_name=_class_name, method_name=_method_name)
156+
return CommandLineArgUtil.PROG_ERROR_EXIT_CODE
162157

163158
variable_file = model_context.get_variable_file()
164159
variables = None
@@ -173,35 +168,36 @@ def __encrypt_model_and_variables(model_context):
173168
aliases = Aliases(model_context, wlst_mode=WlstModes.OFFLINE)
174169
alias_helper = AliasHelper(aliases, __logger, ExceptionType.ENCRYPTION)
175170

176-
try:
177-
passphrase = model_context.get_encryption_passphrase()
178-
model_change_count, variable_change_count = \
179-
encryption_utils.encrypt_model_dictionary(passphrase, model, alias_helper, variables)
180-
except EncryptionException, ee:
181-
__logger.severe('WLSDPLY-04208', _program_name, ee.getLocalizedMessage(), error=ee,
182-
class_name=_class_name, method_name=_method_name)
183-
return CommandLineArgUtil.PROG_ERROR_EXIT_CODE
184-
185-
if variable_change_count > 0:
171+
for model_file, model in models.iteritems():
186172
try:
187-
variable_helper.write_variables(_program_name, variables, variable_file)
188-
__logger.info('WLSDPLY-04209', _program_name, variable_change_count, variable_file,
189-
class_name=_class_name, method_name=_method_name)
190-
except VariableException, ve:
191-
__logger.severe('WLSDPLY-20007', _program_name, variable_file, ve.getLocalizedMessage(), error=ve,
173+
passphrase = model_context.get_encryption_passphrase()
174+
model_change_count, variable_change_count = \
175+
encryption_utils.encrypt_model_dictionary(passphrase, model, alias_helper, variables)
176+
except EncryptionException, ee:
177+
__logger.severe('WLSDPLY-04208', _program_name, ee.getLocalizedMessage(), error=ee,
192178
class_name=_class_name, method_name=_method_name)
193179
return CommandLineArgUtil.PROG_ERROR_EXIT_CODE
194180

195-
if model_change_count > 0:
196-
try:
197-
model_writer = PythonToFile(model)
198-
model_writer.write_to_file(model_file)
199-
__logger.info('WLSDPLY-04210', _program_name, model_change_count, model_file,
200-
class_name=_class_name, method_name=_method_name)
201-
except TranslateException, te:
202-
__logger.severe('WLSDPLY-04211', _program_name, model_file, te.getLocalizedMessage(), error=te,
203-
class_name=_class_name, method_name=_method_name)
204-
return CommandLineArgUtil.PROG_ERROR_EXIT_CODE
181+
if variable_change_count > 0:
182+
try:
183+
variable_helper.write_variables(_program_name, variables, variable_file)
184+
__logger.info('WLSDPLY-04209', _program_name, variable_change_count, variable_file,
185+
class_name=_class_name, method_name=_method_name)
186+
except VariableException, ve:
187+
__logger.severe('WLSDPLY-20007', _program_name, variable_file, ve.getLocalizedMessage(), error=ve,
188+
class_name=_class_name, method_name=_method_name)
189+
return CommandLineArgUtil.PROG_ERROR_EXIT_CODE
190+
191+
if model_change_count > 0:
192+
try:
193+
model_writer = PythonToFile(model)
194+
model_writer.write_to_file(model_file)
195+
__logger.info('WLSDPLY-04210', _program_name, model_change_count, model_file,
196+
class_name=_class_name, method_name=_method_name)
197+
except TranslateException, te:
198+
__logger.severe('WLSDPLY-04211', _program_name, model_file, te.getLocalizedMessage(), error=te,
199+
class_name=_class_name, method_name=_method_name)
200+
return CommandLineArgUtil.PROG_ERROR_EXIT_CODE
205201

206202
return CommandLineArgUtil.PROG_OK_EXIT_CODE
207203

core/src/main/python/wlsdeploy/tool/encrypt/encryption_utils.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def __init__(self, passphrase, alias_helper, variables=None):
3434
self.alias_helper = alias_helper
3535
self.variables = variables
3636
self.model_changes = 0
37-
self.variables_changed = []
37+
self.variable_changes = 0
3838

3939
def encrypt_model_dictionary(self, model_dict):
4040
"""
@@ -66,7 +66,7 @@ def encrypt_model_dictionary(self, model_dict):
6666
location = LocationContext()
6767
self._encrypt_nodes(location, deployments_nodes, top_folder_names)
6868

69-
return self.model_changes, len(self.variables_changed)
69+
return self.model_changes, self.variable_changes
7070

7171
def _encrypt_info_nodes(self, info_nodes):
7272
"""
@@ -173,16 +173,19 @@ def _encrypt_variable_value(self, folder_name, field_name, var_name):
173173
if self.variables is None:
174174
return
175175

176-
# this variable may have been encrypted for another attribute
177-
if var_name in self.variables_changed:
178-
return
179-
176+
# Do not encrypt already encrypted to match model encryption: Don't encrypt encrypted value
180177
if var_name in self.variables:
181178
var_value = self.variables[var_name]
182179
if len(var_value) > 0:
180+
181+
# don't encrypt an already encrypted variable. Matches logic in model
182+
if EncryptionUtils.isEncryptedString(var_value):
183+
self._logger.fine('WLSDPLY-04109', folder_name, field_name, var_name)
184+
return
185+
183186
encrypted_value = EncryptionUtils.encryptString(var_value, String(self.passphrase).toCharArray())
184187
self.variables[var_name] = encrypted_value
185-
self.variables_changed.append(var_name)
188+
self.variable_changes += 1
186189
self._logger.fine('WLSDPLY-04106', folder_name, field_name, var_name,
187190
class_name=self._class_name, method_name=_method_name)
188191
else:

core/src/main/resources/oracle/weblogic/deploy/messages/wlsdeploy_rb.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ WLSDPLY-04105=The value for password field {1} from folder {0} unexpectedly had
375375
WLSDPLY-04106=Encrypted the value of variable {1} referenced from field {0} from folder {2}
376376
WLSDPLY-04107=Unable to find variable {0} definition that was used for field {1} from folder {2}
377377
WLSDPLY-04108=The provider {0} at location {1} was not recognized, and will not be encrypted
378+
WLSDPLY-04109=The field {1} from folder {0} is already encrypted for variable property {2}
378379

379380
# encrypt.py
380381
WLSDPLY-04200=Enter the password to encrypt

core/src/test/python/encryption_test.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ class EncryptionTestCase(unittest.TestCase):
2323
_oracle_home = None
2424

2525
_src_model_file_wo_variables = os.path.join(_resources_dir, 'encryption-test.yaml')
26+
_src_model_file_wo_variables_for_multi = os.path.join(_resources_dir, 'encryption-test-multiple.yaml')
2627
_src_model_file_w_variables = os.path.join(_resources_dir, 'encryption-test-variables.yaml')
28+
_src_model_file_w_variables_multi = os.path.join(_resources_dir, 'encryption-test-variables-multiple.yaml')
2729
_src_variable_file = os.path.join(_resources_dir, 'encryption-test-variables.properties')
2830

2931
_target_model_test1 = os.path.join(_execution_dir, 'model-test1.yaml')
@@ -33,6 +35,7 @@ class EncryptionTestCase(unittest.TestCase):
3335

3436
_passphrase = 'my dog is a rottweiler'
3537
_unencrypted_password = 'welcome1'
38+
_unencrypted_password_second = 'another1'
3639

3740
def setUp(self):
3841
if not os.path.exists(self._execution_dir):
@@ -178,3 +181,115 @@ def testIndirectEncryptionVariables(self):
178181
self.assertEquals(str(String(_decrypted_ds2_pass)), self._unencrypted_password)
179182
return
180183

184+
def testMultipleModelDirectEncryption(self):
185+
copy2(self._src_model_file_wo_variables, self._target_model_test1)
186+
copy2(self._src_model_file_wo_variables_for_multi, self._target_model_test2)
187+
188+
args = list()
189+
args.append('encrypt') # dummy arg for args[0] to get arg padding right
190+
args.append(CommandLineArgUtil.ORACLE_HOME_SWITCH)
191+
args.append(self._oracle_home)
192+
args.append(CommandLineArgUtil.MODEL_FILE_SWITCH)
193+
args.append(self._target_model_test1 + ',' + self._target_model_test2)
194+
args.append(CommandLineArgUtil.PASSPHRASE_SWITCH)
195+
args.append(self._passphrase)
196+
exit_code = encrypt._process_request(args)
197+
self.assertEquals(exit_code, 0)
198+
199+
model1 = FileToPython(self._target_model_test1).parse()
200+
model2 = FileToPython(self._target_model_test2).parse()
201+
passphrase_array = String(self._passphrase).toCharArray()
202+
203+
admin_pass = model1['domainInfo']['AdminPassword']
204+
self.assertEquals(admin_pass.startswith('{AES}'), True)
205+
_decrypted_admin_pass = EncryptionUtils.decryptString(admin_pass, passphrase_array)
206+
self.assertEquals(str(String(_decrypted_admin_pass)), self._unencrypted_password)
207+
208+
admin_pass = model2['domainInfo']['AdminPassword']
209+
self.assertEquals(admin_pass.startswith('{AES}'), True)
210+
_decrypted_admin_pass = EncryptionUtils.decryptString(admin_pass, passphrase_array)
211+
self.assertEquals(str(String(_decrypted_admin_pass)), self._unencrypted_password_second)
212+
213+
return
214+
215+
def testMultipleModelsIndirectEncryptionVariables(self):
216+
copy2(self._src_model_file_w_variables, self._target_model_test2)
217+
copy2(self._src_model_file_w_variables_multi, self._target_model_test3)
218+
copy2(self._src_variable_file, self._target_variables_test3)
219+
220+
args = list()
221+
args.append('encrypt') # dummy arg for args[0] to get arg padding right
222+
args.append(CommandLineArgUtil.ORACLE_HOME_SWITCH)
223+
args.append(self._oracle_home)
224+
args.append(CommandLineArgUtil.MODEL_FILE_SWITCH)
225+
args.append(self._target_model_test2 + ',' + self._target_model_test3)
226+
args.append(CommandLineArgUtil.VARIABLE_FILE_SWITCH)
227+
args.append(self._target_variables_test3)
228+
args.append(CommandLineArgUtil.PASSPHRASE_SWITCH)
229+
args.append(self._passphrase)
230+
exit_code = encrypt._process_request(args)
231+
self.assertEquals(exit_code, 0)
232+
233+
model2 = FileToPython(self._target_model_test2).parse()
234+
model3 = FileToPython(self._target_model_test3).parse()
235+
variables = variables_helper.load_variables(self._target_variables_test3)
236+
passphrase_array = String(self._passphrase).toCharArray()
237+
238+
admin_pass = model2['domainInfo']['AdminPassword']
239+
self.assertNotEquals(admin_pass.startswith('{AES}'), True)
240+
admin_pass = model3['domainInfo']['AdminPassword']
241+
self.assertNotEquals(admin_pass.startswith('{AES}'), True)
242+
admin_pass = variables['admin.password']
243+
self.assertEquals(admin_pass.startswith('{AES}'), True)
244+
_decrypted_admin_pass = EncryptionUtils.decryptString(admin_pass, passphrase_array)
245+
self.assertEquals(str(String(_decrypted_admin_pass)), self._unencrypted_password)
246+
247+
nm_pass = model2['topology']['SecurityConfiguration']['NodeManagerPasswordEncrypted']
248+
self.assertNotEquals(nm_pass.startswith('{AES}'), True)
249+
nm_pass = variables['nm.password']
250+
self.assertEquals(nm_pass.startswith('{AES}'), True)
251+
_decrypted_nm_pass = EncryptionUtils.decryptString(nm_pass, passphrase_array)
252+
self.assertEquals(str(String(_decrypted_nm_pass)), self._unencrypted_password)
253+
254+
ds1_pass = model2['resources']['JDBCSystemResource']['Generic1']['JdbcResource']['JDBCDriverParams']['PasswordEncrypted']
255+
self.assertEquals(ds1_pass.startswith('{AES}'), True)
256+
_decrypted_ds1_pass = EncryptionUtils.decryptString(ds1_pass, passphrase_array)
257+
self.assertEquals(str(String(_decrypted_ds1_pass)), self._unencrypted_password)
258+
259+
return
260+
261+
def testMultipleModelsDirectAndVariables(self):
262+
copy2(self._src_model_file_w_variables, self._target_model_test1)
263+
copy2(self._src_model_file_wo_variables_for_multi, self._target_model_test2)
264+
copy2(self._src_variable_file, self._target_variables_test3)
265+
266+
args = list()
267+
args.append('encrypt') # dummy arg for args[0] to get arg padding right
268+
args.append(CommandLineArgUtil.ORACLE_HOME_SWITCH)
269+
args.append(self._oracle_home)
270+
args.append(CommandLineArgUtil.MODEL_FILE_SWITCH)
271+
args.append(self._target_model_test1 + ',' + self._target_model_test2)
272+
args.append(CommandLineArgUtil.VARIABLE_FILE_SWITCH)
273+
args.append(self._target_variables_test3)
274+
args.append(CommandLineArgUtil.PASSPHRASE_SWITCH)
275+
args.append(self._passphrase)
276+
exit_code = encrypt._process_request(args)
277+
self.assertEquals(exit_code, 0)
278+
279+
model2 = FileToPython(self._target_model_test1).parse()
280+
model3 = FileToPython(self._target_model_test2).parse()
281+
variables = variables_helper.load_variables(self._target_variables_test3)
282+
passphrase_array = String(self._passphrase).toCharArray()
283+
284+
admin_pass = model2['domainInfo']['AdminPassword']
285+
self.assertNotEquals(admin_pass.startswith('{AES}'), True)
286+
admin_pass = variables['admin.password']
287+
self.assertEquals(admin_pass.startswith('{AES}'), True)
288+
_decrypted_admin_pass = EncryptionUtils.decryptString(admin_pass, passphrase_array)
289+
self.assertEquals(str(String(_decrypted_admin_pass)), self._unencrypted_password)
290+
admin_pass = model3['domainInfo']['AdminPassword']
291+
self.assertEquals(admin_pass.startswith('{AES}'), True)
292+
_decrypted_admin_pass = EncryptionUtils.decryptString(admin_pass, passphrase_array)
293+
self.assertEquals(str(String(_decrypted_admin_pass)), self._unencrypted_password_second)
294+
295+
return

0 commit comments

Comments
 (0)