use std::error::Error;
use std::fmt;
#[allow(warnings)]
use futures::future;
use futures::Future;
use rusoto_core::credential::ProvideAwsCredentials;
use rusoto_core::region;
use rusoto_core::request::{BufferedHttpResponse, DispatchSignedRequest};
use rusoto_core::{Client, RusotoError, RusotoFuture};
use rusoto_core::proto;
use rusoto_core::signature::SignedRequest;
use serde_json;
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
pub struct AssociateMemberAccountRequest {
#[serde(rename = "memberAccountId")]
pub member_account_id: String,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
pub struct AssociateS3ResourcesRequest {
#[serde(rename = "memberAccountId")]
#[serde(skip_serializing_if = "Option::is_none")]
pub member_account_id: Option<String>,
#[serde(rename = "s3Resources")]
pub s_3_resources: Vec<S3ResourceClassification>,
}
#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
#[cfg_attr(test, derive(Serialize))]
pub struct AssociateS3ResourcesResult {
#[serde(rename = "failedS3Resources")]
#[serde(skip_serializing_if = "Option::is_none")]
pub failed_s3_resources: Option<Vec<FailedS3Resource>>,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ClassificationType {
#[serde(rename = "continuous")]
pub continuous: String,
#[serde(rename = "oneTime")]
pub one_time: String,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
pub struct ClassificationTypeUpdate {
#[serde(rename = "continuous")]
#[serde(skip_serializing_if = "Option::is_none")]
pub continuous: Option<String>,
#[serde(rename = "oneTime")]
#[serde(skip_serializing_if = "Option::is_none")]
pub one_time: Option<String>,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
pub struct DisassociateMemberAccountRequest {
#[serde(rename = "memberAccountId")]
pub member_account_id: String,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
pub struct DisassociateS3ResourcesRequest {
#[serde(rename = "associatedS3Resources")]
pub associated_s3_resources: Vec<S3Resource>,
#[serde(rename = "memberAccountId")]
#[serde(skip_serializing_if = "Option::is_none")]
pub member_account_id: Option<String>,
}
#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
#[cfg_attr(test, derive(Serialize))]
pub struct DisassociateS3ResourcesResult {
#[serde(rename = "failedS3Resources")]
#[serde(skip_serializing_if = "Option::is_none")]
pub failed_s3_resources: Option<Vec<FailedS3Resource>>,
}
#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
#[cfg_attr(test, derive(Serialize))]
pub struct FailedS3Resource {
#[serde(rename = "errorCode")]
#[serde(skip_serializing_if = "Option::is_none")]
pub error_code: Option<String>,
#[serde(rename = "errorMessage")]
#[serde(skip_serializing_if = "Option::is_none")]
pub error_message: Option<String>,
#[serde(rename = "failedItem")]
#[serde(skip_serializing_if = "Option::is_none")]
pub failed_item: Option<S3Resource>,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
pub struct ListMemberAccountsRequest {
#[serde(rename = "maxResults")]
#[serde(skip_serializing_if = "Option::is_none")]
pub max_results: Option<i64>,
#[serde(rename = "nextToken")]
#[serde(skip_serializing_if = "Option::is_none")]
pub next_token: Option<String>,
}
#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
#[cfg_attr(test, derive(Serialize))]
pub struct ListMemberAccountsResult {
#[serde(rename = "memberAccounts")]
#[serde(skip_serializing_if = "Option::is_none")]
pub member_accounts: Option<Vec<MemberAccount>>,
#[serde(rename = "nextToken")]
#[serde(skip_serializing_if = "Option::is_none")]
pub next_token: Option<String>,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
pub struct ListS3ResourcesRequest {
#[serde(rename = "maxResults")]
#[serde(skip_serializing_if = "Option::is_none")]
pub max_results: Option<i64>,
#[serde(rename = "memberAccountId")]
#[serde(skip_serializing_if = "Option::is_none")]
pub member_account_id: Option<String>,
#[serde(rename = "nextToken")]
#[serde(skip_serializing_if = "Option::is_none")]
pub next_token: Option<String>,
}
#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
#[cfg_attr(test, derive(Serialize))]
pub struct ListS3ResourcesResult {
#[serde(rename = "nextToken")]
#[serde(skip_serializing_if = "Option::is_none")]
pub next_token: Option<String>,
#[serde(rename = "s3Resources")]
#[serde(skip_serializing_if = "Option::is_none")]
pub s_3_resources: Option<Vec<S3ResourceClassification>>,
}
#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
#[cfg_attr(test, derive(Serialize))]
pub struct MemberAccount {
#[serde(rename = "accountId")]
#[serde(skip_serializing_if = "Option::is_none")]
pub account_id: Option<String>,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct S3Resource {
#[serde(rename = "bucketName")]
pub bucket_name: String,
#[serde(rename = "prefix")]
#[serde(skip_serializing_if = "Option::is_none")]
pub prefix: Option<String>,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct S3ResourceClassification {
#[serde(rename = "bucketName")]
pub bucket_name: String,
#[serde(rename = "classificationType")]
pub classification_type: ClassificationType,
#[serde(rename = "prefix")]
#[serde(skip_serializing_if = "Option::is_none")]
pub prefix: Option<String>,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
pub struct S3ResourceClassificationUpdate {
#[serde(rename = "bucketName")]
pub bucket_name: String,
#[serde(rename = "classificationTypeUpdate")]
pub classification_type_update: ClassificationTypeUpdate,
#[serde(rename = "prefix")]
#[serde(skip_serializing_if = "Option::is_none")]
pub prefix: Option<String>,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
pub struct UpdateS3ResourcesRequest {
#[serde(rename = "memberAccountId")]
#[serde(skip_serializing_if = "Option::is_none")]
pub member_account_id: Option<String>,
#[serde(rename = "s3ResourcesUpdate")]
pub s_3_resources_update: Vec<S3ResourceClassificationUpdate>,
}
#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
#[cfg_attr(test, derive(Serialize))]
pub struct UpdateS3ResourcesResult {
#[serde(rename = "failedS3Resources")]
#[serde(skip_serializing_if = "Option::is_none")]
pub failed_s3_resources: Option<Vec<FailedS3Resource>>,
}
#[derive(Debug, PartialEq)]
pub enum AssociateMemberAccountError {
Internal(String),
InvalidInput(String),
LimitExceeded(String),
}
impl AssociateMemberAccountError {
pub fn from_response(res: BufferedHttpResponse) -> RusotoError<AssociateMemberAccountError> {
if let Some(err) = proto::json::Error::parse(&res) {
match err.typ.as_str() {
"InternalException" => {
return RusotoError::Service(AssociateMemberAccountError::Internal(err.msg))
}
"InvalidInputException" => {
return RusotoError::Service(AssociateMemberAccountError::InvalidInput(err.msg))
}
"LimitExceededException" => {
return RusotoError::Service(AssociateMemberAccountError::LimitExceeded(
err.msg,
))
}
"ValidationException" => return RusotoError::Validation(err.msg),
_ => {}
}
}
return RusotoError::Unknown(res);
}
}
impl fmt::Display for AssociateMemberAccountError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())
}
}
impl Error for AssociateMemberAccountError {
fn description(&self) -> &str {
match *self {
AssociateMemberAccountError::Internal(ref cause) => cause,
AssociateMemberAccountError::InvalidInput(ref cause) => cause,
AssociateMemberAccountError::LimitExceeded(ref cause) => cause,
}
}
}
#[derive(Debug, PartialEq)]
pub enum AssociateS3ResourcesError {
AccessDenied(String),
Internal(String),
InvalidInput(String),
LimitExceeded(String),
}
impl AssociateS3ResourcesError {
pub fn from_response(res: BufferedHttpResponse) -> RusotoError<AssociateS3ResourcesError> {
if let Some(err) = proto::json::Error::parse(&res) {
match err.typ.as_str() {
"AccessDeniedException" => {
return RusotoError::Service(AssociateS3ResourcesError::AccessDenied(err.msg))
}
"InternalException" => {
return RusotoError::Service(AssociateS3ResourcesError::Internal(err.msg))
}
"InvalidInputException" => {
return RusotoError::Service(AssociateS3ResourcesError::InvalidInput(err.msg))
}
"LimitExceededException" => {
return RusotoError::Service(AssociateS3ResourcesError::LimitExceeded(err.msg))
}
"ValidationException" => return RusotoError::Validation(err.msg),
_ => {}
}
}
return RusotoError::Unknown(res);
}
}
impl fmt::Display for AssociateS3ResourcesError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())
}
}
impl Error for AssociateS3ResourcesError {
fn description(&self) -> &str {
match *self {
AssociateS3ResourcesError::AccessDenied(ref cause) => cause,
AssociateS3ResourcesError::Internal(ref cause) => cause,
AssociateS3ResourcesError::InvalidInput(ref cause) => cause,
AssociateS3ResourcesError::LimitExceeded(ref cause) => cause,
}
}
}
#[derive(Debug, PartialEq)]
pub enum DisassociateMemberAccountError {
Internal(String),
InvalidInput(String),
}
impl DisassociateMemberAccountError {
pub fn from_response(res: BufferedHttpResponse) -> RusotoError<DisassociateMemberAccountError> {
if let Some(err) = proto::json::Error::parse(&res) {
match err.typ.as_str() {
"InternalException" => {
return RusotoError::Service(DisassociateMemberAccountError::Internal(err.msg))
}
"InvalidInputException" => {
return RusotoError::Service(DisassociateMemberAccountError::InvalidInput(
err.msg,
))
}
"ValidationException" => return RusotoError::Validation(err.msg),
_ => {}
}
}
return RusotoError::Unknown(res);
}
}
impl fmt::Display for DisassociateMemberAccountError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())
}
}
impl Error for DisassociateMemberAccountError {
fn description(&self) -> &str {
match *self {
DisassociateMemberAccountError::Internal(ref cause) => cause,
DisassociateMemberAccountError::InvalidInput(ref cause) => cause,
}
}
}
#[derive(Debug, PartialEq)]
pub enum DisassociateS3ResourcesError {
AccessDenied(String),
Internal(String),
InvalidInput(String),
}
impl DisassociateS3ResourcesError {
pub fn from_response(res: BufferedHttpResponse) -> RusotoError<DisassociateS3ResourcesError> {
if let Some(err) = proto::json::Error::parse(&res) {
match err.typ.as_str() {
"AccessDeniedException" => {
return RusotoError::Service(DisassociateS3ResourcesError::AccessDenied(
err.msg,
))
}
"InternalException" => {
return RusotoError::Service(DisassociateS3ResourcesError::Internal(err.msg))
}
"InvalidInputException" => {
return RusotoError::Service(DisassociateS3ResourcesError::InvalidInput(
err.msg,
))
}
"ValidationException" => return RusotoError::Validation(err.msg),
_ => {}
}
}
return RusotoError::Unknown(res);
}
}
impl fmt::Display for DisassociateS3ResourcesError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())
}
}
impl Error for DisassociateS3ResourcesError {
fn description(&self) -> &str {
match *self {
DisassociateS3ResourcesError::AccessDenied(ref cause) => cause,
DisassociateS3ResourcesError::Internal(ref cause) => cause,
DisassociateS3ResourcesError::InvalidInput(ref cause) => cause,
}
}
}
#[derive(Debug, PartialEq)]
pub enum ListMemberAccountsError {
Internal(String),
InvalidInput(String),
}
impl ListMemberAccountsError {
pub fn from_response(res: BufferedHttpResponse) -> RusotoError<ListMemberAccountsError> {
if let Some(err) = proto::json::Error::parse(&res) {
match err.typ.as_str() {
"InternalException" => {
return RusotoError::Service(ListMemberAccountsError::Internal(err.msg))
}
"InvalidInputException" => {
return RusotoError::Service(ListMemberAccountsError::InvalidInput(err.msg))
}
"ValidationException" => return RusotoError::Validation(err.msg),
_ => {}
}
}
return RusotoError::Unknown(res);
}
}
impl fmt::Display for ListMemberAccountsError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())
}
}
impl Error for ListMemberAccountsError {
fn description(&self) -> &str {
match *self {
ListMemberAccountsError::Internal(ref cause) => cause,
ListMemberAccountsError::InvalidInput(ref cause) => cause,
}
}
}
#[derive(Debug, PartialEq)]
pub enum ListS3ResourcesError {
AccessDenied(String),
Internal(String),
InvalidInput(String),
}
impl ListS3ResourcesError {
pub fn from_response(res: BufferedHttpResponse) -> RusotoError<ListS3ResourcesError> {
if let Some(err) = proto::json::Error::parse(&res) {
match err.typ.as_str() {
"AccessDeniedException" => {
return RusotoError::Service(ListS3ResourcesError::AccessDenied(err.msg))
}
"InternalException" => {
return RusotoError::Service(ListS3ResourcesError::Internal(err.msg))
}
"InvalidInputException" => {
return RusotoError::Service(ListS3ResourcesError::InvalidInput(err.msg))
}
"ValidationException" => return RusotoError::Validation(err.msg),
_ => {}
}
}
return RusotoError::Unknown(res);
}
}
impl fmt::Display for ListS3ResourcesError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())
}
}
impl Error for ListS3ResourcesError {
fn description(&self) -> &str {
match *self {
ListS3ResourcesError::AccessDenied(ref cause) => cause,
ListS3ResourcesError::Internal(ref cause) => cause,
ListS3ResourcesError::InvalidInput(ref cause) => cause,
}
}
}
#[derive(Debug, PartialEq)]
pub enum UpdateS3ResourcesError {
AccessDenied(String),
Internal(String),
InvalidInput(String),
}
impl UpdateS3ResourcesError {
pub fn from_response(res: BufferedHttpResponse) -> RusotoError<UpdateS3ResourcesError> {
if let Some(err) = proto::json::Error::parse(&res) {
match err.typ.as_str() {
"AccessDeniedException" => {
return RusotoError::Service(UpdateS3ResourcesError::AccessDenied(err.msg))
}
"InternalException" => {
return RusotoError::Service(UpdateS3ResourcesError::Internal(err.msg))
}
"InvalidInputException" => {
return RusotoError::Service(UpdateS3ResourcesError::InvalidInput(err.msg))
}
"ValidationException" => return RusotoError::Validation(err.msg),
_ => {}
}
}
return RusotoError::Unknown(res);
}
}
impl fmt::Display for UpdateS3ResourcesError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())
}
}
impl Error for UpdateS3ResourcesError {
fn description(&self) -> &str {
match *self {
UpdateS3ResourcesError::AccessDenied(ref cause) => cause,
UpdateS3ResourcesError::Internal(ref cause) => cause,
UpdateS3ResourcesError::InvalidInput(ref cause) => cause,
}
}
}
pub trait Macie {
fn associate_member_account(
&self,
input: AssociateMemberAccountRequest,
) -> RusotoFuture<(), AssociateMemberAccountError>;
fn associate_s3_resources(
&self,
input: AssociateS3ResourcesRequest,
) -> RusotoFuture<AssociateS3ResourcesResult, AssociateS3ResourcesError>;
fn disassociate_member_account(
&self,
input: DisassociateMemberAccountRequest,
) -> RusotoFuture<(), DisassociateMemberAccountError>;
fn disassociate_s3_resources(
&self,
input: DisassociateS3ResourcesRequest,
) -> RusotoFuture<DisassociateS3ResourcesResult, DisassociateS3ResourcesError>;
fn list_member_accounts(
&self,
input: ListMemberAccountsRequest,
) -> RusotoFuture<ListMemberAccountsResult, ListMemberAccountsError>;
fn list_s3_resources(
&self,
input: ListS3ResourcesRequest,
) -> RusotoFuture<ListS3ResourcesResult, ListS3ResourcesError>;
fn update_s3_resources(
&self,
input: UpdateS3ResourcesRequest,
) -> RusotoFuture<UpdateS3ResourcesResult, UpdateS3ResourcesError>;
}
#[derive(Clone)]
pub struct MacieClient {
client: Client,
region: region::Region,
}
impl MacieClient {
pub fn new(region: region::Region) -> MacieClient {
MacieClient {
client: Client::shared(),
region,
}
}
pub fn new_with<P, D>(
request_dispatcher: D,
credentials_provider: P,
region: region::Region,
) -> MacieClient
where
P: ProvideAwsCredentials + Send + Sync + 'static,
P::Future: Send,
D: DispatchSignedRequest + Send + Sync + 'static,
D::Future: Send,
{
MacieClient {
client: Client::new_with(credentials_provider, request_dispatcher),
region,
}
}
}
impl Macie for MacieClient {
fn associate_member_account(
&self,
input: AssociateMemberAccountRequest,
) -> RusotoFuture<(), AssociateMemberAccountError> {
let mut request = SignedRequest::new("POST", "macie", &self.region, "/");
request.set_content_type("application/x-amz-json-1.1".to_owned());
request.add_header("x-amz-target", "MacieService.AssociateMemberAccount");
let encoded = serde_json::to_string(&input).unwrap();
request.set_payload(Some(encoded));
self.client.sign_and_dispatch(request, |response| {
if response.status.is_success() {
Box::new(future::ok(::std::mem::drop(response)))
} else {
Box::new(
response.buffer().from_err().and_then(|response| {
Err(AssociateMemberAccountError::from_response(response))
}),
)
}
})
}
fn associate_s3_resources(
&self,
input: AssociateS3ResourcesRequest,
) -> RusotoFuture<AssociateS3ResourcesResult, AssociateS3ResourcesError> {
let mut request = SignedRequest::new("POST", "macie", &self.region, "/");
request.set_content_type("application/x-amz-json-1.1".to_owned());
request.add_header("x-amz-target", "MacieService.AssociateS3Resources");
let encoded = serde_json::to_string(&input).unwrap();
request.set_payload(Some(encoded));
self.client.sign_and_dispatch(request, |response| {
if response.status.is_success() {
Box::new(response.buffer().from_err().and_then(|response| {
proto::json::ResponsePayload::new(&response)
.deserialize::<AssociateS3ResourcesResult, _>()
}))
} else {
Box::new(
response.buffer().from_err().and_then(|response| {
Err(AssociateS3ResourcesError::from_response(response))
}),
)
}
})
}
fn disassociate_member_account(
&self,
input: DisassociateMemberAccountRequest,
) -> RusotoFuture<(), DisassociateMemberAccountError> {
let mut request = SignedRequest::new("POST", "macie", &self.region, "/");
request.set_content_type("application/x-amz-json-1.1".to_owned());
request.add_header("x-amz-target", "MacieService.DisassociateMemberAccount");
let encoded = serde_json::to_string(&input).unwrap();
request.set_payload(Some(encoded));
self.client.sign_and_dispatch(request, |response| {
if response.status.is_success() {
Box::new(future::ok(::std::mem::drop(response)))
} else {
Box::new(response.buffer().from_err().and_then(|response| {
Err(DisassociateMemberAccountError::from_response(response))
}))
}
})
}
fn disassociate_s3_resources(
&self,
input: DisassociateS3ResourcesRequest,
) -> RusotoFuture<DisassociateS3ResourcesResult, DisassociateS3ResourcesError> {
let mut request = SignedRequest::new("POST", "macie", &self.region, "/");
request.set_content_type("application/x-amz-json-1.1".to_owned());
request.add_header("x-amz-target", "MacieService.DisassociateS3Resources");
let encoded = serde_json::to_string(&input).unwrap();
request.set_payload(Some(encoded));
self.client.sign_and_dispatch(request, |response| {
if response.status.is_success() {
Box::new(response.buffer().from_err().and_then(|response| {
proto::json::ResponsePayload::new(&response)
.deserialize::<DisassociateS3ResourcesResult, _>()
}))
} else {
Box::new(response.buffer().from_err().and_then(|response| {
Err(DisassociateS3ResourcesError::from_response(response))
}))
}
})
}
fn list_member_accounts(
&self,
input: ListMemberAccountsRequest,
) -> RusotoFuture<ListMemberAccountsResult, ListMemberAccountsError> {
let mut request = SignedRequest::new("POST", "macie", &self.region, "/");
request.set_content_type("application/x-amz-json-1.1".to_owned());
request.add_header("x-amz-target", "MacieService.ListMemberAccounts");
let encoded = serde_json::to_string(&input).unwrap();
request.set_payload(Some(encoded));
self.client.sign_and_dispatch(request, |response| {
if response.status.is_success() {
Box::new(response.buffer().from_err().and_then(|response| {
proto::json::ResponsePayload::new(&response)
.deserialize::<ListMemberAccountsResult, _>()
}))
} else {
Box::new(
response
.buffer()
.from_err()
.and_then(|response| Err(ListMemberAccountsError::from_response(response))),
)
}
})
}
fn list_s3_resources(
&self,
input: ListS3ResourcesRequest,
) -> RusotoFuture<ListS3ResourcesResult, ListS3ResourcesError> {
let mut request = SignedRequest::new("POST", "macie", &self.region, "/");
request.set_content_type("application/x-amz-json-1.1".to_owned());
request.add_header("x-amz-target", "MacieService.ListS3Resources");
let encoded = serde_json::to_string(&input).unwrap();
request.set_payload(Some(encoded));
self.client.sign_and_dispatch(request, |response| {
if response.status.is_success() {
Box::new(response.buffer().from_err().and_then(|response| {
proto::json::ResponsePayload::new(&response)
.deserialize::<ListS3ResourcesResult, _>()
}))
} else {
Box::new(
response
.buffer()
.from_err()
.and_then(|response| Err(ListS3ResourcesError::from_response(response))),
)
}
})
}
fn update_s3_resources(
&self,
input: UpdateS3ResourcesRequest,
) -> RusotoFuture<UpdateS3ResourcesResult, UpdateS3ResourcesError> {
let mut request = SignedRequest::new("POST", "macie", &self.region, "/");
request.set_content_type("application/x-amz-json-1.1".to_owned());
request.add_header("x-amz-target", "MacieService.UpdateS3Resources");
let encoded = serde_json::to_string(&input).unwrap();
request.set_payload(Some(encoded));
self.client.sign_and_dispatch(request, |response| {
if response.status.is_success() {
Box::new(response.buffer().from_err().and_then(|response| {
proto::json::ResponsePayload::new(&response)
.deserialize::<UpdateS3ResourcesResult, _>()
}))
} else {
Box::new(
response
.buffer()
.from_err()
.and_then(|response| Err(UpdateS3ResourcesError::from_response(response))),
)
}
})
}
}