1717""" Configure factory. This module populates configuration based on package manager and environment, e.g. TEST/DEV/PROD"""
1818from __future__ import print_function
1919import os
20+ import time
2021from core .src .bootstrap .Constants import Constants
2122from core .src .bootstrap .EnvLayer import EnvLayer
2223
4041from core .src .package_managers .ZypperPackageManager import ZypperPackageManager
4142
4243from core .src .service_interfaces .LifecycleManager import LifecycleManager
44+ from core .src .service_interfaces .LifecycleManagerAzure import LifecycleManagerAzure
45+ from core .src .service_interfaces .LifecycleManagerArc import LifecycleManagerArc
4346from core .src .service_interfaces .StatusHandler import StatusHandler
4447from core .src .service_interfaces .TelemetryWriter import TelemetryWriter
4548
49+ try :
50+ import urllib2 as urlreq #Python 2.x
51+ except :
52+ import urllib .request as urlreq #Python 3.x
53+
4654
4755class ConfigurationFactory (object ):
4856 """ Class for generating module definitions. Configuration is list of key value pairs. Please DON'T change key name.
4957 DI container relies on the key name to find and resolve dependencies. If you do need change it, please make sure to
5058 update the key name in all places that reference it. """
5159 def __init__ (self , log_file_path , real_record_path , recorder_enabled , emulator_enabled , events_folder ):
60+ self .vm_cloud_type = self .get_vm_cloud_type ()
61+ self .lifecycle_manager_component = self .get_lifecycle_manager_component (self .vm_cloud_type )
62+
5263 self .bootstrap_configurations = {
5364 'prod_config' : self .new_bootstrap_configuration (Constants .PROD , log_file_path , real_record_path , recorder_enabled , emulator_enabled , events_folder ),
5465 'dev_config' : self .new_bootstrap_configuration (Constants .DEV , log_file_path , real_record_path , recorder_enabled , emulator_enabled , events_folder ),
@@ -155,18 +166,21 @@ def new_bootstrap_configuration(config_env, log_file_path, real_record_path, rec
155166
156167 def new_prod_configuration (self , package_manager_name , package_manager_component ):
157168 """ Base configuration for Prod V2. """
169+
158170 configuration = {
159171 'config_env' : Constants .PROD ,
160172 'package_manager_name' : package_manager_name ,
161173 'lifecycle_manager' : {
162- 'component' : LifecycleManager ,
174+ 'component' : self . lifecycle_manager_component ,
163175 'component_args' : ['env_layer' , 'execution_config' , 'composite_logger' , 'telemetry_writer' ],
164176 'component_kwargs' : {}
165177 },
166178 'status_handler' : {
167179 'component' : StatusHandler ,
168180 'component_args' : ['env_layer' , 'execution_config' , 'composite_logger' , 'telemetry_writer' ],
169- 'component_kwargs' : {}
181+ 'component_kwargs' : {
182+ 'vm_cloud_type' : self .vm_cloud_type
183+ }
170184 },
171185 'package_manager' : {
172186 'component' : package_manager_component ,
@@ -187,7 +201,7 @@ def new_prod_configuration(self, package_manager_name, package_manager_component
187201 },
188202 'patch_assessor' : {
189203 'component' : PatchAssessor ,
190- 'component_args' : ['env_layer' , 'execution_config' , 'composite_logger' , 'telemetry_writer' , 'status_handler' , 'package_manager' ],
204+ 'component_args' : ['env_layer' , 'execution_config' , 'composite_logger' , 'telemetry_writer' , 'status_handler' , 'package_manager' , 'lifecycle_manager' ],
191205 'component_kwargs' : {}
192206 },
193207 'patch_installer' : {
@@ -216,7 +230,7 @@ def new_prod_configuration(self, package_manager_name, package_manager_component
216230 },
217231 'configure_patching_processor' : {
218232 'component' : ConfigurePatchingProcessor ,
219- 'component_args' : ['env_layer' , 'execution_config' , 'composite_logger' , 'telemetry_writer' , 'status_handler' , 'package_manager' , 'auto_assess_service_manager' , 'auto_assess_timer_manager' ],
233+ 'component_args' : ['env_layer' , 'execution_config' , 'composite_logger' , 'telemetry_writer' , 'status_handler' , 'package_manager' , 'auto_assess_service_manager' , 'auto_assess_timer_manager' , 'lifecycle_manager' ],
220234 'component_kwargs' : {}
221235 },
222236 'maintenance_window' : {
@@ -240,4 +254,43 @@ def new_test_configuration(self, package_manager_name, package_manager_component
240254 configuration ['config_env' ] = Constants .TEST
241255 # perform desired modifications to configuration
242256 return configuration
257+
258+ def get_lifecycle_manager_component (self , vm_cloud_type ):
259+ """ finding life cycle manager based on vm and returning component name added in the prod configuration """
260+ azure_lifecycle_manager_component = LifecycleManagerAzure
261+ arc_lifecycle_manager_component = LifecycleManagerArc
262+ if (vm_cloud_type == Constants .VMCloudType .AZURE ):
263+ return azure_lifecycle_manager_component
264+ elif (vm_cloud_type == Constants .VMCloudType .ARC ):
265+ return arc_lifecycle_manager_component
266+
267+ return azure_lifecycle_manager_component
268+
269+ def get_vm_cloud_type (self ):
270+ """ detects vm type. logic taken from HCRP code: https://github.com/PowerShell/DesiredStateConfiguration/blob/dev/src/dsc/dsc_service/service_main.cpp#L115
271+ Todo: how to check this only when it is Auto Assessment operation??? """
272+ metadata_value = "True"
273+ user_agent_value = "ArcAgent"
274+ request = urlreq .Request (Constants .IMDS_END_POINT )
275+ request .add_header ('Metadata' , metadata_value )
276+ request .add_header ('UserAgent' , user_agent_value )
277+ print ("\n Trying to connect IMDS end point. URL:{0}." .format (str (Constants .IMDS_END_POINT )))
278+ for i in range (0 , Constants .MAX_IMDS_CONNECTION_RETRY_COUNT ):
279+ try :
280+ res = urlreq .urlopen (request , timeout = 2 )
281+ print (res .get_code ())
282+ if (res .getcode () == 200 ):
283+ print ("Connection to IMDS end point successfully established. VMCloudType is Azure\n " )
284+ return Constants .VMCloudType .AZURE
285+ else :
286+ raise
287+ except :
288+ """ Failed to connect to Azure IMDS endpoint. This is expected on Arc machine - but not expected on Azure machine."""
289+ if i < Constants .MAX_IMDS_CONNECTION_RETRY_COUNT - 1 :
290+ print ("Failed to connect to IMDS end point. [Retry Count={0}]." .format (str (i )))
291+ time .sleep (i + 1 )
292+ else :
293+ print ("Failed to connect IMDS end point. This is expected in ARC VM. VMCloudType is Arc\n " )
294+ return Constants .VMCloudType .ARC
295+
243296 # endregion
0 commit comments