Skip to content

Commit 9d76e0b

Browse files
committed
Merge branch 'jira-wdt-898-validate-credential-mapping' into 'main'
Add simple and content validation for WLS credential mappings See merge request weblogic-cloud/weblogic-deploy-tooling!1705
2 parents 08d5174 + 77cd065 commit 9d76e0b

File tree

5 files changed

+154
-3
lines changed

5 files changed

+154
-3
lines changed

core/src/main/python/wlsdeploy/tool/validate/content_validator.py

+40-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,17 @@
77
from oracle.weblogic.deploy.logging import WLSDeployLogEndHandler
88

99
from wlsdeploy.aliases.model_constants import CLUSTER
10+
from wlsdeploy.aliases.model_constants import CROSS_DOMAIN
11+
from wlsdeploy.aliases.model_constants import DOMAIN_INFO
1012
from wlsdeploy.aliases.model_constants import DYNAMIC_SERVERS
13+
from wlsdeploy.aliases.model_constants import REMOTE_DOMAIN
14+
from wlsdeploy.aliases.model_constants import REMOTE_HOST
15+
from wlsdeploy.aliases.model_constants import REMOTE_PASSWORD
16+
from wlsdeploy.aliases.model_constants import REMOTE_RESOURCE
17+
from wlsdeploy.aliases.model_constants import REMOTE_USER
1118
from wlsdeploy.aliases.model_constants import SERVER_TEMPLATE
1219
from wlsdeploy.aliases.model_constants import TOPOLOGY
20+
from wlsdeploy.aliases.model_constants import WLS_USER_PASSWORD_CREDENTIAL_MAPPINGS
1321
from wlsdeploy.exception import exception_helper
1422
from wlsdeploy.logging.platform_logger import PlatformLogger
1523
from wlsdeploy.util import dictionary_utils
@@ -21,8 +29,6 @@ class ContentValidator(object):
2129
These checks are done after alias folder and attribute checks.
2230
These checks should be performed against a detokenized, merged model.
2331
Tho model may be a sparse model. For example, it could referencce targets from another model.
24-
25-
Dynamic clusters is currently the only validation.
2632
"""
2733
_class_name = 'ContentValidator'
2834
_logger = PlatformLogger('wlsdeploy.validate')
@@ -60,6 +66,7 @@ def validate_model_content(self, model_dict):
6066
# be tokenized in Prepare Model, do not call validate_user_passwords() from here.
6167
#
6268
self.validate_dynamic_clusters(model_dict)
69+
self.validate_credential_mappings(model_dict)
6370

6471
def validate_dynamic_clusters(self, model_dict):
6572
"""
@@ -87,3 +94,34 @@ def validate_dynamic_clusters(self, model_dict):
8794

8895
else:
8996
server_templates.append(server_template)
97+
98+
def validate_credential_mappings(self, model_dict):
99+
"""
100+
Validate the content of the WLSUserPasswordCredentialMappings section of the model.
101+
This does not include simple single-attribute validation such as value ranges,
102+
those are handled in domain_info_validator.__validate_wls_credential_mappings_section
103+
:param model_dict: the model to be validated
104+
"""
105+
domain_info_folder = dictionary_utils.get_dictionary_element(model_dict, DOMAIN_INFO)
106+
mappings_folder = dictionary_utils.get_dictionary_element(domain_info_folder,
107+
WLS_USER_PASSWORD_CREDENTIAL_MAPPINGS)
108+
109+
cross_domain_dict = dictionary_utils.get_dictionary_element(mappings_folder, CROSS_DOMAIN)
110+
for mapping_name, mapping_dict in cross_domain_dict.iteritems():
111+
self.__validate_required_field(mapping_dict, REMOTE_USER, CROSS_DOMAIN, mapping_name)
112+
self.__validate_required_field(mapping_dict, REMOTE_PASSWORD, CROSS_DOMAIN, mapping_name)
113+
self.__validate_required_field(mapping_dict, REMOTE_DOMAIN, CROSS_DOMAIN, mapping_name)
114+
115+
remote_resources_dict = dictionary_utils.get_dictionary_element(mappings_folder, REMOTE_RESOURCE)
116+
for mapping_name, mapping_dict in remote_resources_dict.iteritems():
117+
self.__validate_required_field(mapping_dict, REMOTE_USER, REMOTE_RESOURCE, mapping_name)
118+
self.__validate_required_field(mapping_dict, REMOTE_PASSWORD, REMOTE_RESOURCE, mapping_name)
119+
self.__validate_required_field(mapping_dict, REMOTE_HOST, REMOTE_RESOURCE, mapping_name)
120+
121+
def __validate_required_field(self, dictionary, field_name, parent_folder_name, folder_name):
122+
_method_name = '__validate_required_field'
123+
124+
if field_name not in dictionary:
125+
self._logger.severe('WLSDPLY-05210', field_name, parent_folder_name, folder_name,
126+
class_name=self._class_name, method_name=_method_name)
127+

