def create(ctx): try: run(['systemctl', 'status', 'snmptrapd']) except subprocess.CalledProcessError: raise NonRecoverableError( 'SNMP trap checks cannot be used if snmptrapd has not been ' 'configured. trap_community should be set on the ' 'cloudify.nagios.nodes.Nagios managed nagios node.' ) trap_oid = oid_lookup.get(ctx.node.properties['trap_oid']) instance_oid = ctx.node.properties['instance_oid'] instance_finder = ctx.node.properties['instance_finder'] oid_for_message = ctx.node.properties['oid_for_message'] trap_configuration = {} if instance_oid: trap_configuration['instance'] = { 'oid': oid_lookup.get(instance_oid), 'finder': instance_finder, } if oid_for_message: trap_configuration['oid_for_message'] = oid_for_message ctx.logger.info('Deploying trap configuration') deploy_file( data=json.dumps(trap_configuration), destination=TRAP_CONFIGURATION_PATH.format(oid=trap_oid), sudo=True, )
def create(ctx): props = ctx.node.properties ctx.logger.info('Validating SSL properties') if bool(props['ssl_certificate']) != bool(props['ssl_key']): raise NonRecoverableError( 'Either ssl_certificate and ssl_key must both be provided, ' 'or neither of them must be provided. ' 'ssl_certificate was: {ssl_certificate}; ' 'ssl_key was: {ssl_key}'.format( ssl_certificate=props['ssl_certificate'], ssl_key=props['ssl_key'], )) ctx.logger.info('Enabling EPEL (if required)') yum_install('epel-release') ctx.logger.info('Installing required packages') yum_install([ 'mod_ssl', 'nagios', 'nagios-plugins-disk', 'nagios-plugins-load', 'nagios-plugins-ping', 'nagios-plugins-snmp', 'nagios-selinux', 'net-snmp', 'net-snmp-utils', 'python-flask', 'python-gunicorn', 'python-jinja2', 'python-requests', 'selinux-policy-devel', 'incron', ]) ctx.logger.info('Deploying SELinux configuration') # Prepare SELinux context for trap handler tmp_path = tempfile.mkdtemp() with open( os.path.join(tmp_path, 'cloudify-nagios-snmp-trap-handler.te'), 'w', ) as policy_handle: policy_handle.write( pkgutil.get_data( 'managed_nagios_plugin', 'resources/selinux/cloudify_nagios_snmp_trap_handler.te', )) run(['make', '-f', '/usr/share/selinux/devel/Makefile', '-C', tmp_path], sudo=True) run([ 'semodule', '-i', os.path.join(tmp_path, 'cloudify-nagios-snmp-trap-handler.pp') ], sudo=True) run(['rm', '-rf', tmp_path], sudo=True) ctx.logger.info('Deploying nagios plugins and SNMP trap handler') for supporting_lib in ('constants.py', 'utils.py', 'snmp_utils.py', 'nagios_utils.py', 'rest_utils.py', 'resources/scripts/nagios_plugin_utils.py', 'resources/scripts/logging_utils.py'): if supporting_lib.startswith('resources/scripts/'): destination_filename = supporting_lib[len('resources/scripts/'):] else: destination_filename = supporting_lib deploy_file( data=pkgutil.get_data( 'managed_nagios_plugin', supporting_lib, ), destination='/usr/lib64/nagios/plugins/' + destination_filename, ownership='root.nagios', permissions='440', sudo=True, ) for script in ('check_snmp_numeric', 'check_snmp_aggregate', 'check_group_aggregate', 'check_group_meta_aggregate', 'cloudify_nagios_snmp_trap_handler', 'notify_cloudify', 'check_nagios_command_file', 'check_snmptrap_checks'): source = os.path.join('resources/scripts/', script) script_content = pkgutil.get_data('managed_nagios_plugin', source) destination = os.path.join('/usr/lib64/nagios/plugins', script) deploy_file( data=script_content, destination=destination, permissions='550', sudo=True, ) ctx.logger.info('Deploying nagiosrest') run(['mkdir', '-p', '/usr/local/www/nagiosrest'], sudo=True) for nagiosrest_file in ('nagiosrest.py', 'nagiosrest_group.py', 'nagiosrest_target.py', 'nagiosrest_tenant.py', 'logging_utils.py'): deploy_file( data=pkgutil.get_data( 'managed_nagios_plugin', 'resources/scripts/' + nagiosrest_file, ), destination='/usr/local/www/nagiosrest/' + nagiosrest_file, ownership='root.nagios', permissions='440', sudo=True, ) for supporting_lib in ('nagios_utils.py', 'utils.py', 'constants.py'): deploy_file( data=pkgutil.get_data( 'managed_nagios_plugin', supporting_lib, ), destination='/usr/local/www/nagiosrest/' + supporting_lib, ownership='root.nagios', permissions='440', sudo=True, ) for template in ('hostgroup.template', 'target.template', 'node.template', 'group.template', 'group_check.template', 'meta_group_check.template'): deploy_file( data=pkgutil.get_data( 'managed_nagios_plugin', os.path.join('resources', template), ), destination='/usr/local/www/nagiosrest/' + template, ownership='root.nagios', permissions='440', sudo=True, ) deploy_file( data=pkgutil.get_data( 'managed_nagios_plugin', 'resources/base_configuration/systemd_nagiosrest.conf', ), destination='/usr/lib/systemd/system/nagiosrest-gunicorn.service', ownership='root.root', permissions='440', sudo=True, ) ctx.logger.info('Deploying notification configuration script') deploy_file( data=pkgutil.get_data( 'managed_nagios_plugin', 'resources/scripts/update_notify_cloudify_configuration', ), destination='/usr/local/bin/update_notify_cloudify_configuration', ownership='root.root', permissions='500', sudo=True, # Must have the group of the agent user for reconcile operation to # work correctly template_params={'group': grp.getgrgid(os.getgid()).gr_name}, ) deploy_file( data=pkgutil.get_data( 'managed_nagios_plugin', 'utils.py', ), destination='/usr/local/bin/utils.py', ownership='root.root', permissions='400', sudo=True, ) deploy_file( data=pkgutil.get_data( 'managed_nagios_plugin', 'constants.py', ), destination='/usr/local/bin/constants.py', ownership='root.root', permissions='400', sudo=True, ) ctx.logger.info( 'Creating directory structure for storing temporary rate data') for rate_dir in ('nodes', 'instances'): rate_storage_path = os.path.join(RATE_BASE_PATH, rate_dir) run(['mkdir', '-p', rate_storage_path], sudo=True) run(['chown', 'nagios.', rate_storage_path], sudo=True) run(['restorecon', rate_storage_path], sudo=True) if props['ssl_certificate']: if props['ssl_certificate'].startswith("-----BEGIN CERTIFICATE-----"): deploy_file( data=props['ssl_key'], destination=SSL_KEY_PATH, ownership='root.root', permissions='440', sudo=True, ) deploy_file( data=props['ssl_certificate'], destination=SSL_CERT_PATH, ownership='root.root', permissions='444', sudo=True, ) else: download_and_deploy_file_from_blueprint( source=BLUEPRINT_SSL_KEY_PATH.format( key_file=props['ssl_key'], ), destination=SSL_KEY_PATH, ownership='root.root', permissions='440', ctx=ctx, ) download_and_deploy_file_from_blueprint( source=BLUEPRINT_SSL_CERT_PATH.format( cert_file=props['ssl_certificate'], ), destination=SSL_CERT_PATH, ownership='root.root', permissions='444', ctx=ctx, ) else: ctx.logger.info('Generating SSL certificate') generate_certs(SSL_KEY_PATH, SSL_CERT_PATH, ctx.logger) with open(SSL_CERT_PATH) as crt_handle: ctx.instance.runtime_properties['ssl_certificate'] = crt_handle.read() ctx.logger.info('Reloading systemd configuration') reload_systemd_configuration()
def configure(ctx): props = ctx.node.properties ctx.logger.info('Configuring nagios web user') username = props['nagios_web_username'] password = props['nagios_web_password'] tmpdir = tempfile.mkdtemp() tmp_htpass = os.path.join(tmpdir, 'passwd') run(['htpasswd', '-bc', tmp_htpass, username, password]) run(['mv', tmp_htpass, '/etc/nagios/passwd'], sudo=True) run(['rm', '-rf', tmpdir]) run(['chown', 'root.apache', '/etc/nagios/passwd'], sudo=True) run(['chmod', '640', '/etc/nagios/passwd'], sudo=True) run(['usermod', '-G', 'nagios', 'apache'], sudo=True) ctx.logger.info('Deploying automated reaction configuration') # We're using username+password because current token implementation is # unsuitable for this. reaction_configuration = { 'username': props['cloudify_manager_username'], 'password': props['cloudify_manager_password'], } deploy_file( data=json.dumps(reaction_configuration), destination='/etc/nagios/cloudify_manager.json', ownership='nagios.{group}'.format( # Must have the group of the agent user for reconcile operation to # work correctly group=grp.getgrgid(os.getgid()).gr_name, ), permissions='440', sudo=True, ) notification_plugin_storage_dir = '/var/spool/nagios/cloudifyreaction' run(['mkdir', '-p', notification_plugin_storage_dir], sudo=True) run(['restorecon', notification_plugin_storage_dir], sudo=True) run(['chown', 'nagios.nagios', notification_plugin_storage_dir], sudo=True) run(['chmod', '750', notification_plugin_storage_dir], sudo=True) ctx.logger.info('Preparing object paths') run(['rm', '-rf', BASE_OBJECTS_DIR], sudo=True) object_subdirs = [ 'checks', 'commands', 'contacts', 'groups/group_instances', 'groups/tenants', 'groups/types', 'templates', 'timeperiods', 'deployments', 'snmp_traps', 'targets', 'target_types', 'tenants', ] for subdir in object_subdirs: subdir = os.path.join(BASE_OBJECTS_DIR, subdir) run(['mkdir', '-p', subdir], sudo=True) run(['chown', '-R', OBJECT_OWNERSHIP, BASE_OBJECTS_DIR], sudo=True) run(['chmod', '-R', OBJECT_DIR_PERMISSIONS, BASE_OBJECTS_DIR], sudo=True) ctx.logger.info('Deploying nagios object configuration') config_source_dest_params = ( # Fully qualified paths because these two go outside the objects dir ('cgi.cfg', '/etc/nagios/cgi.cfg', { 'user': username }), ('nagios.cfg', '/etc/nagios/nagios.cfg', {}), # The rest are 'normal' configuration files ('base_system.cfg', 'base_system.cfg', {}), ('command_host_icmp.cfg', 'commands/check_host_icmp.cfg', {}), ('command_no_check.cfg', 'commands/no_check.cfg', {}), ('command_local_load.cfg', 'commands/check_local_load.cfg', {}), ('command_local_disk.cfg', 'commands/check_local_disk.cfg', {}), ('command_snmp_value.cfg', 'commands/check_snmp_value.cfg', {}), ('command_check_nagios_command_file.cfg', 'commands/check_nagios_command_file.cfg', {}), ('command_snmp_aggregate.cfg', 'commands/check_snmp_aggregate.cfg', {}), ('command_group_aggregate.cfg', 'commands/check_group_aggregate.cfg', {}), ('command_group_meta_aggregate.cfg', 'commands/check_group_meta_aggregate.cfg', {}), ('command_snmptrap_checks.cfg', 'commands/check_snmptrap_checks.cfg', {}), ('notification.cfg', 'commands/notify_automation.cfg', {}), ('contact.cfg', 'contacts/automation.cfg', {}), ('template_generic_service.cfg', 'templates/generic_service.cfg', {}), ('template_generic_host.cfg', 'templates/generic_host.cfg', {}), ('template_pseudo_host.cfg', 'templates/pseudo_host.cfg', {}), ('timeperiod_24x7.cfg', 'timeperiods/24x7.cfg', {}), ) for source, dest, params in config_source_dest_params: deploy_configuration_file( ctx.logger, source=os.path.join('resources/base_configuration', source), destination=dest, template_params=params, # We can't validate before we've put all of the configuration in # place as it will be invalid until it's finished validate=False, # We can't reload, it's not running yet reload_service=False, sudo=True, ) ctx.logger.info('Configuring httpd for ssl') deploy_file( data=pkgutil.get_data( 'managed_nagios_plugin', 'resources/base_configuration/httpd.conf', ), destination='/etc/httpd/conf/httpd.conf', ownership='root.apache', permissions='440', sudo=True, ) deploy_file( data=pkgutil.get_data( 'managed_nagios_plugin', 'resources/base_configuration/ssl.conf', ), destination='/etc/httpd/conf.d/ssl.conf', ownership='root.apache', permissions='440', sudo=True, ) ctx.logger.info('Configuring httpd for nagiosrest') deploy_file( data=pkgutil.get_data( 'managed_nagios_plugin', 'resources/base_configuration/httpd_nagiosrest.conf', ), destination='/etc/httpd/conf.d/nagiosrest.conf', ownership='root.apache', permissions='440', sudo=True, ) ctx.logger.info('Allowing nagiosrest to restart nagios') deploy_file( data=pkgutil.get_data( 'managed_nagios_plugin', 'resources/base_configuration/sudoers-nagiosrest', ), destination='/etc/sudoers.d/nagios-service-restart', ownership='root.root', permissions='440', sudo=True, ) ctx.logger.info('Deploying base SNMP configuration') deploy_file( data=pkgutil.get_data( 'managed_nagios_plugin', 'resources/base_configuration/snmp', ), destination='/etc/snmp/snmp.conf', ownership='root.root', permissions='440', sudo=True, ) trap_community = ctx.node.properties['trap_community'] if trap_community: ctx.logger.info('Configuring SNMP traps to use handler') deploy_file( data=pkgutil.get_data( 'managed_nagios_plugin', 'resources/base_configuration/snmptrapd', ), destination='/etc/snmp/snmptrapd.conf', ownership='root.root', permissions='440', sudo=True, template_params={ 'trap_community': trap_community, }, ) ctx.logger.info('Configuring notification script') deploy_file( data=pkgutil.get_data( 'managed_nagios_plugin', 'resources/base_configuration/incron.allow', ), destination='/etc/incron.allow', ownership='root.root', permissions='440', sudo=True, ) deploy_file( data=pkgutil.get_data( 'managed_nagios_plugin', 'resources/base_configuration/incron_root_spool', ), destination='/var/spool/incron/root', ownership='root.root', permissions='400', template_params={ 'homedir': os.path.expanduser('~'), }, sudo=True, ) agent_config_dir = os.path.join( os.path.expanduser('~'), '.cfy-agent', ) agent_configs = [ os.path.join(agent_config_dir, filename) for filename in os.listdir(agent_config_dir) ] # We'll use the most recently updated agent config current_agent_config = max(agent_configs, key=os.path.getmtime) run( [ '/usr/local/bin/update_notify_cloudify_configuration', current_agent_config, ], sudo=True, ) ctx.logger.info('Deploying logging configuration') level = props['component_log_level'].upper() validate_level = logging.getLevelName(level) if not isinstance(validate_level, int): raise NonRecoverableError( '{level} is not a valid logging level. ' 'It is recommended that component_log_level be set to one of ' 'DEBUG, INFO, WARNING, ERROR'.format(level=level)) component_logging_config = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'default': { 'format': '%(name)s(%(process)s) [%(levelname)s]: %(message)s', }, }, 'handlers': { 'syslog': { 'formatter': 'default', 'level': level, 'class': 'logging.handlers.SysLogHandler', 'address': '/dev/log', }, }, 'loggers': { '': { 'handlers': ['syslog'], 'level': level, 'propagate': True, }, }, } deploy_file( data=json.dumps(component_logging_config), destination='/etc/nagios/cloudify_components_logging.cfg', ownership='root.nagios', permissions='440', sudo=True, ) deploy_file( data=pkgutil.get_data( 'managed_nagios_plugin', 'resources/base_configuration/logrotate_config', ), destination='/etc/logrotate.d/managed_nagios', ownership='root.root', permissions='444', sudo=True, ) deploy_file( data=pkgutil.get_data( 'managed_nagios_plugin', 'resources/base_configuration/rsyslog_config', ), destination='/etc/rsyslog.d/managed_nagios_logging.conf', ownership='root.root', permissions='444', sudo=True, ) stop_service('rsyslog') start_service('rsyslog')
def create_target_type(logger, name, description, check_relationships, instance_failure_reaction, instance_health_check, check_interval, retry_interval, max_check_retries): deploy_configuration_file( logger, source='resources/target_type.template', destination=get_target_type_configuration_destination(name), template_params={ 'name': name, 'description': description, }, reload_service=False, sudo=True, ) deploy_configuration_file( logger, source='resources/target_type_host_template.template', destination=get_target_type_host_template_destination(name), template_params={ 'target_type': name, 'check_command': instance_health_check, 'check_interval': check_interval, 'retry_interval': retry_interval, 'max_check_retries': max_check_retries, }, reload_service=False, sudo=True, ) reactions = {'checks': {}, 'traps': {}} for check in check_relationships: props = check.node.properties # To avoid warnings in the logs, we'll set all notifications to 1 # minute, or the check_interval, whichever is higher. This means that # notifications will be retried every minute or every check_interval # if health state of a check does not improve. # Nagios will not send notifications more often than check_interval, # and will leave a warning in the logs every time it reloads # configuration for each notification_interval that is set lower # than check_interval. notification_interval = max(1, int(props.get('check_interval', 1))) if check.node.type == 'cloudify.nagios.nodes.SNMPTrapReaction': normalised_oid = oid_lookup.get(props['trap_oid']) if props['reaction']: reactions['traps'][normalised_oid] = { 'workflow': make_workflow_object( props['reaction'], ), 'constraints': { 'min_instances': props['min_instances'], 'max_instances': props['max_instances'], } } params = { 'target_type': name, 'oid': normalised_oid, } check_type = 'trap' disallowed = [] elif check.node.type == 'cloudify.nagios.nodes.SNMPValueCheck': params = { 'target_type': name, 'check_description': props['check_description'], 'snmp_oid': props['snmp_oid'], 'low_warning_threshold': props['low_warning_threshold'], 'low_critical_threshold': props['low_critical_threshold'], 'high_warning_threshold': props['high_warning_threshold'], 'high_critical_threshold': props['high_critical_threshold'], 'max_check_retries': props['max_check_retries'], 'check_interval': props['check_interval'], 'retry_interval': props['retry_interval'], 'notification_interval': notification_interval, 'rate': '--rate' if props['rate_check'] else '' } check_type = 'snmp_poll' disallowed = [] elif check.node.type == ( 'cloudify.nagios.nodes.SNMPAggregateValueCheck' ): params = { 'target_type': name, 'check_description': props['check_description'], 'snmp_oids': props['snmp_oids'], 'on_unknown': props['on_unknown'], 'aggregation_type': props['aggregation_type'], 'low_warning_threshold': props['low_warning_threshold'], 'low_critical_threshold': props['low_critical_threshold'], 'high_warning_threshold': props['high_warning_threshold'], 'high_critical_threshold': props['high_critical_threshold'], 'max_check_retries': props['max_check_retries'], 'check_interval': props['check_interval'], 'retry_interval': props['retry_interval'], 'notification_interval': notification_interval, 'rate': '--rate' if props['rate_check'] else '' } check_type = 'snmp_aggregate' disallowed = ['{{instance}}'] else: raise NonRecoverableError( 'Cannot parse check of type {node_type}'.format( node_type=check.node.type, ) ) reaction = {} # Trap reactions are deployed separately if check_type != 'trap': for level in ('low', 'high'): property_name = 'action_on_{level}_threshold'.format( level=level, ) min_instances_limit_name = '{level}_min_instances'.format( level=level, ) max_instances_limit_name = '{level}_max_instances'.format( level=level, ) if props[property_name]: action = make_workflow_object(props[property_name], disallowed=disallowed) reaction[level] = { 'workflow': action, 'constraints': { 'min_instances': props[min_instances_limit_name], 'max_instances': props[max_instances_limit_name], } } create_check(logger, check_type, name, check.node.id, params) if reaction: reactions['checks'][props['check_description']] = reaction host_reaction = make_workflow_object(instance_failure_reaction) if host_reaction: reactions['host'] = {'workflow': host_reaction} deploy_file( data=json.dumps(reactions), destination=get_reaction_configuration_destination(name), sudo=True, ) trigger_nagios_reload(set_group=True)
def create_group(ctx): props = ctx.node.properties name = props['name'] if ':' in name or '/' in name: raise NonRecoverableError('Group names must not contain : or /.') ctx.logger.info('Getting related checks') check_relationships = get_all_relationship_targets( ctx=ctx, target_relation_type='group_check', no_target_error=('Group types must be connected to 1+ checks with ' 'relationship {target_relation_type}'), ) allowed_check_types = ('cloudify.nagios.nodes.SNMPAggregateValueCheck', ) for check in check_relationships: if check.node.type not in allowed_check_types: raise NonRecoverableError( 'Group checks only support targeting checks of type: ' '{allowed}'.format(allowed=', '.join(allowed_check_types), )) ctx.logger.info('Generating group configuration') group_checks = get_all_relationship_targets( ctx=ctx, target_relation_type='group_check', no_target_error=('Check groups must be associated with checks.'), ) check_descriptions = [ check.node.properties['check_description'] for check in group_checks ] configuration = { "services": check_descriptions, "reactions": {}, "check_configuration": { "unknown": props["on_unknown"], "approach": props["aggregation_type"], "check_interval": props["check_interval"], "low_warning_threshold": props["low_warning_threshold"], "low_critical_threshold": props["low_critical_threshold"], "high_warning_threshold": props["high_warning_threshold"], "high_critical_threshold": props["high_critical_threshold"], }, } for level in 'low', 'high': action_name = 'action_on_{level}_threshold'.format(level=level) if props[action_name]['workflow_id']: configuration['reactions'][level] = { 'workflow': props[action_name] } ctx.logger.info('Creating group subdirectories') for subdir in ('groups/tenants', 'groups/types', 'groups/members', 'groups/checks'): make_config_subdir(subdir, sudo=True) ctx.logger.info('Creating group base configuration') deploy_file( data=json.dumps(configuration), destination=os.path.join( BASE_OBJECTS_DIR, 'groups/types/{name}.json'.format(name=hashlib.md5( name.encode('utf-8')).hexdigest(), )), sudo=True, ) ctx.logger.info('Deploying check list') check_list = [ check.node.properties['check_description'] for check in check_relationships ] deploy_file( data=json.dumps(check_list), destination=os.path.join( BASE_OBJECTS_DIR, 'groups/checks/{name}.json'.format(name=name, )), sudo=True, ) ctx.logger.info('Creating hostgroup') deploy_configuration_file( ctx.logger, source='resources/group_type.template', destination=os.path.join('groups/types', name + '.cfg'), template_params={ 'group_name': name, }, reload_service=True, sudo=True, )
def create(ctx): name = ctx.node.properties['name'] description = ctx.node.properties['alias'] ctx.logger.info('Validating instance health check command') available_checks = ( 'do-not-check', 'check-host-icmp', ) if ctx.node.properties['instance_health_check'] not in available_checks: raise NonRecoverableError( 'Command "{cmd}" specified by instance_health_check was invalid. ' 'Valid options are: {options}'.format( cmd=ctx.node.properties['instance_health_check'], options=', '.join(available_checks), )) ctx.logger.info('Using most secure available SNMP configuration') connection_config = ConfigParser() connection_config.add_section('snmp_params') snmp_props = ctx.node.properties['snmp_properties'] snmp_params = None # Pick the most secure snmp settings provided if snmp_props['v3']['username'] is not None: snmp_params = { 'protocol': 3, 'seclevel': 'authPriv', 'authproto': 'SHA', 'privproto': 'AES', 'secname': snmp_props['v3']['username'], 'authpasswd': snmp_props['v3']['auth_pass'], 'privpasswd': snmp_props['v3']['priv_pass'], } if snmp_props['v3'].get('context'): snmp_params['context'] = snmp_props['v3']['context'] elif snmp_props['v2c']['community'] is not None: snmp_params = { 'protocol': '2c', 'community': snmp_props['v2c']['community'], } if snmp_params is None: raise NonRecoverableError( 'Currently checks require SNMP configuration.') else: for key, value in snmp_params.items(): connection_config.set('snmp_params', key, text_type(value)) connection_config_text = _FakeFile() connection_config.write(connection_config_text) deploy_file( data=text_type(connection_config_text), destination=get_connection_config_location(name), sudo=True, ) ctx.logger.info('Getting related checks') check_relationships = get_all_relationship_targets( ctx=ctx, target_relation_type='target_type_checks', no_target_error=('Target types must be connected to 1+ checks with ' 'relationship {target_relation_type}'), ) ctx.logger.info('Deploying configuration') create_target_type( ctx.logger, name, description, check_relationships, instance_failure_reaction=ctx.node. properties['action_on_instance_failure'], instance_health_check=ctx.node.properties['instance_health_check'], check_interval=ctx.node.properties['check_interval'], retry_interval=ctx.node.properties['retry_interval'], max_check_retries=ctx.node.properties['max_check_retries'], )