-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Anze
committed
Jan 31, 2019
0 parents
commit c33964c
Showing
8 changed files
with
236 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
image: docker:stable | ||
|
||
services: | ||
- docker:dind | ||
|
||
variables: | ||
DOCKER_DRIVER: overlay2 | ||
|
||
stages: | ||
- deploy | ||
|
||
|
||
deploy_to_docker_hub: | ||
stage: deploy | ||
when: manual | ||
only: | ||
# We only want master branch AND when tag looks like 'vX.Y.Z', however GitLab doesn't support conjunctive conditions yet: | ||
# https://gitlab.com/gitlab-org/gitlab-ce/issues/27818 | ||
# refs: | ||
# - master # Yeah, that doesn't work... The job for a commit with a tag and on a master branch is not being created. | ||
# | ||
# However we can mark tags 'v*.*.*' as protected, which also allows us to (somewhat) safely use Private-Token as protected | ||
# CI variable. | ||
variables: | ||
- $CI_COMMIT_TAG =~ /^v[0-9]+[.][0-9]+[.][0-9]+$/ | ||
script: | ||
- apk add --no-cache git | ||
# check that we are deploying the latest version: | ||
- export LAST_KNOWN_VERSION=`git tag -l --sort=-version:refname "v*.*.*" | head -n 1 | tr -d '[:space:]'` | ||
- '[ "$LAST_KNOWN_VERSION" == "$CI_COMMIT_TAG" ] || (echo "Tag does not denote latest known version (which is $LAST_KNOWN_VERSION), aborting!" && exit 1)' | ||
- echo "Deploying..." | ||
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY | ||
- docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_TAG" -t "$CI_REGISTRY_IMAGE:latest" --build-arg VERSION=$CI_COMMIT_TAG --build-arg VCS_REF=$CI_COMMIT_SHA --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') . | ||
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_TAG" | ||
- docker push "$CI_REGISTRY_IMAGE:latest" | ||
- docker rmi grafolean/grafolean:$CI_COMMIT_TAG | ||
- docker rmi grafolean/grafolean:latest | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
FROM python:3.6-alpine | ||
|
||
COPY requirements.txt grafolean-worker-ping.py /opt/ | ||
RUN pip install -r /opt/requirements.txt | ||
RUN echo -e "* * * * * source /etc/environment; export BACKEND_URL BOT_TOKEN; python /opt/grafolean-worker-ping.py > /proc/1/fd/1 2> /proc/1/fd/2\n" > /etc/crontabs/root | ||
|
||
# https://stackoverflow.com/a/47960145/593487 | ||
ENTRYPOINT ["crond", "-f", "-d", "8"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
[[source]] | ||
name = "pypi" | ||
url = "https://pypi.org/simple" | ||
verify_ssl = true | ||
|
||
[dev-packages] | ||
|
||
[packages] | ||
requests = "*" | ||
multiping = "*" | ||
|
||
[requires] | ||
python_version = "3.6" |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
version: '2.1' | ||
services: | ||
|
||
# To run this image, you must create a .env file with following content: | ||
# BACKEND_URL=... # backend API base url (the part before "/api/...") | ||
# BOT_TOKEN=... # bot token | ||
|
||
grafolean-worker-ping: | ||
# If you wish to load an explicit version, change the next line. For example: | ||
# image: grafolean/grafolean-worker-ping:v1.0.0 | ||
image: grafolean/grafolean-worker-ping | ||
build: | ||
context: . | ||
dockerfile: Dockerfile | ||
volumes: | ||
- .env:/etc/environment |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
from collections import defaultdict | ||
from multiping import MultiPing | ||
import os | ||
import requests | ||
import socket | ||
import time | ||
|
||
N_PINGS = 3 | ||
|
||
# This is copy-pasted from multiping package; the reason is that we need to get MultiPing | ||
# instance, because it holds the IP addresses which correspond to the addresses we wanted | ||
# pinged - and the key in ping results is the IP. | ||
def multi_ping(dest_addrs, timeout, retry=0, ignore_lookup_errors=False): | ||
retry_timeout = float(timeout) / (retry + 1) | ||
|
||
mp = MultiPing(dest_addrs, ignore_lookup_errors=ignore_lookup_errors) | ||
|
||
results = {} | ||
retry_count = 0 | ||
while retry_count <= retry: | ||
# Send a batch of pings | ||
mp.send() | ||
single_results, no_results = mp.receive(retry_timeout) | ||
# Add the results from the last sending of pings to the overall results | ||
results.update(single_results) | ||
if not no_results: | ||
# No addresses left? We are done. | ||
break | ||
retry_count += 1 | ||
|
||
return results, no_results, mp | ||
|
||
def get_addr_for_ip_dict(addrs, mp): | ||
# This is complicated, and a hack. Still... mp (MultiPing instance) holds two lists, | ||
# self._dest_addrs and self._unprocessed_targets. List _unprocessed_targets has the addresses | ||
# that couldn't be resolved. Others were resolved, and _dest_addrs has the IPs in the same | ||
# order as original addresses. | ||
resolved_addrs = [a for a in addrs if a not in mp._unprocessed_targets] | ||
ip_to_addr = {k: v for k, v in zip(mp._dest_addrs, resolved_addrs)} | ||
return ip_to_addr | ||
|
||
def do_ping(addrs): | ||
results = defaultdict(list) | ||
mp = None | ||
ip_to_addr = {} | ||
for i in range(N_PINGS): | ||
print(".") | ||
responses, no_responses, mp = multi_ping(addrs, timeout=2, retry=3, ignore_lookup_errors=True) | ||
|
||
# Some addresses (like demo.grafolean.com) resolve to multiple IPs, so each call to multi_ping will | ||
# resolve differently - we must find the new IP addresses every time: | ||
ip_to_addr = get_addr_for_ip_dict(addrs, mp) | ||
|
||
for no_resp in no_responses: | ||
addr = ip_to_addr.get(no_resp, no_resp) | ||
results[addr].append(None) | ||
for resp, t in responses.items(): | ||
addr = ip_to_addr.get(resp, resp) | ||
results[addr].append(t) | ||
|
||
if i < N_PINGS - 1: | ||
time.sleep(1) | ||
return dict(results) | ||
|
||
def send_results_to_grafolean(base_url, account_id, bot_token, results): | ||
url = '{}/api/accounts/{}/values/?b={}'.format(base_url, account_id, bot_token) | ||
values = [] | ||
for ip in results: | ||
for ping_index, ping_time in enumerate(results[ip]): | ||
values.append({ | ||
'p': 'ping.{}.{}.success'.format(ip.replace('.', '_'), ping_index), | ||
'v': 0 if ping_time is None else 1, | ||
}) | ||
if ping_time is not None: | ||
values.append({ | ||
'p': 'ping.{}.{}.rtt'.format(ip.replace('.', '_'), ping_index), | ||
'v': ping_time, | ||
}) | ||
print("Sending results to Grafolean") | ||
r = requests.post(url, json=values) | ||
print(r.text) | ||
r.raise_for_status() | ||
|
||
if __name__ == "__main__": | ||
addrs = ["8.8.8.8", "youtube.com", "127.0.0.1", "demo.grafolean.com", "grafolean.com", "whateverdoeesndfexist.com"] | ||
results = do_ping(addrs) | ||
send_results_to_grafolean(os.environ.get('BACKEND_URL'), 1, os.environ.get('BOT_TOKEN'), results) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
-i https://pypi.org/simple | ||
certifi==2018.11.29 | ||
chardet==3.0.4 | ||
idna==2.8 | ||
multiping==1.1.2 | ||
requests==2.21.0 | ||
urllib3==1.24.1 |