1- # Copyright (c) 2021, 2022 , Oracle and/or its affiliates.
1+ # Copyright (c) 2021, 2023 , Oracle and/or its affiliates.
22# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33#
44# ------------
77# WDT filters to prepare a model for use a target environment, using the createDomain or prepareModel tools.
88# These operations can be invoked as a single call, or independently of each other.
99from oracle .weblogic .deploy .util import PyRealBoolean
10+ from oracle .weblogic .deploy .util import PyOrderedDict
1011from wlsdeploy .aliases import alias_utils
12+ from wlsdeploy .aliases .model_constants import ADMIN_SERVER_NAME
1113from wlsdeploy .aliases .model_constants import AUTO_MIGRATION_ENABLED
1214from wlsdeploy .aliases .model_constants import CALCULATED_LISTEN_PORTS
1315from wlsdeploy .aliases .model_constants import CANDIDATE_MACHINE
1416from wlsdeploy .aliases .model_constants import CANDIDATE_MACHINES_FOR_MIGRATABLE_SERVER
1517from wlsdeploy .aliases .model_constants import CLUSTER
1618from wlsdeploy .aliases .model_constants import CLUSTER_MESSAGING_MODE
1719from wlsdeploy .aliases .model_constants import DATABASE_LESS_LEASING_BASIS
20+ from wlsdeploy .aliases .model_constants import DEFAULT_ADMIN_SERVER_NAME
1821from wlsdeploy .aliases .model_constants import DYNAMIC_SERVERS
1922from wlsdeploy .aliases .model_constants import LISTEN_PORT
2023from wlsdeploy .aliases .model_constants import MACHINE
3134from wlsdeploy .aliases .model_constants import RESOURCE_MANAGER
3235from wlsdeploy .aliases .model_constants import SECURITY_CONFIGURATION
3336from wlsdeploy .aliases .model_constants import SERVER
37+ from wlsdeploy .aliases .model_constants import SERVER_NAME_PREFIX
3438from wlsdeploy .aliases .model_constants import SERVER_START
3539from wlsdeploy .aliases .model_constants import SERVER_TEMPLATE
3640from wlsdeploy .aliases .model_constants import TOPOLOGY
4549from wlsdeploy .util import dictionary_utils
4650import wlsdeploy .util .unicode_helper as str_helper
4751
52+ FIX_PREFIX_TEMPLATE = '-- FIX PREFIX %s --'
53+
4854_class_name = 'wko_filter'
4955_logger = PlatformLogger ('wlsdeploy.tool.util' )
5056
@@ -61,6 +67,7 @@ def filter_model(model, model_context):
6167 filter_resources (model , model_context )
6268 filter_online_attributes (model , model_context )
6369 check_clustered_server_ports (model , model_context )
70+ check_dynamic_cluster_prefixes (model , model_context )
6471
6572
6673def filter_model_for_wko (model , model_context ):
@@ -73,6 +80,17 @@ def filter_model_for_wko(model, model_context):
7380 filter_model (model , model_context )
7481
7582
83+ def filter_model_for_wko3 (model , model_context ):
84+ """
85+ Perform filtering operations on the specified model to prepare for WKO deployment.
86+ Currently matches the general k8s target filtering.
87+ :param model: the model to be filtered
88+ :param model_context: used by nested filters
89+ """
90+ filter_model (model , model_context )
91+ check_admin_server_defined (model , model_context )
92+
93+
7694def filter_model_for_vz (model , model_context ):
7795 """
7896 Perform filtering operations on the specified model to prepare for Verrazzano deployment.
@@ -143,6 +161,71 @@ def check_clustered_server_ports(model, _model_context):
143161 server_port_map [server_cluster ] = {"firstServer" : server_name , "serverPort" : server_port_text }
144162
145163
164+ def check_dynamic_cluster_prefixes (model , _model_context ):
165+ """
166+ All Dynamic Clusters must have a DynamicServers section with the ServerNamePrefix field explicitly declared.
167+ Ensure each cluster uses a unique value for this field.
168+ :param model: the model to be updated
169+ :param _model_context: unused, passed by filter_helper if called independently
170+ :return:
171+ """
172+ _method_name = 'check_dynamic_cluster_prefixes'
173+
174+ server_name_prefixes = []
175+ topology_folder = dictionary_utils .get_dictionary_element (model , TOPOLOGY )
176+ clusters_folder = dictionary_utils .get_dictionary_element (topology_folder , CLUSTER )
177+ for cluster_name , cluster_fields in clusters_folder .items ():
178+ dynamic_folder = dictionary_utils .get_element (cluster_fields , DYNAMIC_SERVERS )
179+ if dynamic_folder :
180+ server_name_prefix = dictionary_utils .get_element (dynamic_folder , SERVER_NAME_PREFIX )
181+
182+ if not server_name_prefix :
183+ _logger .warning ('WLSDPLY-20204' , cluster_name , SERVER_NAME_PREFIX , class_name = _class_name ,
184+ method_name = _method_name )
185+ server_name_prefix = _get_unused_prefix (server_name_prefixes )
186+ dynamic_folder [SERVER_NAME_PREFIX ] = server_name_prefix
187+
188+ elif server_name_prefix in server_name_prefixes :
189+ _logger .warning ('WLSDPLY-20205' , SERVER_NAME_PREFIX , server_name_prefix , class_name = _class_name ,
190+ method_name = _method_name )
191+ server_name_prefix = _get_unused_prefix (server_name_prefixes )
192+ dynamic_folder [SERVER_NAME_PREFIX ] = server_name_prefix
193+
194+ server_name_prefixes .append (server_name_prefix )
195+
196+
197+ def check_admin_server_defined (model , _model_context ):
198+ """
199+ Ensure that the AdminServerName attribute is set, and that the server is defined.
200+ This is required by WKO 3.0, and not by 4.0 and later.
201+ :param model: the model to be filtered
202+ :param _model_context: unused, passed by filter_helper if called independently
203+ """
204+ _method_name = 'check_admin_server_defined'
205+
206+ topology_folder = dictionary_utils .get_element (model , TOPOLOGY )
207+ if topology_folder is None :
208+ # for cases with multiple models, avoid adding topology and admin server for
209+ # models with only resources, applications, etc.
210+ return
211+
212+ admin_server_name = dictionary_utils .get_element (topology_folder , ADMIN_SERVER_NAME )
213+ if not admin_server_name :
214+ admin_server_name = DEFAULT_ADMIN_SERVER_NAME
215+ _logger .info ('WLSDPLY-20206' , ADMIN_SERVER_NAME , admin_server_name , class_name = _class_name ,
216+ method_name = _method_name )
217+ topology_folder [ADMIN_SERVER_NAME ] = admin_server_name
218+
219+ servers_folder = dictionary_utils .get_element (topology_folder , SERVER )
220+ if servers_folder is None :
221+ servers_folder = PyOrderedDict ()
222+ topology_folder [SERVER ] = servers_folder
223+
224+ if admin_server_name not in servers_folder :
225+ _logger .info ('WLSDPLY-20207' , SERVER , admin_server_name , class_name = _class_name , method_name = _method_name )
226+ servers_folder [admin_server_name ] = PyOrderedDict ()
227+
228+
146229def filter_topology (model , _model_context ):
147230 """
148231 Remove elements from the topology section of the model that are not relevant in a Kubernetes environment.
@@ -201,6 +284,18 @@ def filter_resources(model, _model_context):
201284 del resources [delete_key ]
202285
203286
287+ def _get_unused_prefix (used_prefixes ):
288+ """
289+ Find a recognizable, unused prefix that can be used in the filtered model.
290+ :param used_prefixes: prefixes that have already been used in the model
291+ :return: an unused prefix
292+ """
293+ i = 1
294+ while FIX_PREFIX_TEMPLATE % i in used_prefixes :
295+ i += 1
296+ return FIX_PREFIX_TEMPLATE % i
297+
298+
204299class OnlineAttributeFilter (ModelTraverse ):
205300 """
206301 Traverse the model and remove any online-only attributes.
0 commit comments