-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move s3-credentials check command to ch-monitoring (#264)
* Move s3-credentials check command to ch-monitoring * Update tests
- Loading branch information
1 parent
bd8912a
commit 3db97cb
Showing
7 changed files
with
175 additions
and
161 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
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
This file was deleted.
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,85 @@ | ||
import json | ||
import random | ||
import sys | ||
import time | ||
from xml.dom import minidom | ||
|
||
import requests | ||
from click import group, option, pass_context | ||
|
||
from ch_tools.chadmin.cli.chadmin_group import Chadmin | ||
from ch_tools.chadmin.internal.system import match_ch_version | ||
|
||
|
||
@group("s3-credentials-config", cls=Chadmin) | ||
@option( | ||
"-m", | ||
"--metadata-address", | ||
"metadata_address", | ||
default="169.254.169.254", | ||
help="Compute metadata api address.", | ||
) | ||
@pass_context | ||
def s3_credentials_config_group(ctx, metadata_address): | ||
""" | ||
Manage default ClickHouse s3 credentials. | ||
""" | ||
ctx.obj["s3_cred_metadata_addr"] = metadata_address | ||
|
||
|
||
def _add_node(document, root, name): | ||
node = document.createElement(name) | ||
root.appendChild(node) | ||
return node | ||
|
||
|
||
def _request_token(endpoint): | ||
# pylint: disable=missing-timeout | ||
return requests.get( | ||
f"http://{endpoint}/computeMetadata/v1/instance/service-accounts/default/token", | ||
headers={"Metadata-Flavor": "Google"}, | ||
) | ||
|
||
|
||
def _get_token(endpoint): | ||
response = _request_token(endpoint) | ||
if response.status_code != 200: | ||
sys.exit(1) | ||
data = json.loads(response.content) | ||
if data["token_type"] != "Bearer": | ||
sys.exit(1) | ||
return data["access_token"] | ||
|
||
|
||
@s3_credentials_config_group.command( | ||
"update", help="update ch default s3 credentials config" | ||
) | ||
@option("-e", "--endpoint", "endpoint", type=str, help="S3 endpoint") | ||
@option( | ||
"-s", | ||
"--random-sleep", | ||
"random_sleep", | ||
default=False, | ||
help="whether need a random sleep", | ||
) | ||
@pass_context | ||
def update_s3_credentials(ctx, endpoint, random_sleep): | ||
"""Update s3 creds.""" | ||
if random_sleep: | ||
time.sleep(random.randint(0, 30)) | ||
|
||
doc = minidom.Document() | ||
storage = _add_node( | ||
doc, _add_node(doc, _add_node(doc, doc, "clickhouse"), "s3"), "cloud_storage" | ||
) | ||
endpoint_header = ( | ||
"access_header" if match_ch_version(ctx, min_version="24.11") else "header" | ||
) | ||
_add_node(doc, storage, "endpoint").appendChild(doc.createTextNode(endpoint)) | ||
_add_node(doc, storage, endpoint_header).appendChild( | ||
doc.createTextNode( | ||
f"X-YaCloud-SubjectToken: {_get_token(ctx.obj['s3_cred_metadata_addr'])}" | ||
) | ||
) | ||
with open("/etc/clickhouse-server/config.d/s3_credentials.xml", "wb") as file: | ||
file.write(doc.toprettyxml(indent=4 * " ", encoding="utf-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,80 @@ | ||
import os | ||
import time | ||
from datetime import timedelta | ||
|
||
import requests | ||
from click import pass_context | ||
from cloup import command, option | ||
|
||
from ch_tools.common.clickhouse.config.path import ( | ||
CLICKHOUSE_RESETUP_CONFIG_PATH, | ||
CLICKHOUSE_S3_CREDENTIALS_CONFIG_PATH, | ||
) | ||
from ch_tools.common.result import CRIT, OK, WARNING, Result | ||
|
||
|
||
@command("s3-credentials-config") | ||
@option( | ||
"-p", | ||
"--present", | ||
default=False, | ||
is_flag=True, | ||
help="whether config expected to present", | ||
) | ||
@pass_context | ||
def s3_credentials_configs_command(ctx, present): | ||
""" | ||
Check S3 credentials config. | ||
""" | ||
if not present: | ||
if not os.path.exists(CLICKHOUSE_S3_CREDENTIALS_CONFIG_PATH): | ||
return Result(OK) | ||
return Result(CRIT, "S3 default config present, but shouldn't") | ||
|
||
if os.path.isfile(CLICKHOUSE_RESETUP_CONFIG_PATH): | ||
return Result(OK, "Skipped as resetup is in progress") | ||
|
||
if os.path.exists(CLICKHOUSE_S3_CREDENTIALS_CONFIG_PATH): | ||
delta = timedelta( | ||
seconds=time.time() | ||
- os.path.getmtime(CLICKHOUSE_S3_CREDENTIALS_CONFIG_PATH) | ||
) | ||
if delta < timedelta(hours=2): | ||
return Result(OK) | ||
if delta < timedelta(hours=4): | ||
return Result( | ||
WARNING, | ||
f"S3 token expire in {_delta_to_hours(timedelta(hours=12) - delta)} hours", | ||
) | ||
|
||
if delta < timedelta(hours=12): | ||
msg = f"S3 token expire in {_delta_to_hours(timedelta(hours=12) - delta)} hours" | ||
else: | ||
msg = f"S3 token expired {_delta_to_hours(delta - timedelta(hours=12))} hours ago" | ||
else: | ||
msg = "S3 default config not present" | ||
|
||
code = _request_token(ctx.obj["s3_cred_metadata_addr"]).status_code | ||
if code == 404: | ||
if "default" in requests.get( | ||
f"http://{ctx.obj['s3_cred_metadata_addr']}/computeMetadata/v1/instance/?recursive=true", | ||
headers={"Metadata-Flavor": "Google"}, | ||
timeout=60, | ||
).json().get("serviceAccounts", {}): | ||
return Result(WARNING, "service account deleted") | ||
|
||
return Result(CRIT, "service account not linked") | ||
|
||
return Result(CRIT, f"{msg}, iam code {code}") | ||
|
||
|
||
def _request_token(endpoint): | ||
# pylint: disable=missing-timeout | ||
return requests.get( | ||
f"http://{endpoint}/computeMetadata/v1/instance/service-accounts/default/token", | ||
headers={"Metadata-Flavor": "Google"}, | ||
) | ||
|
||
|
||
def _delta_to_hours(delta: timedelta) -> str: | ||
return f"{(delta.total_seconds() / 3600):.2f}" |
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
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