-
Notifications
You must be signed in to change notification settings - Fork 459
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add metrics queries; have prep-mail read report from URL (#141)
- Loading branch information
Showing
12 changed files
with
352 additions
and
23 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
target/ | ||
.vscode/ | ||
scripts/ |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
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
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 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 |
---|---|---|
@@ -1,40 +1,92 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
|
||
#![deny(warnings)] | ||
|
||
extern crate env_logger; | ||
extern crate futures; | ||
extern crate handlebars; | ||
extern crate hyper; | ||
extern crate hyper_tls; | ||
extern crate serde; | ||
extern crate serde_json; | ||
extern crate snitcher; | ||
extern crate tokio; | ||
extern crate url; | ||
|
||
use std::env; | ||
use std::sync::{Arc, Mutex}; | ||
|
||
use futures::future::{self, Either}; | ||
use futures::Future; | ||
use handlebars::Handlebars; | ||
use hyper::{Client as HyperClient, Method}; | ||
use hyper_tls::HttpsConnector; | ||
use snitcher::client; | ||
use snitcher::connect::HyperClientService; | ||
use snitcher::report::Report; | ||
use url::Url; | ||
|
||
mod error; | ||
|
||
use error::{Error, Result}; | ||
use snitcher::report::Report; | ||
|
||
const REPORT_JSON_KEY: &str = "REPORT_JSON"; | ||
const REPORT_JSON_URL_KEY: &str = "REPORT_JSON_URL"; | ||
const REPORT_TEMPLATE_KEY: &str = "REPORT_TEMPLATE"; | ||
const DEFAULT_REPORT_TEMPLATE: &str = include_str!("mail-template.hbs"); | ||
|
||
fn main() -> Result<()> { | ||
env_logger::init(); | ||
|
||
// read the report JSON from the environment | ||
let report_json = get_env(REPORT_JSON_KEY)?; | ||
let report: Report = serde_json::from_str(&report_json)?; | ||
let template = | ||
get_env(REPORT_TEMPLATE_KEY).unwrap_or_else(|_| String::from(DEFAULT_REPORT_TEMPLATE)); | ||
let report_url = Url::parse(&get_env(REPORT_JSON_URL_KEY)?)?; | ||
|
||
let task = get_report_json(report_url) | ||
.and_then(|report_json| report_json.ok_or(Error::NoReportJsonFound)) | ||
.and_then(|report_json| serde_json::from_str(&report_json).map_err(Error::from)) | ||
.and_then(|report: Report| { | ||
let template = get_env(REPORT_TEMPLATE_KEY) | ||
.unwrap_or_else(|_| String::from(DEFAULT_REPORT_TEMPLATE)); | ||
|
||
// render the template and generate report | ||
let reg = Handlebars::new(); | ||
reg.render_template(&template, &report).map_err(Error::from) | ||
}) | ||
.map(|html| println!("{}", html)); | ||
|
||
// render the template and generate report | ||
let reg = Handlebars::new(); | ||
println!("{}", reg.render_template(&template, &report)?); | ||
let error = Arc::new(Mutex::new(None)); | ||
let error_copy = error.clone(); | ||
tokio::run(task.map_err(move |err| { | ||
*error_copy.lock().unwrap() = Some(err); | ||
})); | ||
|
||
Ok(()) | ||
let lock = Arc::try_unwrap(error).expect("Error lock still has multiple owners."); | ||
let error = lock.into_inner().expect("Error mutex cannot be locked."); | ||
|
||
// we want to propagate any errors we might have encountered from 'main' | ||
// because we want to exit with a non-zero error code when something goes | ||
// wrong | ||
Ok(error.map(|err| Err(err)).unwrap_or_else(|| Ok(()))?) | ||
} | ||
|
||
fn get_env(key: &str) -> Result<String> { | ||
env::var(key).map_err(|_| Error::Env(key.to_string())) | ||
} | ||
|
||
fn get_report_json(report_url: Url) -> impl Future<Item = Option<String>, Error = Error> + Send { | ||
HttpsConnector::new(4) | ||
.map(|connector| { | ||
let path = report_url.path().to_owned(); | ||
let client = client::Client::new( | ||
HyperClientService::new(HyperClient::builder().build(connector)), | ||
report_url, | ||
); | ||
|
||
Either::A( | ||
client | ||
.request_str::<()>(Method::GET, &path, None, None, false) | ||
.map_err(Error::from), | ||
) | ||
}) | ||
.map_err(Error::from) | ||
.unwrap_or_else(|err| Either::B(future::err(err))) | ||
} |
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,180 @@ | ||
#!/bin/bash | ||
|
||
set -e | ||
|
||
SCRIPT_NAME=$(basename "$0") | ||
DIR=$(cd "$(dirname "$0")"/.. && pwd) | ||
DEFAULT_DOCKER_NAMESPACE="microsoft" | ||
DOCKER_NAMESPACE=$DEFAULT_DOCKER_NAMESPACE | ||
DOCKERFILE= | ||
SKIP_PUSH=0 | ||
|
||
usage() | ||
{ | ||
echo "$SCRIPT_NAME [options]" | ||
echo "Note: Depending on the options you might have to run this as root or sudo." | ||
echo "" | ||
echo "options" | ||
echo " -i, --image-name Image name (e.g. snitcher)" | ||
echo " -P, --project Project to build image for. Must be 'snitcher' or 'prep-mail'" | ||
echo " -r, --registry Docker registry required to build, tag and run the module" | ||
echo " -u, --username Docker Registry Username" | ||
echo " -p, --password Docker Username's password" | ||
echo " -n, --namespace Docker namespace (default: $DEFAULT_DOCKER_NAMESPACE)" | ||
echo " -v, --image-version Docker Image Version." | ||
echo "--skip-push Build images, but don't push them" | ||
exit 1; | ||
} | ||
|
||
print_help_and_exit() | ||
{ | ||
echo "Run $SCRIPT_NAME --help for more information." | ||
exit 1 | ||
} | ||
|
||
process_args() | ||
{ | ||
save_next_arg=0 | ||
for arg in "$@" | ||
do | ||
if [ $save_next_arg -eq 1 ]; then | ||
DOCKER_REGISTRY="$arg" | ||
save_next_arg=0 | ||
elif [ $save_next_arg -eq 2 ]; then | ||
DOCKER_USERNAME="$arg" | ||
save_next_arg=0 | ||
elif [ $save_next_arg -eq 3 ]; then | ||
DOCKER_PASSWORD="$arg" | ||
save_next_arg=0 | ||
elif [ $save_next_arg -eq 4 ]; then | ||
DOCKER_IMAGEVERSION="$arg" | ||
save_next_arg=0 | ||
elif [ $save_next_arg -eq 5 ]; then | ||
PROJECT="$arg" | ||
save_next_arg=0 | ||
elif [ $save_next_arg -eq 6 ]; then | ||
DOCKER_IMAGENAME="$arg" | ||
save_next_arg=0 | ||
elif [ $save_next_arg -eq 7 ]; then | ||
DOCKER_NAMESPACE="$arg" | ||
save_next_arg=0 | ||
else | ||
case "$arg" in | ||
"-h" | "--help" ) usage;; | ||
"-r" | "--registry" ) save_next_arg=1;; | ||
"-u" | "--username" ) save_next_arg=2;; | ||
"-p" | "--password" ) save_next_arg=3;; | ||
"-v" | "--image-version" ) save_next_arg=4;; | ||
"-P" | "--project" ) save_next_arg=5;; | ||
"-i" | "--image-name" ) save_next_arg=6;; | ||
"-n" | "--namespace" ) save_next_arg=7;; | ||
"--skip-push" ) SKIP_PUSH=1 ;; | ||
* ) usage;; | ||
esac | ||
fi | ||
done | ||
|
||
if [[ -z ${DOCKER_REGISTRY} ]]; then | ||
echo "Registry parameter invalid" | ||
print_help_and_exit | ||
fi | ||
|
||
if [[ $SKIP_PUSH -eq 0 ]]; then | ||
if [[ -z ${DOCKER_USERNAME} ]]; then | ||
echo "Docker username parameter invalid" | ||
print_help_and_exit | ||
fi | ||
|
||
if [[ -z ${DOCKER_PASSWORD} ]]; then | ||
echo "Docker password parameter invalid" | ||
print_help_and_exit | ||
fi | ||
fi | ||
|
||
if [[ -z ${DOCKER_IMAGENAME} ]]; then | ||
echo "Docker image name parameter invalid" | ||
print_help_and_exit | ||
fi | ||
|
||
if [[ -z ${DOCKER_IMAGEVERSION} ]]; then | ||
echo "Docker image version not found." | ||
print_help_and_exit | ||
fi | ||
|
||
DOCKERFILE="$DIR/$PROJECT/docker/linux/amd64/Dockerfile" | ||
if [[ ! -f $DOCKERFILE ]]; then | ||
echo "No Dockerfile at $DOCKERFILE" | ||
print_help_and_exit | ||
fi | ||
} | ||
|
||
############################################################################### | ||
# Build docker image and push it to private repo | ||
# | ||
# @param[1] - imagename; Name of the docker edge image to publish; Required; | ||
# @param[2] - arch; Arch of base image; Required; | ||
# @param[3] - dockerfile; Path to the dockerfile; Optional; | ||
# Leave as "" and defaults will be chosen. | ||
# @param[4] - context_path; docker context path; Required; | ||
# @param[5] - build_args; docker context path; Optional; | ||
# Leave as "" and no build args will be supplied. | ||
############################################################################### | ||
docker_build_and_tag_and_push() | ||
{ | ||
imagename="$1" | ||
arch="$2" | ||
dockerfile="$3" | ||
context_path="$4" | ||
build_args="${*:5}" | ||
|
||
if [ -z "${imagename}" ] || [ -z "${arch}" ] || [ -z "${context_path}" ]; then | ||
echo "Error: Arguments are invalid [$imagename] [$arch] [$context_path]" | ||
exit 1 | ||
fi | ||
|
||
echo "Building and pushing Docker image $imagename for $arch" | ||
docker_build_cmd="docker build --no-cache" | ||
docker_build_cmd+=" -t $DOCKER_REGISTRY/$DOCKER_NAMESPACE/$imagename:$DOCKER_IMAGEVERSION-linux-$arch" | ||
if [ ! -z "${dockerfile}" ]; then | ||
docker_build_cmd+=" --file $dockerfile" | ||
fi | ||
docker_build_cmd+=" $build_args $context_path" | ||
|
||
echo "Running... $docker_build_cmd" | ||
|
||
if ! $docker_build_cmd; then | ||
echo "Docker build failed with exit code $?" | ||
exit 1 | ||
fi | ||
|
||
if [ $SKIP_PUSH -eq 0 ]; then | ||
docker_push_cmd="docker push $DOCKER_REGISTRY/$DOCKER_NAMESPACE/$imagename:$DOCKER_IMAGEVERSION-linux-$arch" | ||
echo "Running... $docker_push_cmd" | ||
if ! $docker_push_cmd; then | ||
echo "Docker push failed with exit code $?" | ||
exit 1 | ||
fi | ||
fi | ||
} | ||
|
||
process_args "$@" | ||
|
||
# log in to container registry | ||
if [ $SKIP_PUSH -eq 0 ]; then | ||
if ! docker login "$DOCKER_REGISTRY" -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; then | ||
echo "Docker login failed!" | ||
exit 1 | ||
fi | ||
fi | ||
|
||
# push image | ||
docker_build_and_tag_and_push \ | ||
"$DOCKER_IMAGENAME" \ | ||
"amd64" \ | ||
"$DOCKERFILE" \ | ||
"$DIR" \ | ||
"" | ||
|
||
echo "Done building and pushing Docker image $DOCKER_IMAGENAME for $PROJECT" | ||
|
||
exit $? |
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
Oops, something went wrong.