Skip to content

Commit

Permalink
Merge pull request bottlerocket-os#4271 from ginglis13/port-aws-confi…
Browse files Browse the repository at this point in the history
…g-helper
  • Loading branch information
ginglis13 authored Oct 29, 2024
2 parents d63c795 + 0611157 commit 10f658a
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 0 deletions.
133 changes: 133 additions & 0 deletions sources/api/schnauzer/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,82 @@ pub fn tuf_prefix(
Ok(())
}

/// The `aws-config` helper is used to create an AWS config file
/// with `use_fips_endpoint` value set based on if the variant is FIPS enabled.
///
/// # Fallback
///
/// If this helper runs and `settings.aws.config` is set or `settings.aws.config`
/// is set to a profile other than "default" the helper will return early, leaving the
/// existing `settings.aws.config` setting in place.
///
/// # Example
///
/// The AWS config value is generated via
/// `{{ aws-config settings.aws.config settings.aws.profile }}`
///
/// This would result in something like:
/// ```toml
/// [default]
/// use_fips_endpoint=false
/// ```
///
/// The helper will then base64 encode this content and set as `settings.aws.config`.
pub fn aws_config(
helper: &Helper<'_, '_>,
_: &Handlebars,
_: &Context,
renderctx: &mut RenderContext<'_, '_>,
out: &mut dyn Output,
) -> Result<(), RenderError> {
trace!("Starting aws-config helper");
let template_name = template_name(renderctx);

check_param_count(helper, template_name, 2)?;

let aws_config = get_param(helper, 0)?;
if !aws_config.is_null() {
trace!("settings.aws.config already configured. Exiting aws-config helper early");
return Ok(());
}

// settings.aws.profile may be null. If so, we'll use the "default" profile in constructing
// the AWS config.
let aws_profile = match get_param(helper, 1)? {
Value::Null => "default",
Value::String(s) => s,

_ => {
return Err(RenderError::from(
error::TemplateHelperError::InvalidTemplateValue {
expected: "string",
value: get_param(helper, 1)?.to_owned(),
template: template_name.to_owned(),
},
))
}
};

if aws_profile != "default" {
return Ok(());
}

// construct the base64 encoded AWS config
let aws_config_str = format!(
r#"[default]
use_fips_endpoint={}"#,
fips_enabled()
);
let new_aws_config = base64::engine::general_purpose::STANDARD.encode(&aws_config_str);

out.write(&new_aws_config)
.with_context(|_| error::TemplateWriteSnafu {
template: template_name.to_owned(),
})?;

Ok(())
}

/// Utility function to determine if a variant is in FIPS mode based
/// on /proc/sys/crypto/fips_enabled.
fn fips_enabled() -> bool {
Expand Down Expand Up @@ -2458,6 +2534,63 @@ mod test_tuf_repository {
}
}

#[cfg(test)]
mod test_aws_config_fips_endpoint {
use super::*;
use handlebars::RenderError;
use serde::Serialize;
use serde_json::json;

// A thin wrapper around the handlebars render_template method that includes
// setup and registration of helpers
fn setup_and_render_template<T>(tmpl: &str, data: &T) -> Result<String, RenderError>
where
T: Serialize,
{
let mut aws_config_helper = Handlebars::new();
aws_config_helper.register_helper("aws-config", Box::new(aws_config));

aws_config_helper.render_template(tmpl, data)
}

const METADATA_TEMPLATE: &str = "{{ aws-config settings.aws.config settings.aws.profile }}";

// base64 encoded string:
// [default]
// use_fips_endpoint=false
const EXPECTED_CONFIG_DEFAULT: &str = "W2RlZmF1bHRdCnVzZV9maXBzX2VuZHBvaW50PWZhbHNl";

#[test]
fn config_default() {
let result = setup_and_render_template(
METADATA_TEMPLATE,
&json!({"settings": {"aws": {"profile": "default"}}}),
)
.unwrap();
assert_eq!(result, EXPECTED_CONFIG_DEFAULT);
}

#[test]
fn config_already_exists() {
let result = setup_and_render_template(
METADATA_TEMPLATE,
&json!({"settings": {"aws": {"profile": "default", "config": "abc"}}}),
)
.unwrap();
assert_eq!(result, "");
}

#[test]
fn config_non_default_profile() {
let result = setup_and_render_template(
METADATA_TEMPLATE,
&json!({"settings": {"aws": {"profile": "custom"}}}),
)
.unwrap();
assert_eq!(result, "");
}
}

#[cfg(test)]
mod test_host {
use super::*;
Expand Down
1 change: 1 addition & 0 deletions sources/api/schnauzer/src/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ pub fn build_template_registry() -> Result<handlebars::Handlebars<'static>> {
template_registry.register_helper("join_node_taints", Box::new(helpers::join_node_taints));
template_registry.register_helper("default", Box::new(helpers::default));
template_registry.register_helper("ecr-prefix", Box::new(helpers::ecr_prefix));
template_registry.register_helper("aws-config", Box::new(helpers::aws_config));
template_registry.register_helper("tuf-prefix", Box::new(helpers::tuf_prefix));
template_registry.register_helper("metadata-prefix", Box::new(helpers::metadata_prefix));
template_registry.register_helper("host", Box::new(helpers::host));
Expand Down
1 change: 1 addition & 0 deletions sources/api/schnauzer/src/v2/import/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ fn all_helpers() -> HashMap<ExtensionName, HashMap<HelperName, Box<dyn HelperDef
hashmap! {
"aws" => hashmap! {
"ecr-prefix" => helper!(handlebars_helpers::ecr_prefix),
"aws-config" => helper!(handlebars_helpers::aws_config),
},

"ecs" => hashmap! {
Expand Down

0 comments on commit 10f658a

Please sign in to comment.