Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup Telegraf in provisioner #279

Merged
merged 15 commits into from
May 22, 2023
Merged
44 changes: 22 additions & 22 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -25,37 +25,37 @@ common --enable_bzlmod=true
build --@io_bazel_rules_docker//transitions:enable=false

# Enable builds without the bytes https://github.com/bazelbuild/bazel/issues/6862
build:remote --remote_download_minimal
build:buildbuddy --remote_download_minimal

# From https://www.buildbuddy.io/docs/cloud
# Use BuildBuddy
build --bes_results_url=https://app.buildbuddy.io/invocation/
build --bes_backend=grpcs://remote.buildbuddy.io
build --remote_cache=grpcs://remote.buildbuddy.io
build --remote_timeout=3600
build:buildbuddy --bes_results_url=https://app.buildbuddy.io/invocation/
build:buildbuddy --bes_backend=grpcs://remote.buildbuddy.io
build:buildbuddy --remote_cache=grpcs://remote.buildbuddy.io
build:buildbuddy --remote_timeout=3600

# Suggestions from BuildBuddy
build --experimental_remote_build_event_upload=minimal
build --experimental_remote_cache_compression
build --experimental_stream_log_file_uploads
build:buildbuddy --experimental_remote_build_event_upload=minimal
build:buildbuddy --experimental_remote_cache_compression
build:buildbuddy --experimental_stream_log_file_uploads
common --nolegacy_important_outputs

# For BuildBuddy Remote Build Execution
build:remote --remote_executor=grpcs://remote.buildbuddy.io
build:remote --host_platform=@buildbuddy_toolchain//:platform
build:remote --platforms=@buildbuddy_toolchain//:platform
build:remote --extra_execution_platforms=@buildbuddy_toolchain//:platform
build:remote --crosstool_top=@buildbuddy_toolchain//:toolchain
build:remote --extra_toolchains=@buildbuddy_toolchain//:cc_toolchain
build:remote --javabase=@buildbuddy_toolchain//:javabase_jdk8
build:remote --host_javabase=@buildbuddy_toolchain//:javabase_jdk8
build:remote --java_toolchain=@buildbuddy_toolchain//:toolchain_jdk8
build:remote --host_java_toolchain=@buildbuddy_toolchain//:toolchain_jdk8
build:remote --define=EXECUTOR=remote
build:remote --jobs=50
build:buildbuddy_rbe --remote_executor=grpcs://remote.buildbuddy.io
build:buildbuddy_rbe --host_platform=@buildbuddy_toolchain//:platform
build:buildbuddy_rbe --platforms=@buildbuddy_toolchain//:platform
build:buildbuddy_rbe --extra_execution_platforms=@buildbuddy_toolchain//:platform
build:buildbuddy_rbe --crosstool_top=@buildbuddy_toolchain//:toolchain
build:buildbuddy_rbe --extra_toolchains=@buildbuddy_toolchain//:cc_toolchain
build:buildbuddy_rbe --javabase=@buildbuddy_toolchain//:javabase_jdk8
build:buildbuddy_rbe --host_javabase=@buildbuddy_toolchain//:javabase_jdk8
build:buildbuddy_rbe --java_toolchain=@buildbuddy_toolchain//:toolchain_jdk8
build:buildbuddy_rbe --host_java_toolchain=@buildbuddy_toolchain//:toolchain_jdk8
build:buildbuddy_rbe --define=EXECUTOR=remote
build:buildbuddy_rbe --jobs=50
# To make the remote build work from macbook M1 (https://buildbuddy.slack.com/archives/CUHBFVATU/p1651609573695259?thread_ts=1651609249.864879&cid=CUHBFVATU)
build:remote --host_cpu=k8
build:remote --cpu=k8
build:buildbuddy_rbe --host_cpu=k8
build:buildbuddy_rbe --cpu=k8

# The CI has some specific configuration which we only want to load in the CI
try-import %workspace%/ci.bazelrc
Expand Down
14 changes: 12 additions & 2 deletions buildbuddy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,17 @@ actions:
branches:
- "*"
bazel_commands:
- "test //... @rules_task//... --config remote"
- "test //... @rules_task//... --config buildbuddy --config buildbuddy_rbe"

- name: "Test Teleport connection"
user: buildbuddy
container_image: "ubuntu-20.04"
triggers:
pull_request:
branches:
- "*"
bazel_commands:
- "run //tools/teleport:connection_test --config buildbuddy"

