Skip to content

Commit

Permalink
Merge pull request #1087 from zmrow/pubsys-grant
Browse files Browse the repository at this point in the history
Add `cargo make grant-ami` and `revoke-ami` tasks
  • Loading branch information
tjkirch authored Sep 1, 2020
2 parents 9fc82dd + b6305f9 commit 7842a8a
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 18 deletions.
78 changes: 76 additions & 2 deletions Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,8 @@ pubsys \
--infra-config-path "${PUBLISH_INFRA_CONFIG_PATH}" \
\
publish-ami \
--make-public \
--grant \
--group-names all \
\
--ami-input "${ami_input}" \
${PUBLISH_REGIONS:+--regions "${PUBLISH_REGIONS}"}
Expand Down Expand Up @@ -477,7 +478,80 @@ pubsys \
--infra-config-path "${PUBLISH_INFRA_CONFIG_PATH}" \
\
publish-ami \
--make-private \
--revoke \
--group-names all \
\
--ami-input "${ami_input}" \
${PUBLISH_REGIONS:+--regions "${PUBLISH_REGIONS}"}
'''
]

[tasks.grant-ami]
# Rather than depend on "build", which currently rebuilds images each run, we
# depend on publish-tools and check for the input file below to save time.
# This does mean that `cargo make ami` must be run before `cargo make grant-ami`.
dependencies = ["publish-tools"]
script_runner = "bash"
script = [
'''
set -e
export PATH="${BUILDSYS_TOOLS_DIR}/bin:${PATH}"
if [ -z "${GRANT_TO_USERS}" ] && [ -z "${GRANT_TO_GROUPS}" ]; then
echo "GRANT_TO_USERS and/or GRANT_TO_GROUPS is mandatory for grant-ami; please give a comma-separated list of user IDs or group names" >&2
exit 1
fi
ami_input="${BUILDSYS_OUTPUT_DIR}/${BUILDSYS_NAME_FULL}-amis.json"
if [ ! -s "${ami_input}" ]; then
echo "AMI input file doesn't exist for the current version/commit - ${BUILDSYS_VERSION_FULL} - please run 'cargo make ami'" >&2
exit 1
fi
pubsys \
--infra-config-path "${PUBLISH_INFRA_CONFIG_PATH}" \
\
publish-ami \
--grant \
${GRANT_TO_USERS:+--user-ids "${GRANT_TO_USERS}"} \
${GRANT_TO_GROUPS:+--group-names "${GRANT_TO_GROUPS}"} \
\
--ami-input "${ami_input}" \
${PUBLISH_REGIONS:+--regions "${PUBLISH_REGIONS}"}
'''
]

[tasks.revoke-ami]
# Rather than depend on "build", which currently rebuilds images each run, we
# depend on publish-tools and check for the input file below to save time.
# This does mean that `cargo make ami` must be run before `cargo make revoke-ami`.
dependencies = ["publish-tools"]
script_runner = "bash"
script = [
'''
set -e
export PATH="${BUILDSYS_TOOLS_DIR}/bin:${PATH}"
if [ -z "${REVOKE_FROM_USERS}" ] && [ -z "${REVOKE_FROM_GROUPS}" ]; then
echo "REVOKE_FROM_USERS and/or REVOKE_FROM_GROUPS is mandatory for revoke-ami; please give a comma-separated list of user IDs or group names" >&2
exit 1
fi
ami_input="${BUILDSYS_OUTPUT_DIR}/${BUILDSYS_NAME_FULL}-amis.json"
if [ ! -s "${ami_input}" ]; then
echo "AMI input file doesn't exist for the current version/commit - ${BUILDSYS_VERSION_FULL} - please run 'cargo make ami'" >&2
exit 1
fi
pubsys \
--infra-config-path "${PUBLISH_INFRA_CONFIG_PATH}" \
\
publish-ami \
--revoke \
${REVOKE_FROM_USERS:+--user-ids "${REVOKE_FROM_USERS}"} \
${REVOKE_FROM_GROUPS:+--group-names "${REVOKE_FROM_GROUPS}"} \
\
--ami-input "${ami_input}" \
${PUBLISH_REGIONS:+--regions "${PUBLISH_REGIONS}"}
Expand Down
53 changes: 37 additions & 16 deletions tools/pubsys/src/aws/publish_ami/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! The publish_ami module owns the 'publish-ami' subcommand and controls the process of granting
//! and revoking public access to EC2 AMIs.
//! and revoking access to EC2 AMIs.
use crate::aws::ami::wait::{self, wait_for_ami};
use crate::aws::ami::Image;
Expand All @@ -26,6 +26,7 @@ use structopt::StructOpt;
#[derive(Debug, StructOpt)]
#[structopt(setting = clap::AppSettings::DeriveDisplayOrder)]
#[structopt(group = clap::ArgGroup::with_name("mode").required(true).multiple(false))]
#[structopt(group = clap::ArgGroup::with_name("who").required(true).multiple(true))]
pub(crate) struct PublishArgs {
/// Path to the JSON file containing regional AMI IDs to modify
#[structopt(long)]
Expand All @@ -36,22 +37,29 @@ pub(crate) struct PublishArgs {
#[structopt(long, use_delimiter = true)]
regions: Vec<String>,

/// Make the AMIs public
/// Grant access to the given users/groups
#[structopt(long, group = "mode")]
make_public: bool,
/// Make the AMIs private
grant: bool,
/// Revoke access from the given users/groups
#[structopt(long, group = "mode")]
make_private: bool,
revoke: bool,

/// User IDs to give/remove access
#[structopt(long, use_delimiter = true, group = "who")]
user_ids: Vec<String>,
/// Group names to give/remove access
#[structopt(long, use_delimiter = true, group = "who")]
group_names: Vec<String>,
}

/// Common entrypoint from main()
pub(crate) async fn run(args: &Args, publish_args: &PublishArgs) -> Result<()> {
let (operation, mode) = if publish_args.make_public {
("add".to_string(), "public")
} else if publish_args.make_private {
("remove".to_string(), "private")
let (operation, description) = if publish_args.grant {
("add".to_string(), "granting access")
} else if publish_args.revoke {
("remove".to_string(), "revoking access")
} else {
unreachable!("developer error: make-public and make-private not required/exclusive");
unreachable!("developer error: --grant and --revoke not required/exclusive");
};

info!(
Expand Down Expand Up @@ -165,16 +173,29 @@ pub(crate) async fn run(args: &Args, publish_args: &PublishArgs) -> Result<()> {
let snapshots = get_regional_snapshots(&amis, &ec2_clients).await?;
trace!("Found snapshots: {:?}", snapshots);

let all = Some(vec!["all".to_string()]);
info!("Updating snapshot permissions - making {}", mode);
modify_regional_snapshots(None, all.clone(), &operation, &snapshots, &ec2_clients).await?;

info!("Updating image permissions - making {}", mode);
info!("Updating snapshot permissions - {}", description);
modify_regional_snapshots(
Some(publish_args.user_ids.clone()),
Some(publish_args.group_names.clone()),
&operation,
&snapshots,
&ec2_clients,
)
.await?;

info!("Updating image permissions - {}", description);
let ami_ids = amis
.into_iter()
.map(|(region, image)| (region, image.id))
.collect();
modify_regional_images(None, all, &operation, &ami_ids, &ec2_clients).await?;
modify_regional_images(
Some(publish_args.user_ids.clone()),
Some(publish_args.group_names.clone()),
&operation,
&ami_ids,
&ec2_clients,
)
.await?;

Ok(())
}
Expand Down

0 comments on commit 7842a8a

Please sign in to comment.