core/src/main/python/wlsdeploy/tool/validate/domain_info_validator.py

+37-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
44
"""
55
from oracle.weblogic.deploy.create import RCURunner
6-
from oracle.weblogic.deploy.util import WLSDeployArchive
76

87
from wlsdeploy.aliases.model_constants import ATP_DEFAULT_TABLESPACE
98
from wlsdeploy.aliases.model_constants import ATP_TEMPORARY_TABLESPACE
@@ -14,16 +13,20 @@
1413
from wlsdeploy.aliases.model_constants import DRIVER_PARAMS_TRUSTSTORETYPE_PROPERTY
1514
from wlsdeploy.aliases.model_constants import DRIVER_PARAMS_TRUSTSTORE_PROPERTY
1615
from wlsdeploy.aliases.model_constants import DYNAMIC_CLUSTER_SERVER_GROUP_TARGETING_LIMITS
16+
from wlsdeploy.aliases.model_constants import METHOD
1717
from wlsdeploy.aliases.model_constants import MODEL_LIST_DELIMITER
1818
from wlsdeploy.aliases.model_constants import ORACLE_DATABASE_CONNECTION_TYPE
19+
from wlsdeploy.aliases.model_constants import PROTOCOL
1920
from wlsdeploy.aliases.model_constants import RCU_DATABASE_TYPE
2021
from wlsdeploy.aliases.model_constants import RCU_DB_INFO
2122
from wlsdeploy.aliases.model_constants import RCU_DEFAULT_TABLESPACE
2223
from wlsdeploy.aliases.model_constants import RCU_TEMP_TBLSPACE
24+
from wlsdeploy.aliases.model_constants import REMOTE_RESOURCE
2325
from wlsdeploy.aliases.model_constants import SERVER_GROUP_TARGETING_LIMITS
2426
from wlsdeploy.aliases.model_constants import STORE_TYPE_SSO
2527
from wlsdeploy.aliases.model_constants import WLS_POLICIES
2628
from wlsdeploy.aliases.model_constants import WLS_ROLES
29+
from wlsdeploy.aliases.model_constants import WLS_USER_PASSWORD_CREDENTIAL_MAPPINGS
2730
from wlsdeploy.logging.platform_logger import PlatformLogger
2831
from wlsdeploy.tool.create import wlspolicies_helper
2932
from wlsdeploy.tool.create import wlsroles_helper
@@ -59,6 +62,18 @@
5962
'JKS'
6063
]
6164

65+
RESOURCE_METHODS = [
66+
'GET',
67+
'POST'
68+
]
69+
70+
RESOURCE_PROTOCOLS = [
71+
'http',
72+
'https',
73+
't3',
74+
't3s'
75+
]
76+
6277
DEPRECATED_DB_TYPES = [
6378
RCURunner.ORACLE_DB_TYPE,
6479
RCURunner.ORACLE_ATP_DB_TYPE,
@@ -109,6 +124,8 @@ def _validate_folder(self, model_node, location):
109124
self.__validate_wlsroles_section(model_node)
110125
elif folder_name == WLS_POLICIES:
111126
self.__validate_wlspolicies_section(model_node)
127+
elif folder_name == WLS_USER_PASSWORD_CREDENTIAL_MAPPINGS:
128+
self.__validate_wls_credential_mappings_section(model_node)
112129
elif folder_name == RCU_DB_INFO:
113130
self.__validate_rcu_db_info_section(model_node)
114131

@@ -163,6 +180,25 @@ def __validate_wlsroles_section(self, roles_dict):
163180

164181
self._logger.exiting(class_name=_class_name, method_name=__method_name)
165182

183+
def __validate_wls_credential_mappings_section(self, mappings_dict):
184+
# This method validates fields that can be checked in an unmerged model, such as value ranges.
185+
# Checks for merged model (such as required/missing fields) are done in create_content_validator.py .
186+
_method_name = '__validate_wls_credential_mappings_section'
187+
188+
# no field checks for cross-domain mappings
189+
190+
remote_resources_dict = dictionary_utils.get_dictionary_element(mappings_dict, REMOTE_RESOURCE)
191+
for mapping_name, mapping_dict in remote_resources_dict.iteritems():
192+
method = dictionary_utils.get_element(mapping_dict, METHOD)
193+
if method and method not in RESOURCE_METHODS:
194+
self._logger.severe('WLSDPLY-05313', method, REMOTE_RESOURCE, mapping_name, METHOD,
195+
', '.join(RESOURCE_METHODS), class_name=_class_name, method_name=_method_name)
196+
197+
protocol = dictionary_utils.get_element(mapping_dict, PROTOCOL)
198+
if protocol and protocol not in RESOURCE_PROTOCOLS:
199+
self._logger.severe('WLSDPLY-05313', protocol, REMOTE_RESOURCE, mapping_name, PROTOCOL,
200+
', '.join(RESOURCE_PROTOCOLS), class_name=_class_name, method_name=_method_name)
201+
166202
def __validate_rcu_db_info_section(self, info_dict):
167203
_method_name = '__validate_rcu_db_info_section'
168204

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

+2
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,7 @@ WLSDPLY-05206=Found model attribute {0} of type {1} with value {2}
663663
WLSDPLY-05207=Found alias attribute {0} of type {1} with default value {2}
664664
WLSDPLY-05208=Skipping password validation for user {0} because the password appears to be tokenized
665665
WLSDPLY-05209=Model content validation failed
666+
WLSDPLY-05210=Attribute "{0}" is required for {1} credential mapping {2}
666667

667668
# wlsdeploy/tool/validate/deployments_validator.py
668669
WLSDPLY-05240=Archive {0} {1} at location {2} was expected to start with {3}
@@ -682,6 +683,7 @@ WLSDPLY-05309={0} field {1} must be specified for {2} value of {3}
682683
WLSDPLY-05310={0} field {1} must be specified if {2} is specified
683684
WLSDPLY-05311=Prepended path {0} for {1} field {2} is an archive path, and no archive file is specified
684685
WLSDPLY-05312=Prepended path {0} for {1} field {2} is an archive path, and not found in any archive file
686+
WLSDPLY-05313=Value {0} is invalid for {1} {2} field {3}, must be one of {4}
685687

686688
# oracle/weblogic/deploy/validate/PasswordValidator.java
687689
WLSDPLY-05400=Password validation failed because the username was not provided

core/src/test/python/wlsdeploy/tool/validate/content_validator_test.py

+41
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@
1010
from base_test import BaseTestCase
1111
from wlsdeploy.aliases.aliases import Aliases
1212
from wlsdeploy.aliases.model_constants import CLUSTER
13+
from wlsdeploy.aliases.model_constants import CROSS_DOMAIN
14+
from wlsdeploy.aliases.model_constants import DOMAIN_INFO
1315
from wlsdeploy.aliases.model_constants import DYNAMIC_SERVERS
16+
from wlsdeploy.aliases.model_constants import REMOTE_RESOURCE
1417
from wlsdeploy.aliases.model_constants import SERVER_TEMPLATE
1518
from wlsdeploy.aliases.model_constants import TOPOLOGY
19+
from wlsdeploy.aliases.model_constants import WLS_USER_PASSWORD_CREDENTIAL_MAPPINGS
1620
from wlsdeploy.logging.platform_logger import PlatformLogger
1721
from wlsdeploy.tool.validate.content_validator import ContentValidator
1822
from wlsdeploy.util.cla_utils import CommandLineArgUtil
@@ -81,6 +85,43 @@ def test_dynamic_dynamic_cluster_server_templates(self):
8185
# clusterOne and clusterTwo have the same server template
8286
self._validate_message_key(handler, Level.WARNING, 'WLSDPLY-05201', 1)
8387

88+
def test_wls_credential_mappings(self):
89+
model_dict = {
90+
DOMAIN_INFO: {
91+
WLS_USER_PASSWORD_CREDENTIAL_MAPPINGS: {
92+
CROSS_DOMAIN: {
93+
'map1': {
94+
# these 3 are required
95+
# 'RemoteDomain': 'otherDomain',
96+
# 'RemoteUser': 'otherUser',
97+
# 'RemotePassword': 'welcome1',
98+
}
99+
},
100+
REMOTE_RESOURCE: {
101+
'map2': {
102+
# these 3 are required
103+
# 'RemoteHost': 'otherHost',
104+
# 'RemoteUser': 'otherUser',
105+
# 'RemotePassword': 'welcome1',
106+
}
107+
}
108+
}
109+
}
110+
}
111+
112+
validator = self.create_validator()
113+
validator.validate_model_content(model_dict)
114+
115+
handler = self._summary_handler
116+
self.assertNotEqual(handler, None, "Summary handler is not present")
117+
118+
# Verify 2 errors, no warnings
119+
self.assertEqual(handler.getMessageCount(Level.SEVERE), 6)
120+
self.assertEqual(handler.getMessageCount(Level.WARNING), 0)
121+
122+
# 6 missing attributes for mappings
123+
self._validate_message_key(handler, Level.SEVERE, 'WLSDPLY-05210', 6)
124+
84125
def create_validator(self):
85126
args_map = {
86127
CommandLineArgUtil.ORACLE_HOME_SWITCH: '/oracle'

core/src/test/python/wlsdeploy/tool/validate/domain_info_validator_test.py

+34
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,15 @@
1212
from wlsdeploy.aliases.aliases import Aliases
1313
from wlsdeploy.aliases.model_constants import DATABASE_TYPE
1414
from wlsdeploy.aliases.model_constants import DOMAIN_INFO
15+
from wlsdeploy.aliases.model_constants import METHOD
1516
from wlsdeploy.aliases.model_constants import ORACLE_DATABASE_CONNECTION_TYPE
17+
from wlsdeploy.aliases.model_constants import PROTOCOL
1618
from wlsdeploy.aliases.model_constants import RCU_DATABASE_TYPE
1719
from wlsdeploy.aliases.model_constants import RCU_DB_INFO
20+
from wlsdeploy.aliases.model_constants import REMOTE_RESOURCE
1821
from wlsdeploy.aliases.model_constants import WLS_POLICIES
1922
from wlsdeploy.aliases.model_constants import WLS_ROLES
23+
from wlsdeploy.aliases.model_constants import WLS_USER_PASSWORD_CREDENTIAL_MAPPINGS
2024
from wlsdeploy.logging.platform_logger import PlatformLogger
2125
from wlsdeploy.tool.validate.validator import Validator
2226
from wlsdeploy.util.model_context import ModelContext
@@ -133,6 +137,36 @@ def test_wls_roles_validation(self):
133137
# MyTester3 has invalid update mode
134138
self._validate_message_key(handler, Level.SEVERE, 'WLSDPLY-12505', 1)
135139

140+
def test_wls_credential_mappings_section(self):
141+
_method_name = 'test_wls_credential_mappings_section'
142+
143+
mappings_dict = {
144+
REMOTE_RESOURCE: {
145+
'map1': {
146+
# these 2 values are bad
147+
PROTOCOL: 'httpx',
148+
METHOD: 'SEND',
149+
}
150+
}
151+
}
152+
153+
model_dict = {
154+
DOMAIN_INFO: {
155+
WLS_USER_PASSWORD_CREDENTIAL_MAPPINGS: mappings_dict
156+
}
157+
}
158+
159+
self.validator.validate_in_standalone_mode(model_dict, {})
160+
161+
handler = self._summary_handler
162+
self.assertNotEqual(handler, None, "Summary handler is not present")
163+
164+
self.assertEqual(handler.getMessageCount(Level.SEVERE), 2)
165+
self.assertEqual(handler.getMessageCount(Level.WARNING), 0)
166+
167+
# PROTOCOL and METHOD have invalid values
168+
self._validate_message_key(handler, Level.SEVERE, 'WLSDPLY-05313', 2)
169+
136170
def test_rcu_db_info_validation(self):
137171
model_dict = {
138172
DOMAIN_INFO: {

0 commit comments

Comments
 (0)