Source code for infrahouse_toolkit.cli.lib
"""Auxiliary functions for command line tools."""
import json
import boto3
import click
import hcl
from infrahouse_toolkit import DEFAULT_OPEN_ENCODING
DEFAULT_TF_BACKEND_FILE = "terraform.tf"
[docs]def get_bucket(tf_file=DEFAULT_TF_BACKEND_FILE) -> str:
"""
Find bucket name in a Terraform backend configuration.
:param tf_file: Path to the Terraform backend configuration.
:type tf_file: str
:return: Bucket name.
"""
with open(tf_file, encoding=DEFAULT_OPEN_ENCODING) as f_desc:
obj = hcl.load(f_desc)
return obj["terraform"]["backend"]["s3"]["bucket"]
[docs]def get_backend_key(tf_file=DEFAULT_TF_BACKEND_FILE) -> str:
"""
Find terraform state filename in a Terraform backend configuration.
:param tf_file: Path to the Terraform backend configuration.
:type tf_file: str
:return: Path to Terraform state in S3.
"""
with open(tf_file, encoding=DEFAULT_OPEN_ENCODING) as f_desc:
obj = hcl.load(f_desc)
return obj["terraform"]["backend"]["s3"]["key"]
[docs]def get_s3_client(role: str = None):
"""
Get a boto3 S3 client to work with AWS S3.
If a role is given, assume it.
:param role: ARN of a role to be assumed
:return: A boto3 S3 client object
"""
if role:
client = boto3.client("sts")
response = client.assume_role(DurationSeconds=900, RoleArn=role, RoleSessionName="infrahouse-toolkit")
session = boto3.Session(
aws_access_key_id=response["Credentials"]["AccessKeyId"],
aws_secret_access_key=response["Credentials"]["SecretAccessKey"],
aws_session_token=response["Credentials"]["SessionToken"],
)
else:
session = boto3.Session()
return session.client("s3")
[docs]def get_elastic_password(secret_key="elastic_secret"):
"""
Try to extract the password for user elastic from AWS secretsmanager.
If the code runs on an elasticsearch node, there is a secret-id with the password in the custom facts.
Try to extract that secret and return the password.
:param secret_key: A key in the puppet facts map facts["elasticsearch"][<secret_key>].
``elastic_secret`` or ``kibana_system_secret`` are the only supported values.
:type secret_key: str
"""
try:
with open("/etc/puppetlabs/facter/facts.d/custom.json", encoding=DEFAULT_OPEN_ENCODING) as f_custom_facts:
custom_facts = json.load(f_custom_facts)
client = boto3.client("secretsmanager")
response = client.get_secret_value(SecretId=custom_facts["elasticsearch"][secret_key])
return response["SecretString"]
except FileNotFoundError:
return None
[docs]def read_from_file_or_prompt(file_path: str, prompt_text="Enter a secret value and press ENTER") -> str:
"""
Read a string from a file if it exists. If not, prompt a user to enter the string.
Return the string value.
:param file_path: Path to the file.
:type file_path: str
:param prompt_text: What text to show a user.
:type prompt_text: str
:return: The string value whether it was read from the file or entered by teh user.
"""
if file_path:
with open(file_path, encoding=DEFAULT_OPEN_ENCODING) as val_desc:
return val_desc.read()
else:
return click.prompt(prompt_text, hide_input=True)