Docker: don't re-register local agent if not needed (#2141)

This commit is contained in:
mmetc 2023-03-27 15:38:38 +02:00 committed by GitHub
parent d769fff1e8
commit f39fbf07fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 108 additions and 30 deletions

View file

@ -19,6 +19,9 @@ RUN apk add --no-cache git gcc libc-dev make bash gettext binutils-gold coreutil
cscli parsers install crowdsecurity/whitelists && \
go install github.com/mikefarah/yq/v4@v4.31.2
# In case we need to remove agents here..
# cscli machines list -o json | yq '.[].machineId' | xargs -r cscli machines delete
FROM alpine:latest as slim
RUN apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community tzdata bash && \

View file

@ -23,6 +23,9 @@ RUN apt-get update && \
cscli parsers install crowdsecurity/whitelists && \
go install github.com/mikefarah/yq/v4@v4.31.2
# In case we need to remove agents here..
# cscli machines list -o json | yq '.[].machineId' | xargs -r cscli machines delete
FROM debian:bullseye-slim as slim
ENV DEBIAN_FRONTEND=noninteractive
@ -50,7 +53,6 @@ COPY --from=build /go/src/crowdsec/docker/config.yaml /staging/etc/crowdsec/conf
RUN yq -n '.url="http://0.0.0.0:8080"' | install -m 0600 /dev/stdin /staging/etc/crowdsec/local_api_credentials.yaml && \
yq eval -i ".plugin_config.group = \"nogroup\"" /staging/etc/crowdsec/config.yaml
ENTRYPOINT /bin/bash docker_start.sh
FROM slim as plugins

View file

@ -185,13 +185,22 @@ elif [ -n "$USE_WAL" ] && isfalse "$USE_WAL"; then
conf_set '.db_config.use_wal = false'
fi
# regenerate local agent credentials (even if agent is disabled, cscli needs a
# connection to the API)
cscli machines delete "$CUSTOM_HOSTNAME" 2>/dev/null || true
lapi_credentials_path=$(conf_get '.api.client.credentials_path')
if isfalse "$DISABLE_LOCAL_API"; then
if isfalse "$USE_TLS" || [ "$CLIENT_CERT_FILE" = "" ]; then
echo "Regenerate local agent credentials"
cscli machines add "$CUSTOM_HOSTNAME" --auto
# generate local agent credentials (even if agent is disabled, cscli needs a
# connection to the API)
if ( isfalse "$USE_TLS" || [ "$CLIENT_CERT_FILE" = "" ] ); then
if yq -e '.login==strenv(CUSTOM_HOSTNAME)' "$lapi_credentials_path" && ( cscli machines list -o json | yq -e 'any_c(.machineId==strenv(CUSTOM_HOSTNAME))' >/dev/null ); then
echo "Local agent already registered"
else
echo "Generate local agent credentials"
# if the db is persistent but the credentials are not, we need to
# delete the old machine to generate new credentials
cscli machines delete "$CUSTOM_HOSTNAME" >/dev/null 2>&1 || true
cscli machines add "$CUSTOM_HOSTNAME" --auto
fi
fi
echo "Check if lapi needs to register an additional agent"
@ -205,8 +214,6 @@ fi
# ----------------
lapi_credentials_path=$(conf_get '.api.client.credentials_path')
conf_set_if "$LOCAL_API_URL" '.url = strenv(LOCAL_API_URL)' "$lapi_credentials_path"
if istrue "$DISABLE_LOCAL_API"; then

View file

@ -0,0 +1,87 @@
#!/usr/bin/env python
from http import HTTPStatus
import pytest
pytestmark = pytest.mark.docker
def test_no_agent(crowdsec, flavor):
"""Test DISABLE_AGENT=true"""
env = {
'DISABLE_AGENT': 'true',
}
with crowdsec(flavor=flavor, environment=env) as cs:
cs.wait_for_log("*CrowdSec Local API listening on 0.0.0.0:8080*")
cs.wait_for_http(8080, '/health', want_status=HTTPStatus.OK)
res = cs.cont.exec_run('cscli lapi status')
assert res.exit_code == 0
stdout = res.output.decode()
assert "You can successfully interact with Local API (LAPI)" in stdout
def test_machine_register(crowdsec, flavor, tmp_path_factory):
"""A local agent is always registered for use by cscli"""
data_dir = tmp_path_factory.mktemp('data')
env = {
'DISABLE_AGENT': 'true',
}
volumes = {
data_dir: {'bind': '/var/lib/crowdsec/data', 'mode': 'rw'},
}
with crowdsec(flavor=flavor, environment=env, volumes=volumes) as cs:
cs.wait_for_log([
"*Generate local agent credentials*",
"*CrowdSec Local API listening on 0.0.0.0:8080*",
])
cs.wait_for_http(8080, '/health', want_status=HTTPStatus.OK)
res = cs.cont.exec_run('cscli lapi status')
assert res.exit_code == 0
stdout = res.output.decode()
assert "You can successfully interact with Local API (LAPI)" in stdout
# The local agent is not registered, because we didn't persist local_api_credentials.yaml
with crowdsec(flavor=flavor, environment=env, volumes=volumes) as cs:
cs.wait_for_log([
"*Generate local agent credentials*",
"*CrowdSec Local API listening on 0.0.0.0:8080*",
])
cs.wait_for_http(8080, '/health', want_status=HTTPStatus.OK)
res = cs.cont.exec_run('cscli lapi status')
assert res.exit_code == 0
stdout = res.output.decode()
assert "You can successfully interact with Local API (LAPI)" in stdout
config_dir = tmp_path_factory.mktemp('config')
volumes[config_dir] = {'bind': '/etc/crowdsec', 'mode': 'rw'}
with crowdsec(flavor=flavor, environment=env, volumes=volumes) as cs:
cs.wait_for_log([
"*Generate local agent credentials*",
"*CrowdSec Local API listening on 0.0.0.0:8080*",
])
cs.wait_for_http(8080, '/health', want_status=HTTPStatus.OK)
res = cs.cont.exec_run('cscli lapi status')
assert res.exit_code == 0
stdout = res.output.decode()
assert "You can successfully interact with Local API (LAPI)" in stdout
# The local agent is now already registered
with crowdsec(flavor=flavor, environment=env, volumes=volumes) as cs:
cs.wait_for_log([
"*Local agent already registered*",
"*CrowdSec Local API listening on 0.0.0.0:8080*",
])
cs.wait_for_http(8080, '/health', want_status=HTTPStatus.OK)
res = cs.cont.exec_run('cscli lapi status')
assert res.exit_code == 0
stdout = res.output.decode()
assert "You can successfully interact with Local API (LAPI)" in stdout

View file

@ -1,21 +0,0 @@
#!/usr/bin/env python
from http import HTTPStatus
import pytest
pytestmark = pytest.mark.docker
def test_no_agent(crowdsec, flavor):
"""Test DISABLE_AGENT=true"""
env = {
'DISABLE_AGENT': 'true',
}
with crowdsec(flavor=flavor, environment=env) as cs:
cs.wait_for_log("*CrowdSec Local API listening on 0.0.0.0:8080*")
cs.wait_for_http(8080, '/health', want_status=HTTPStatus.OK)
res = cs.cont.exec_run('cscli lapi status')
assert res.exit_code == 0
stdout = res.output.decode()
assert "You can successfully interact with Local API (LAPI)" in stdout