- name: "Deploy provisioner"
user: buildbuddy
Expand All @@ -20,4 +30,4 @@ actions:
branches:
- "master"
bazel_commands:
- "run //provisioner:deploy"
- "run //provisioner:deploy --config buildbuddy"
6 changes: 6 additions & 0 deletions provisioner/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,27 @@ pyinfra_run(
srcs = [
"connectors/teleport.py",
"deploys/microk8s/tasks/install_microk8s.py",
"deploys/monitoring/tasks/install_monitoring.py",
"deploys/network/tasks/install_network.py",
"deploys/teleport/tasks/install_teleport.py",
"group_data/dev.py",
"group_data/prod.py",
"group_data/test.py",
"utils.py",
],
args = [
"--data install_network=True",
"--data install_monitoring=True",
"--data install_microk8s=True",
"--data install_teleport=True",
],
data = [
"deploys/microk8s/files/cmdline.txt",
"deploys/monitoring/files/json_file_output.conf",
"deploys/monitoring/files/telegraf.conf",
"deploys/network/files/99_config.yaml",
"deploys/teleport/files/teleport.yaml.j2",
"deploys/teleport/files/teleport_health_check.conf",
],
deploy = "deploy.py",
env = {
Expand Down
118 changes: 21 additions & 97 deletions provisioner/connectors/teleport.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,23 +70,6 @@ def ssh(self, command):
]
return StringCommand(*args)

def scp_upload(self, local_file, remote_file):
remote_file = f"{self.teleport_host}:{remote_file}"
return self.scp(local_file, remote_file)

def scp_download(self, remote_file, local_file):
remote_file = f"{self.teleport_host}:{remote_file}"
return self.scp(remote_file, local_file)

def scp(self, from_file, to_file):
args = [
*self._get_connection_args(),
"scp",
from_file,
to_file,
]
return StringCommand(*args)

def _get_connection_args(self):
args = [self.tsh_binary]

Expand Down Expand Up @@ -167,14 +150,27 @@ def run_shell_command(
)


def _put_file(host, filename_or_io, temp_file):
def _put_file(host, state, filename_or_io, temp_file):
teleport_client = host.connector_data["teleport_client"]
local.shell(
teleport_client.scp_upload(
local_file=filename_or_io,
remote_file=temp_file,

with get_file_io(filename_or_io) as file_io:
stdin = file_io.read().decode("utf-8")

teleport_command = teleport_client.ssh(
command=f"'cat > {temp_file}'"
).get_raw_value()
)

run_local_shell_command(
state,
host,
teleport_command,
timeout=10,
stdin=stdin,
success_exit_codes=[0],
print_output=False,
print_input=False,
return_combined_output=False,
)


# Inspired by https://github.com/Fizzadar/pyinfra/blob/6eca1a52d955a0497cd33c02cb9a94176f93583d/pyinfra/connectors/ssh.py#L493
Expand Down Expand Up @@ -203,7 +199,7 @@ def put_file(
if sudo or doas or su_user:
# Get temp file location
temp_file = remote_temp_filename or state.get_temp_filename(remote_filename)
_put_file(host, filename_or_io, temp_file)
_put_file(host, state, filename_or_io, temp_file)

# Make sure our sudo/su user can access the file
if su_user:
Expand Down Expand Up @@ -290,16 +286,6 @@ def put_file(
return True


def _get_file(host: "Host", remote_filename: str, filename_or_io):
teleport_client = host.connector_data["teleport_client"]
local.shell(
teleport_client.scp_download(
local_file=filename_or_io,
remote_file=remote_filename,
).get_raw_value()
)


def get_file(
state: "State",
host: "Host",
Expand All @@ -313,66 +299,4 @@ def get_file(
print_input: bool = False,
**command_kwargs,
):
"""
Download a file from the remote host using SFTP. Supports download files
with sudo by copying to a temporary directory with read permissions,
downloading and then removing the copy.
"""

if sudo or su_user:
# Get temp file location
temp_file = remote_temp_filename or state.get_temp_filename(remote_filename)

# Copy the file to the tempfile location and add read permissions
command = "cp {0} {1} && chmod +r {0}".format(remote_filename, temp_file)

copy_status, _, stderr = run_shell_command(
state,
host,
command,
sudo=sudo,
sudo_user=sudo_user,
su_user=su_user,
print_output=print_output,
print_input=print_input,
**command_kwargs,
)

if copy_status is False:
logger.error("File download copy temp error: {0}".format("\n".join(stderr)))
return False

try:
_get_file(host, temp_file, filename_or_io)

# Ensure that, even if we encounter an error, we (attempt to) remove the
# temporary copy of the file.
finally:
remove_status, _, stderr = run_shell_command(
state,
host,
"rm -f {0}".format(temp_file),
sudo=sudo,
sudo_user=sudo_user,
su_user=su_user,
print_output=print_output,
print_input=print_input,
**command_kwargs,
)

if remove_status is False:
logger.error(
"File download remove temp error: {0}".format("\n".join(stderr))
)
return False

else:
_get_file(host, remote_filename, filename_or_io)

if print_output:
click.echo(
"{0}file downloaded: {1}".format(host.print_prefix, remote_filename),
err=True,
)

return True
raise NotImplementedError
21 changes: 21 additions & 0 deletions provisioner/deploy.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
from provisioner.deploys.network.tasks.install_network import install_network
from provisioner.deploys.microk8s.tasks.install_microk8s import install_microk8s
from provisioner.deploys.teleport.tasks.install_teleport import install_teleport
from provisioner.deploys.monitoring.tasks.install_monitoring import install_monitoring
from provisioner.utils import wait_for_reconnect

from pyinfra import host
from pyinfra.facts.files import File
from pyinfra.operations import server

if host.get_fact(File, "/var/run/reboot-required"):
server.reboot(
name="Reboot required. Rebooting the server and wait to reconnect",
delay=60,
reboot_timeout=600,
_sudo=True,
_ignore_errors=True, # restarting the service will disconnect us and result in error
)

wait_for_reconnect(
name="Wait for teleport to reconnect",
)

if host.data.get("install_network"):
install_network()

if host.data.get("install_monitoring"):
install_monitoring()

if host.data.get("install_teleport"):
install_teleport()

Expand Down
7 changes: 7 additions & 0 deletions provisioner/deploys/monitoring/files/json_file_output.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[[outputs.file]]
files = ["/tmp/metrics.out"]
data_format = "json"
json_timestamp_units = "1s"
rotation_interval = "1h"
rotation_max_size = "250MB"
rotation_max_archives = 24
Loading