Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 26 additions & 16 deletions check_docker/check_swarm.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,27 +104,23 @@ def process_urllib_response(response):
try:
resp = json.loads(body)
except json.JSONDecodeError as e:
unknown(f'Unable to parse response.')
unknown(f'Unable to parse response. {e}')
print_results()
sys.exit(rc)

return resp


def get_swarm_status():
content, status = get_url(daemon + '/swarm')
return status

return get_url(daemon + '/info')

def get_service_info(name):
return get_url(daemon + '/services/{service}'.format(service=name))


def get_service_tasks(name):
tasks, status = get_url(daemon + '/tasks?filters={{"name":{{"{service}":true}}}}'.format(service=name))
tasks, _ = get_url(daemon + '/tasks?filters={{"name":{{"{service}":true}}}}'.format(service=name))
return tasks


def get_nodes():
return get_url(daemon + '/nodes')

Expand All @@ -134,7 +130,7 @@ def get_services(names):
if status == 406:
critical("Error checking service status, node is not in swarm mode")
return []
elif status not in HTTP_GOOD_CODES:
if status not in HTTP_GOOD_CODES:
unknown("Could not retrieve service info")
return []

Expand Down Expand Up @@ -186,9 +182,23 @@ def unknown(message):
# Checks
#############################################################################################
def check_swarm():
status = get_swarm_status()
process_url_status(status, ok_msg='Node is in a swarm',
critical_msg='Node is not in a swarm', unknown_msg='Error accessing swarm info')
content, status = get_swarm_status()
if status not in HTTP_GOOD_CODES:
unknown('Could not retrieve swarm info')
return

if 'Swarm' not in content:
unknown('No swarm status available')
return

state = content['Swarm'].get('LocalNodeState')

if state == 'active':
ok(f'Node is in a swarm. Local node status: {state}')
elif state == 'pending':
warning(f'Node is not active in swarm. Local node status: {state}')
else:
critical(f'Node is not in a swarm. Local node status: {state}')


def process_global_service(name, ignore_paused=False):
Expand All @@ -197,7 +207,7 @@ def process_global_service(name, ignore_paused=False):
bad_node_states.add('paused')

# Get all the nodes we care about based on their state
node_list, status = get_nodes()
node_list, _ = get_nodes()
node_index = set()
for node in node_list:
if node['Spec']['Availability'] in bad_node_states:
Expand Down Expand Up @@ -234,7 +244,7 @@ def process_replicated_service(name, replicas_desired):

def check_service(name, ignore_paused=False):
# get service mode
service_info, status = get_service_info(name)
service_info, _ = get_service_info(name)
mode_info = service_info['Spec']['Mode']

# if global ensure one per node
Expand Down Expand Up @@ -346,8 +356,8 @@ def socketfile_permissions_failure(parsed_args):
and stat.S_ISSOCK(os.stat(parsed_args.connection).st_mode)
and os.access(parsed_args.connection, os.R_OK)
and os.access(parsed_args.connection, os.W_OK))
else:
return False

return False


def print_results():
Expand Down Expand Up @@ -379,7 +389,7 @@ def perform_checks(raw_args):

def main():
perform_checks(argv[1:])
exit(rc)
sys.exit(rc)


if __name__ == '__main__':
Expand Down
24 changes: 20 additions & 4 deletions tests/test_check_swarm.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ def mock_open(*args, **kwargs):

def test_get_swarm_status(check_swarm):
with patch('check_docker.check_swarm.get_url', return_value=('', 999)):
response = check_swarm.get_swarm_status()
assert response == 999
response, status = check_swarm.get_swarm_status()
assert status == 999


def test_get_service_info(check_swarm):
Expand Down Expand Up @@ -243,19 +243,35 @@ def test_check_swarm_called(check_swarm, fs):
def test_check_swarm_results_OK(check_swarm, fs):
fs.create_file(check_swarm.DEFAULT_SOCKET, contents='', st_mode=(stat.S_IFSOCK | 0o666))
args = ['--swarm']
with patch('check_docker.check_swarm.get_swarm_status', return_value=200):
with patch('check_docker.check_swarm.get_swarm_status', return_value=({'Swarm': {'LocalNodeState': 'active'}}, 200)):
check_swarm.perform_checks(args)
assert check_swarm.rc == cs.OK_RC


def test_check_swarm_results_CRITICAL(check_swarm, fs):
fs.create_file(check_swarm.DEFAULT_SOCKET, contents='', st_mode=(stat.S_IFSOCK | 0o666))
args = ['--swarm']
with patch('check_docker.check_swarm.get_swarm_status', return_value=406):
with patch('check_docker.check_swarm.get_swarm_status', return_value=({'Swarm': {'LocalNodeState': 'inactive'}}, 200)):
check_swarm.perform_checks(args)
assert check_swarm.rc == cs.CRITICAL_RC


def test_check_swarm_results_WARNING(check_swarm, fs):
fs.create_file(check_swarm.DEFAULT_SOCKET, contents='', st_mode=(stat.S_IFSOCK | 0o666))
args = ['--swarm']
with patch('check_docker.check_swarm.get_swarm_status', return_value=({'Swarm': {'LocalNodeState': 'pending'}}, 200)):
check_swarm.perform_checks(args)
assert check_swarm.rc == cs.WARNING_RC


def test_check_swarm_results_UNKNOWN(check_swarm, fs):
fs.create_file(check_swarm.DEFAULT_SOCKET, contents='', st_mode=(stat.S_IFSOCK | 0o666))
args = ['--swarm']
with patch('check_docker.check_swarm.get_swarm_status', return_value=({}, 200)):
check_swarm.perform_checks(args)
assert check_swarm.rc == cs.UNKNOWN_RC


def test_check_service_called(check_swarm, fs):
service_info = {'Spec': {'Mode': {'Replicated': {'Replicas': 1}}}}

Expand Down