diff --git a/.latest-tag-aws-sdk-go b/.latest-tag-aws-sdk-go index 7d0a264e..b79a4cbe 100644 --- a/.latest-tag-aws-sdk-go +++ b/.latest-tag-aws-sdk-go @@ -1 +1 @@ -release-2024-09-17 +release-2024-09-18 diff --git a/src/aws_cost_explorer.erl b/src/aws_cost_explorer.erl index c533db5b..1f35bfe0 100644 --- a/src/aws_cost_explorer.erl +++ b/src/aws_cost_explorer.erl @@ -1112,6 +1112,7 @@ %% reservation_purchase_recommendation_detail() :: #{ %% <<"AccountId">> => string(), %% <<"AverageNormalizedUnitsUsedPerHour">> => string(), +%% <<"AverageNumberOfCapacityUnitsUsedPerHour">> => string(), %% <<"AverageNumberOfInstancesUsedPerHour">> => string(), %% <<"AverageUtilization">> => string(), %% <<"CurrencyCode">> => string(), @@ -1122,12 +1123,16 @@ %% <<"EstimatedReservationCostForLookbackPeriod">> => string(), %% <<"InstanceDetails">> => instance_details(), %% <<"MaximumNormalizedUnitsUsedPerHour">> => string(), +%% <<"MaximumNumberOfCapacityUnitsUsedPerHour">> => string(), %% <<"MaximumNumberOfInstancesUsedPerHour">> => string(), %% <<"MinimumNormalizedUnitsUsedPerHour">> => string(), +%% <<"MinimumNumberOfCapacityUnitsUsedPerHour">> => string(), %% <<"MinimumNumberOfInstancesUsedPerHour">> => string(), %% <<"RecommendedNormalizedUnitsToPurchase">> => string(), +%% <<"RecommendedNumberOfCapacityUnitsToPurchase">> => string(), %% <<"RecommendedNumberOfInstancesToPurchase">> => string(), %% <<"RecurringStandardMonthlyCost">> => string(), +%% <<"ReservedCapacityDetails">> => reserved_capacity_details(), %% <<"UpfrontCost">> => string() %% } -type reservation_purchase_recommendation_detail() :: #{binary() => any()}. @@ -1641,6 +1646,13 @@ %% } -type elasti_cache_instance_details() :: #{binary() => any()}. +%% Example: +%% dynamo_db_capacity_details() :: #{ +%% <<"CapacityUnits">> => string(), +%% <<"Region">> => string() +%% } +-type dynamo_db_capacity_details() :: #{binary() => any()}. + %% Example: %% list_savings_plans_purchase_recommendation_generation_response() :: #{ %% <<"GenerationSummaryList">> => list(generation_summary()()), @@ -1660,6 +1672,12 @@ %% } -type get_cost_categories_request() :: #{binary() => any()}. +%% Example: +%% reserved_capacity_details() :: #{ +%% <<"DynamoDBCapacityDetails">> => dynamo_db_capacity_details() +%% } +-type reserved_capacity_details() :: #{binary() => any()}. + %% Example: %% reservation_purchase_recommendation_metadata() :: #{ %% <<"AdditionalMetadata">> => string(), diff --git a/src/aws_directory.erl b/src/aws_directory.erl index 95f5795b..5bf896b6 100644 --- a/src/aws_directory.erl +++ b/src/aws_directory.erl @@ -79,6 +79,8 @@ describe_conditional_forwarders/3, describe_directories/2, describe_directories/3, + describe_directory_data_access/2, + describe_directory_data_access/3, describe_domain_controllers/2, describe_domain_controllers/3, describe_event_topics/2, @@ -99,6 +101,8 @@ describe_update_directory/3, disable_client_authentication/2, disable_client_authentication/3, + disable_directory_data_access/2, + disable_directory_data_access/3, disable_ldaps/2, disable_ldaps/3, disable_radius/2, @@ -107,6 +111,8 @@ disable_sso/3, enable_client_authentication/2, enable_client_authentication/3, + enable_directory_data_access/2, + enable_directory_data_access/3, enable_ldaps/2, enable_ldaps/3, enable_radius/2, @@ -525,6 +531,12 @@ %% } -type update_trust_result() :: #{binary() => any()}. +%% Example: +%% describe_directory_data_access_request() :: #{ +%% <<"DirectoryId">> := string() +%% } +-type describe_directory_data_access_request() :: #{binary() => any()}. + %% Example: %% enable_radius_request() :: #{ %% <<"DirectoryId">> := string(), @@ -579,6 +591,12 @@ %% } -type list_schema_extensions_result() :: #{binary() => any()}. +%% Example: +%% enable_directory_data_access_request() :: #{ +%% <<"DirectoryId">> := string() +%% } +-type enable_directory_data_access_request() :: #{binary() => any()}. + %% Example: %% add_tags_to_resource_request() :: #{ %% <<"ResourceId">> := string(), @@ -852,6 +870,12 @@ %% } -type incompatible_settings_exception() :: #{binary() => any()}. +%% Example: +%% enable_directory_data_access_result() :: #{ + +%% } +-type enable_directory_data_access_result() :: #{binary() => any()}. + %% Example: %% tag() :: #{ %% <<"Key">> => string(), @@ -1203,6 +1227,12 @@ %% } -type reset_user_password_request() :: #{binary() => any()}. +%% Example: +%% disable_directory_data_access_request() :: #{ +%% <<"DirectoryId">> := string() +%% } +-type disable_directory_data_access_request() :: #{binary() => any()}. + %% Example: %% trust() :: #{ %% <<"CreatedDateTime">> => non_neg_integer(), @@ -1478,6 +1508,12 @@ %% } -type create_log_subscription_result() :: #{binary() => any()}. +%% Example: +%% describe_directory_data_access_result() :: #{ +%% <<"DataAccessStatus">> => list(any()) +%% } +-type describe_directory_data_access_result() :: #{binary() => any()}. + %% Example: %% directory_limit_exceeded_exception() :: #{ %% <<"Message">> => string(), @@ -1592,6 +1628,12 @@ %% } -type add_tags_to_resource_result() :: #{binary() => any()}. +%% Example: +%% disable_directory_data_access_result() :: #{ + +%% } +-type disable_directory_data_access_result() :: #{binary() => any()}. + %% Example: %% ip_route_info() :: #{ %% <<"AddedDateTime">> => non_neg_integer(), @@ -1926,6 +1968,13 @@ invalid_next_token_exception() | client_exception(). +-type describe_directory_data_access_errors() :: + access_denied_exception() | + service_exception() | + directory_does_not_exist_exception() | + client_exception() | + unsupported_operation_exception(). + -type describe_domain_controllers_errors() :: entity_does_not_exist_exception() | invalid_parameter_exception() | @@ -2004,6 +2053,15 @@ client_exception() | unsupported_operation_exception(). +-type disable_directory_data_access_errors() :: + directory_unavailable_exception() | + access_denied_exception() | + service_exception() | + directory_does_not_exist_exception() | + client_exception() | + directory_in_desired_state_exception() | + unsupported_operation_exception(). + -type disable_ldaps_errors() :: directory_unavailable_exception() | invalid_parameter_exception() | @@ -2034,6 +2092,15 @@ no_available_certificate_exception() | unsupported_operation_exception(). +-type enable_directory_data_access_errors() :: + directory_unavailable_exception() | + access_denied_exception() | + service_exception() | + directory_does_not_exist_exception() | + client_exception() | + directory_in_desired_state_exception() | + unsupported_operation_exception(). + -type enable_ldaps_errors() :: directory_unavailable_exception() | invalid_parameter_exception() | @@ -2819,6 +2886,24 @@ describe_directories(Client, Input, Options) when is_map(Client), is_map(Input), is_list(Options) -> request(Client, <<"DescribeDirectories">>, Input, Options). +%% @doc Obtains status of directory data access enablement through the +%% Directory Service Data API for the specified directory. +-spec describe_directory_data_access(aws_client:aws_client(), describe_directory_data_access_request()) -> + {ok, describe_directory_data_access_result(), tuple()} | + {error, any()} | + {error, describe_directory_data_access_errors(), tuple()}. +describe_directory_data_access(Client, Input) + when is_map(Client), is_map(Input) -> + describe_directory_data_access(Client, Input, []). + +-spec describe_directory_data_access(aws_client:aws_client(), describe_directory_data_access_request(), proplists:proplist()) -> + {ok, describe_directory_data_access_result(), tuple()} | + {error, any()} | + {error, describe_directory_data_access_errors(), tuple()}. +describe_directory_data_access(Client, Input, Options) + when is_map(Client), is_map(Input), is_list(Options) -> + request(Client, <<"DescribeDirectoryDataAccess">>, Input, Options). + %% @doc Provides information about any domain controllers in your directory. -spec describe_domain_controllers(aws_client:aws_client(), describe_domain_controllers_request()) -> {ok, describe_domain_controllers_result(), tuple()} | @@ -3016,6 +3101,24 @@ disable_client_authentication(Client, Input, Options) when is_map(Client), is_map(Input), is_list(Options) -> request(Client, <<"DisableClientAuthentication">>, Input, Options). +%% @doc Deactivates access to directory data via the Directory Service Data +%% API for the specified directory. +-spec disable_directory_data_access(aws_client:aws_client(), disable_directory_data_access_request()) -> + {ok, disable_directory_data_access_result(), tuple()} | + {error, any()} | + {error, disable_directory_data_access_errors(), tuple()}. +disable_directory_data_access(Client, Input) + when is_map(Client), is_map(Input) -> + disable_directory_data_access(Client, Input, []). + +-spec disable_directory_data_access(aws_client:aws_client(), disable_directory_data_access_request(), proplists:proplist()) -> + {ok, disable_directory_data_access_result(), tuple()} | + {error, any()} | + {error, disable_directory_data_access_errors(), tuple()}. +disable_directory_data_access(Client, Input, Options) + when is_map(Client), is_map(Input), is_list(Options) -> + request(Client, <<"DisableDirectoryDataAccess">>, Input, Options). + %% @doc Deactivates LDAP secure calls for the specified directory. -spec disable_ldaps(aws_client:aws_client(), disable_ldaps_request()) -> {ok, disable_ldaps_result(), tuple()} | @@ -3088,6 +3191,24 @@ enable_client_authentication(Client, Input, Options) when is_map(Client), is_map(Input), is_list(Options) -> request(Client, <<"EnableClientAuthentication">>, Input, Options). +%% @doc Enables access to directory data via the Directory Service Data API +%% for the specified directory. +-spec enable_directory_data_access(aws_client:aws_client(), enable_directory_data_access_request()) -> + {ok, enable_directory_data_access_result(), tuple()} | + {error, any()} | + {error, enable_directory_data_access_errors(), tuple()}. +enable_directory_data_access(Client, Input) + when is_map(Client), is_map(Input) -> + enable_directory_data_access(Client, Input, []). + +-spec enable_directory_data_access(aws_client:aws_client(), enable_directory_data_access_request(), proplists:proplist()) -> + {ok, enable_directory_data_access_result(), tuple()} | + {error, any()} | + {error, enable_directory_data_access_errors(), tuple()}. +enable_directory_data_access(Client, Input, Options) + when is_map(Client), is_map(Input), is_list(Options) -> + request(Client, <<"EnableDirectoryDataAccess">>, Input, Options). + %% @doc Activates the switch for the specific directory to always use LDAP %% secure calls. -spec enable_ldaps(aws_client:aws_client(), enable_ldaps_request()) -> @@ -3390,6 +3511,9 @@ remove_tags_from_resource(Client, Input, Options) %% Simple AD %% directory. %% +%% Disabled users will become enabled and can be authenticated following the +%% API call. +%% %% You can reset the password for any user in your directory with the %% following %% exceptions: diff --git a/src/aws_directory_service_data.erl b/src/aws_directory_service_data.erl new file mode 100644 index 00000000..3934a035 --- /dev/null +++ b/src/aws_directory_service_data.erl @@ -0,0 +1,1501 @@ +%% WARNING: DO NOT EDIT, AUTO-GENERATED CODE! +%% See https://github.com/aws-beam/aws-codegen for more details. + +%% @doc Amazon Web Services Directory Service Data is an extension of +%% Directory Service. +%% +%% This API reference provides detailed information +%% about Directory Service Data operations and object types. +%% +%% With Directory Service Data, you can create, read, update, and delete +%% users, groups, and memberships from +%% your Managed Microsoft AD without additional costs and without deploying +%% dedicated management +%% instances. You can also perform built-in object management tasks across +%% directories without +%% direct network connectivity, which simplifies provisioning and access +%% management to achieve +%% fully automated deployments. Directory Service Data supports user and +%% group write operations, such as +%% `CreateUser' and `CreateGroup', within the organizational unit +%% (OU) of +%% your Managed Microsoft AD. Directory Service Data supports read +%% operations, such as `ListUsers' and +%% `ListGroups', on all users, groups, and group memberships within your +%% Managed Microsoft AD and across trusted realms. Directory Service Data +%% supports adding and removing group members in +%% your OU and the Amazon Web Services Delegated Groups OU, so you can grant +%% and deny access to specific roles +%% and permissions. For more information, see Manage users and +%% groups: +%% https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_manage_users_groups.html +%% in the Directory Service Administration Guide. +%% +%% Directory management operations and configuration changes made against the +%% Directory Service +%% API will also reflect in Directory Service Data API with eventual +%% consistency. You can expect a short delay +%% between management changes, such as adding a new directory trust and +%% calling the Directory Service Data API +%% for the newly created trusted realm. +%% +%% Directory Service Data connects to your Managed Microsoft AD domain +%% controllers and performs operations on +%% underlying directory objects. When you create your Managed Microsoft AD, +%% you choose subnets for domain +%% controllers that Directory Service creates on your behalf. If a domain +%% controller is unavailable, Directory Service Data +%% uses an available domain controller. As a result, you might notice +%% eventual consistency while +%% objects replicate from one domain controller to another domain controller. +%% For more +%% information, see What +%% gets created: +%% https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_getting_started_what_gets_created.html +%% in the Directory Service Administration Guide. +%% Directory limits vary by Managed Microsoft AD edition: +%% +%% Standard edition – Supports 8 transactions per +%% second (TPS) for read operations and 4 TPS for write operations per +%% directory. There's a +%% concurrency limit of 10 concurrent requests. +%% +%% Enterprise edition – Supports 16 transactions per +%% second (TPS) for read operations and 8 TPS for write operations per +%% directory. There's a +%% concurrency limit of 10 concurrent requests. +%% +%% Amazon Web Services Account - Supports a total of 100 TPS for +%% Directory Service Data operations across all directories. +%% +%% Directory Service Data only supports the Managed Microsoft AD directory +%% type and is only available in the primary +%% Amazon Web Services Region. For more information, see Managed Microsoft +%% AD: +%% https://docs.aws.amazon.com/directoryservice/latest/admin-guide/directory_microsoft_ad.html +%% and Primary vs additional Regions: +%% https://docs.aws.amazon.com/directoryservice/latest/admin-guide/multi-region-global-primary-additional.html +%% in the Directory Service Administration +%% Guide. +-module(aws_directory_service_data). + +-export([add_group_member/2, + add_group_member/3, + create_group/2, + create_group/3, + create_user/2, + create_user/3, + delete_group/2, + delete_group/3, + delete_user/2, + delete_user/3, + describe_group/2, + describe_group/3, + describe_user/2, + describe_user/3, + disable_user/2, + disable_user/3, + list_group_members/2, + list_group_members/3, + list_groups/2, + list_groups/3, + list_groups_for_member/2, + list_groups_for_member/3, + list_users/2, + list_users/3, + remove_group_member/2, + remove_group_member/3, + search_groups/2, + search_groups/3, + search_users/2, + search_users/3, + update_group/2, + update_group/3, + update_user/2, + update_user/3]). + +-include_lib("hackney/include/hackney_lib.hrl"). + + + +%% Example: +%% list_groups_result() :: #{ +%% <<"DirectoryId">> => string(), +%% <<"Groups">> => list(group_summary()()), +%% <<"NextToken">> => string(), +%% <<"Realm">> => string() +%% } +-type list_groups_result() :: #{binary() => any()}. + + +%% Example: +%% user_summary() :: #{ +%% <<"Enabled">> => [boolean()], +%% <<"GivenName">> => string(), +%% <<"SAMAccountName">> => string(), +%% <<"SID">> => string(), +%% <<"Surname">> => string() +%% } +-type user_summary() :: #{binary() => any()}. + + +%% Example: +%% search_users_result() :: #{ +%% <<"DirectoryId">> => string(), +%% <<"NextToken">> => string(), +%% <<"Realm">> => string(), +%% <<"Users">> => list(user()()) +%% } +-type search_users_result() :: #{binary() => any()}. + +%% Example: +%% disable_user_result() :: #{} +-type disable_user_result() :: #{}. + + +%% Example: +%% create_group_result() :: #{ +%% <<"DirectoryId">> => string(), +%% <<"SAMAccountName">> => string(), +%% <<"SID">> => string() +%% } +-type create_group_result() :: #{binary() => any()}. + + +%% Example: +%% list_group_members_request() :: #{ +%% <<"DirectoryId">> := string(), +%% <<"MaxResults">> => integer(), +%% <<"MemberRealm">> => string(), +%% <<"NextToken">> => string(), +%% <<"Realm">> => string(), +%% <<"SAMAccountName">> := string() +%% } +-type list_group_members_request() :: #{binary() => any()}. + +%% Example: +%% add_group_member_result() :: #{} +-type add_group_member_result() :: #{}. + + +%% Example: +%% create_user_result() :: #{ +%% <<"DirectoryId">> => string(), +%% <<"SAMAccountName">> => string(), +%% <<"SID">> => string() +%% } +-type create_user_result() :: #{binary() => any()}. + + +%% Example: +%% update_group_request() :: #{ +%% <<"ClientToken">> => string(), +%% <<"DirectoryId">> := string(), +%% <<"GroupScope">> => list(any()), +%% <<"GroupType">> => list(any()), +%% <<"OtherAttributes">> => map(), +%% <<"SAMAccountName">> := string(), +%% <<"UpdateType">> => list(any()) +%% } +-type update_group_request() :: #{binary() => any()}. + + +%% Example: +%% conflict_exception() :: #{ +%% <<"Message">> => string() +%% } +-type conflict_exception() :: #{binary() => any()}. + + +%% Example: +%% resource_not_found_exception() :: #{ +%% <<"Message">> => string() +%% } +-type resource_not_found_exception() :: #{binary() => any()}. + + +%% Example: +%% describe_user_result() :: #{ +%% <<"DirectoryId">> => string(), +%% <<"DistinguishedName">> => string(), +%% <<"EmailAddress">> => string(), +%% <<"Enabled">> => [boolean()], +%% <<"GivenName">> => string(), +%% <<"OtherAttributes">> => map(), +%% <<"Realm">> => string(), +%% <<"SAMAccountName">> => string(), +%% <<"SID">> => string(), +%% <<"Surname">> => string(), +%% <<"UserPrincipalName">> => string() +%% } +-type describe_user_result() :: #{binary() => any()}. + + +%% Example: +%% search_groups_result() :: #{ +%% <<"DirectoryId">> => string(), +%% <<"Groups">> => list(group()()), +%% <<"NextToken">> => string(), +%% <<"Realm">> => string() +%% } +-type search_groups_result() :: #{binary() => any()}. + +%% Example: +%% delete_group_result() :: #{} +-type delete_group_result() :: #{}. + + +%% Example: +%% search_groups_request() :: #{ +%% <<"DirectoryId">> := string(), +%% <<"MaxResults">> => integer(), +%% <<"NextToken">> => string(), +%% <<"Realm">> => string(), +%% <<"SearchAttributes">> := list(string()()), +%% <<"SearchString">> := string() +%% } +-type search_groups_request() :: #{binary() => any()}. + + +%% Example: +%% remove_group_member_request() :: #{ +%% <<"ClientToken">> => string(), +%% <<"DirectoryId">> := string(), +%% <<"GroupName">> := string(), +%% <<"MemberName">> := string(), +%% <<"MemberRealm">> => string() +%% } +-type remove_group_member_request() :: #{binary() => any()}. + + +%% Example: +%% list_group_members_result() :: #{ +%% <<"DirectoryId">> => string(), +%% <<"MemberRealm">> => string(), +%% <<"Members">> => list(member()()), +%% <<"NextToken">> => string(), +%% <<"Realm">> => string() +%% } +-type list_group_members_result() :: #{binary() => any()}. + + +%% Example: +%% search_users_request() :: #{ +%% <<"DirectoryId">> := string(), +%% <<"MaxResults">> => integer(), +%% <<"NextToken">> => string(), +%% <<"Realm">> => string(), +%% <<"SearchAttributes">> := list(string()()), +%% <<"SearchString">> := string() +%% } +-type search_users_request() :: #{binary() => any()}. + + +%% Example: +%% create_group_request() :: #{ +%% <<"ClientToken">> => string(), +%% <<"DirectoryId">> := string(), +%% <<"GroupScope">> => list(any()), +%% <<"GroupType">> => list(any()), +%% <<"OtherAttributes">> => map(), +%% <<"SAMAccountName">> := string() +%% } +-type create_group_request() :: #{binary() => any()}. + + +%% Example: +%% list_users_result() :: #{ +%% <<"DirectoryId">> => string(), +%% <<"NextToken">> => string(), +%% <<"Realm">> => string(), +%% <<"Users">> => list(user_summary()()) +%% } +-type list_users_result() :: #{binary() => any()}. + + +%% Example: +%% delete_user_request() :: #{ +%% <<"ClientToken">> => string(), +%% <<"DirectoryId">> := string(), +%% <<"SAMAccountName">> := string() +%% } +-type delete_user_request() :: #{binary() => any()}. + + +%% Example: +%% internal_server_exception() :: #{ +%% <<"Message">> => string() +%% } +-type internal_server_exception() :: #{binary() => any()}. + + +%% Example: +%% access_denied_exception() :: #{ +%% <<"Message">> => string(), +%% <<"Reason">> => list(any()) +%% } +-type access_denied_exception() :: #{binary() => any()}. + + +%% Example: +%% describe_user_request() :: #{ +%% <<"DirectoryId">> := string(), +%% <<"OtherAttributes">> => list(string()()), +%% <<"Realm">> => string(), +%% <<"SAMAccountName">> := string() +%% } +-type describe_user_request() :: #{binary() => any()}. + +%% Example: +%% update_user_result() :: #{} +-type update_user_result() :: #{}. + + +%% Example: +%% update_user_request() :: #{ +%% <<"ClientToken">> => string(), +%% <<"DirectoryId">> := string(), +%% <<"EmailAddress">> => string(), +%% <<"GivenName">> => string(), +%% <<"OtherAttributes">> => map(), +%% <<"SAMAccountName">> := string(), +%% <<"Surname">> => string(), +%% <<"UpdateType">> => list(any()) +%% } +-type update_user_request() :: #{binary() => any()}. + +%% Example: +%% delete_user_result() :: #{} +-type delete_user_result() :: #{}. + + +%% Example: +%% directory_unavailable_exception() :: #{ +%% <<"Message">> => string(), +%% <<"Reason">> => list(any()) +%% } +-type directory_unavailable_exception() :: #{binary() => any()}. + + +%% Example: +%% validation_exception() :: #{ +%% <<"Message">> => string(), +%% <<"Reason">> => list(any()) +%% } +-type validation_exception() :: #{binary() => any()}. + +%% Example: +%% update_group_result() :: #{} +-type update_group_result() :: #{}. + + +%% Example: +%% throttling_exception() :: #{ +%% <<"Message">> => string(), +%% <<"RetryAfterSeconds">> => [integer()] +%% } +-type throttling_exception() :: #{binary() => any()}. + + +%% Example: +%% group() :: #{ +%% <<"DistinguishedName">> => string(), +%% <<"GroupScope">> => list(any()), +%% <<"GroupType">> => list(any()), +%% <<"OtherAttributes">> => map(), +%% <<"SAMAccountName">> => string(), +%% <<"SID">> => string() +%% } +-type group() :: #{binary() => any()}. + + +%% Example: +%% add_group_member_request() :: #{ +%% <<"ClientToken">> => string(), +%% <<"DirectoryId">> := string(), +%% <<"GroupName">> := string(), +%% <<"MemberName">> := string(), +%% <<"MemberRealm">> => string() +%% } +-type add_group_member_request() :: #{binary() => any()}. + + +%% Example: +%% user() :: #{ +%% <<"DistinguishedName">> => string(), +%% <<"EmailAddress">> => string(), +%% <<"Enabled">> => [boolean()], +%% <<"GivenName">> => string(), +%% <<"OtherAttributes">> => map(), +%% <<"SAMAccountName">> => string(), +%% <<"SID">> => string(), +%% <<"Surname">> => string(), +%% <<"UserPrincipalName">> => string() +%% } +-type user() :: #{binary() => any()}. + + +%% Example: +%% describe_group_request() :: #{ +%% <<"DirectoryId">> := string(), +%% <<"OtherAttributes">> => list(string()()), +%% <<"Realm">> => string(), +%% <<"SAMAccountName">> := string() +%% } +-type describe_group_request() :: #{binary() => any()}. + + +%% Example: +%% list_groups_for_member_request() :: #{ +%% <<"DirectoryId">> := string(), +%% <<"MaxResults">> => integer(), +%% <<"MemberRealm">> => string(), +%% <<"NextToken">> => string(), +%% <<"Realm">> => string(), +%% <<"SAMAccountName">> := string() +%% } +-type list_groups_for_member_request() :: #{binary() => any()}. + + +%% Example: +%% delete_group_request() :: #{ +%% <<"ClientToken">> => string(), +%% <<"DirectoryId">> := string(), +%% <<"SAMAccountName">> := string() +%% } +-type delete_group_request() :: #{binary() => any()}. + + +%% Example: +%% member() :: #{ +%% <<"MemberType">> => list(any()), +%% <<"SAMAccountName">> => string(), +%% <<"SID">> => string() +%% } +-type member() :: #{binary() => any()}. + + +%% Example: +%% list_users_request() :: #{ +%% <<"DirectoryId">> := string(), +%% <<"MaxResults">> => integer(), +%% <<"NextToken">> => string(), +%% <<"Realm">> => string() +%% } +-type list_users_request() :: #{binary() => any()}. + +%% Example: +%% remove_group_member_result() :: #{} +-type remove_group_member_result() :: #{}. + + +%% Example: +%% list_groups_for_member_result() :: #{ +%% <<"DirectoryId">> => string(), +%% <<"Groups">> => list(group_summary()()), +%% <<"MemberRealm">> => string(), +%% <<"NextToken">> => string(), +%% <<"Realm">> => string() +%% } +-type list_groups_for_member_result() :: #{binary() => any()}. + + +%% Example: +%% describe_group_result() :: #{ +%% <<"DirectoryId">> => string(), +%% <<"DistinguishedName">> => string(), +%% <<"GroupScope">> => list(any()), +%% <<"GroupType">> => list(any()), +%% <<"OtherAttributes">> => map(), +%% <<"Realm">> => string(), +%% <<"SAMAccountName">> => string(), +%% <<"SID">> => string() +%% } +-type describe_group_result() :: #{binary() => any()}. + + +%% Example: +%% group_summary() :: #{ +%% <<"GroupScope">> => list(any()), +%% <<"GroupType">> => list(any()), +%% <<"SAMAccountName">> => string(), +%% <<"SID">> => string() +%% } +-type group_summary() :: #{binary() => any()}. + + +%% Example: +%% list_groups_request() :: #{ +%% <<"DirectoryId">> := string(), +%% <<"MaxResults">> => integer(), +%% <<"NextToken">> => string(), +%% <<"Realm">> => string() +%% } +-type list_groups_request() :: #{binary() => any()}. + + +%% Example: +%% disable_user_request() :: #{ +%% <<"ClientToken">> => string(), +%% <<"DirectoryId">> := string(), +%% <<"SAMAccountName">> := string() +%% } +-type disable_user_request() :: #{binary() => any()}. + + +%% Example: +%% create_user_request() :: #{ +%% <<"ClientToken">> => string(), +%% <<"DirectoryId">> := string(), +%% <<"EmailAddress">> => string(), +%% <<"GivenName">> => string(), +%% <<"OtherAttributes">> => map(), +%% <<"SAMAccountName">> := string(), +%% <<"Surname">> => string() +%% } +-type create_user_request() :: #{binary() => any()}. + +-type add_group_member_errors() :: + throttling_exception() | + validation_exception() | + directory_unavailable_exception() | + access_denied_exception() | + internal_server_exception() | + resource_not_found_exception() | + conflict_exception(). + +-type create_group_errors() :: + throttling_exception() | + validation_exception() | + directory_unavailable_exception() | + access_denied_exception() | + internal_server_exception() | + conflict_exception(). + +-type create_user_errors() :: + throttling_exception() | + validation_exception() | + directory_unavailable_exception() | + access_denied_exception() | + internal_server_exception() | + conflict_exception(). + +-type delete_group_errors() :: + throttling_exception() | + validation_exception() | + directory_unavailable_exception() | + access_denied_exception() | + internal_server_exception() | + resource_not_found_exception() | + conflict_exception(). + +-type delete_user_errors() :: + throttling_exception() | + validation_exception() | + directory_unavailable_exception() | + access_denied_exception() | + internal_server_exception() | + resource_not_found_exception() | + conflict_exception(). + +-type describe_group_errors() :: + throttling_exception() | + validation_exception() | + directory_unavailable_exception() | + access_denied_exception() | + internal_server_exception() | + resource_not_found_exception(). + +-type describe_user_errors() :: + throttling_exception() | + validation_exception() | + directory_unavailable_exception() | + access_denied_exception() | + internal_server_exception() | + resource_not_found_exception(). + +-type disable_user_errors() :: + throttling_exception() | + validation_exception() | + directory_unavailable_exception() | + access_denied_exception() | + internal_server_exception() | + resource_not_found_exception() | + conflict_exception(). + +-type list_group_members_errors() :: + throttling_exception() | + validation_exception() | + directory_unavailable_exception() | + access_denied_exception() | + internal_server_exception() | + resource_not_found_exception(). + +-type list_groups_errors() :: + throttling_exception() | + validation_exception() | + directory_unavailable_exception() | + access_denied_exception() | + internal_server_exception(). + +-type list_groups_for_member_errors() :: + throttling_exception() | + validation_exception() | + directory_unavailable_exception() | + access_denied_exception() | + internal_server_exception() | + resource_not_found_exception(). + +-type list_users_errors() :: + throttling_exception() | + validation_exception() | + directory_unavailable_exception() | + access_denied_exception() | + internal_server_exception(). + +-type remove_group_member_errors() :: + throttling_exception() | + validation_exception() | + directory_unavailable_exception() | + access_denied_exception() | + internal_server_exception() | + resource_not_found_exception() | + conflict_exception(). + +-type search_groups_errors() :: + throttling_exception() | + validation_exception() | + directory_unavailable_exception() | + access_denied_exception() | + internal_server_exception(). + +-type search_users_errors() :: + throttling_exception() | + validation_exception() | + directory_unavailable_exception() | + access_denied_exception() | + internal_server_exception(). + +-type update_group_errors() :: + throttling_exception() | + validation_exception() | + directory_unavailable_exception() | + access_denied_exception() | + internal_server_exception() | + resource_not_found_exception() | + conflict_exception(). + +-type update_user_errors() :: + throttling_exception() | + validation_exception() | + directory_unavailable_exception() | + access_denied_exception() | + internal_server_exception() | + resource_not_found_exception() | + conflict_exception(). + +%%==================================================================== +%% API +%%==================================================================== + +%% @doc Adds an existing user, group, or computer as a group member. +-spec add_group_member(aws_client:aws_client(), add_group_member_request()) -> + {ok, add_group_member_result(), tuple()} | + {error, any()} | + {error, add_group_member_errors(), tuple()}. +add_group_member(Client, Input) -> + add_group_member(Client, Input, []). + +-spec add_group_member(aws_client:aws_client(), add_group_member_request(), proplists:proplist()) -> + {ok, add_group_member_result(), tuple()} | + {error, any()} | + {error, add_group_member_errors(), tuple()}. +add_group_member(Client, Input0, Options0) -> + Method = post, + Path = ["/GroupMemberships/AddGroupMember"], + SuccessStatusCode = 200, + {SendBodyAsBinary, Options1} = proplists_take(send_body_as_binary, Options0, false), + {ReceiveBodyAsBinary, Options2} = proplists_take(receive_body_as_binary, Options1, false), + Options = [{send_body_as_binary, SendBodyAsBinary}, + {receive_body_as_binary, ReceiveBodyAsBinary}, + {append_sha256_content_hash, false} + | Options2], + + Headers = [], + Input1 = Input0, + + CustomHeaders = [], + Input2 = Input1, + + QueryMapping = [ + {<<"DirectoryId">>, <<"DirectoryId">>} + ], + {Query_, Input} = aws_request:build_headers(QueryMapping, Input2), + request(Client, Method, Path, Query_, CustomHeaders ++ Headers, Input, Options, SuccessStatusCode). + +%% @doc Creates a new group. +-spec create_group(aws_client:aws_client(), create_group_request()) -> + {ok, create_group_result(), tuple()} | + {error, any()} | + {error, create_group_errors(), tuple()}. +create_group(Client, Input) -> + create_group(Client, Input, []). + +-spec create_group(aws_client:aws_client(), create_group_request(), proplists:proplist()) -> + {ok, create_group_result(), tuple()} | + {error, any()} | + {error, create_group_errors(), tuple()}. +create_group(Client, Input0, Options0) -> + Method = post, + Path = ["/Groups/CreateGroup"], + SuccessStatusCode = 200, + {SendBodyAsBinary, Options1} = proplists_take(send_body_as_binary, Options0, false), + {ReceiveBodyAsBinary, Options2} = proplists_take(receive_body_as_binary, Options1, false), + Options = [{send_body_as_binary, SendBodyAsBinary}, + {receive_body_as_binary, ReceiveBodyAsBinary}, + {append_sha256_content_hash, false} + | Options2], + + Headers = [], + Input1 = Input0, + + CustomHeaders = [], + Input2 = Input1, + + QueryMapping = [ + {<<"DirectoryId">>, <<"DirectoryId">>} + ], + {Query_, Input} = aws_request:build_headers(QueryMapping, Input2), + request(Client, Method, Path, Query_, CustomHeaders ++ Headers, Input, Options, SuccessStatusCode). + +%% @doc Creates a new user. +-spec create_user(aws_client:aws_client(), create_user_request()) -> + {ok, create_user_result(), tuple()} | + {error, any()} | + {error, create_user_errors(), tuple()}. +create_user(Client, Input) -> + create_user(Client, Input, []). + +-spec create_user(aws_client:aws_client(), create_user_request(), proplists:proplist()) -> + {ok, create_user_result(), tuple()} | + {error, any()} | + {error, create_user_errors(), tuple()}. +create_user(Client, Input0, Options0) -> + Method = post, + Path = ["/Users/CreateUser"], + SuccessStatusCode = 200, + {SendBodyAsBinary, Options1} = proplists_take(send_body_as_binary, Options0, false), + {ReceiveBodyAsBinary, Options2} = proplists_take(receive_body_as_binary, Options1, false), + Options = [{send_body_as_binary, SendBodyAsBinary}, + {receive_body_as_binary, ReceiveBodyAsBinary}, + {append_sha256_content_hash, false} + | Options2], + + Headers = [], + Input1 = Input0, + + CustomHeaders = [], + Input2 = Input1, + + QueryMapping = [ + {<<"DirectoryId">>, <<"DirectoryId">>} + ], + {Query_, Input} = aws_request:build_headers(QueryMapping, Input2), + request(Client, Method, Path, Query_, CustomHeaders ++ Headers, Input, Options, SuccessStatusCode). + +%% @doc Deletes a group. +-spec delete_group(aws_client:aws_client(), delete_group_request()) -> + {ok, delete_group_result(), tuple()} | + {error, any()} | + {error, delete_group_errors(), tuple()}. +delete_group(Client, Input) -> + delete_group(Client, Input, []). + +-spec delete_group(aws_client:aws_client(), delete_group_request(), proplists:proplist()) -> + {ok, delete_group_result(), tuple()} | + {error, any()} | + {error, delete_group_errors(), tuple()}. +delete_group(Client, Input0, Options0) -> + Method = post, + Path = ["/Groups/DeleteGroup"], + SuccessStatusCode = 200, + {SendBodyAsBinary, Options1} = proplists_take(send_body_as_binary, Options0, false), + {ReceiveBodyAsBinary, Options2} = proplists_take(receive_body_as_binary, Options1, false), + Options = [{send_body_as_binary, SendBodyAsBinary}, + {receive_body_as_binary, ReceiveBodyAsBinary}, + {append_sha256_content_hash, false} + | Options2], + + Headers = [], + Input1 = Input0, + + CustomHeaders = [], + Input2 = Input1, + + QueryMapping = [ + {<<"DirectoryId">>, <<"DirectoryId">>} + ], + {Query_, Input} = aws_request:build_headers(QueryMapping, Input2), + request(Client, Method, Path, Query_, CustomHeaders ++ Headers, Input, Options, SuccessStatusCode). + +%% @doc Deletes a user. +-spec delete_user(aws_client:aws_client(), delete_user_request()) -> + {ok, delete_user_result(), tuple()} | + {error, any()} | + {error, delete_user_errors(), tuple()}. +delete_user(Client, Input) -> + delete_user(Client, Input, []). + +-spec delete_user(aws_client:aws_client(), delete_user_request(), proplists:proplist()) -> + {ok, delete_user_result(), tuple()} | + {error, any()} | + {error, delete_user_errors(), tuple()}. +delete_user(Client, Input0, Options0) -> + Method = post, + Path = ["/Users/DeleteUser"], + SuccessStatusCode = 200, + {SendBodyAsBinary, Options1} = proplists_take(send_body_as_binary, Options0, false), + {ReceiveBodyAsBinary, Options2} = proplists_take(receive_body_as_binary, Options1, false), + Options = [{send_body_as_binary, SendBodyAsBinary}, + {receive_body_as_binary, ReceiveBodyAsBinary}, + {append_sha256_content_hash, false} + | Options2], + + Headers = [], + Input1 = Input0, + + CustomHeaders = [], + Input2 = Input1, + + QueryMapping = [ + {<<"DirectoryId">>, <<"DirectoryId">>} + ], + {Query_, Input} = aws_request:build_headers(QueryMapping, Input2), + request(Client, Method, Path, Query_, CustomHeaders ++ Headers, Input, Options, SuccessStatusCode). + +%% @doc Returns information about a specific group. +-spec describe_group(aws_client:aws_client(), describe_group_request()) -> + {ok, describe_group_result(), tuple()} | + {error, any()} | + {error, describe_group_errors(), tuple()}. +describe_group(Client, Input) -> + describe_group(Client, Input, []). + +-spec describe_group(aws_client:aws_client(), describe_group_request(), proplists:proplist()) -> + {ok, describe_group_result(), tuple()} | + {error, any()} | + {error, describe_group_errors(), tuple()}. +describe_group(Client, Input0, Options0) -> + Method = post, + Path = ["/Groups/DescribeGroup"], + SuccessStatusCode = 200, + {SendBodyAsBinary, Options1} = proplists_take(send_body_as_binary, Options0, false), + {ReceiveBodyAsBinary, Options2} = proplists_take(receive_body_as_binary, Options1, false), + Options = [{send_body_as_binary, SendBodyAsBinary}, + {receive_body_as_binary, ReceiveBodyAsBinary}, + {append_sha256_content_hash, false} + | Options2], + + Headers = [], + Input1 = Input0, + + CustomHeaders = [], + Input2 = Input1, + + QueryMapping = [ + {<<"DirectoryId">>, <<"DirectoryId">>} + ], + {Query_, Input} = aws_request:build_headers(QueryMapping, Input2), + request(Client, Method, Path, Query_, CustomHeaders ++ Headers, Input, Options, SuccessStatusCode). + +%% @doc Returns information about a specific user. +-spec describe_user(aws_client:aws_client(), describe_user_request()) -> + {ok, describe_user_result(), tuple()} | + {error, any()} | + {error, describe_user_errors(), tuple()}. +describe_user(Client, Input) -> + describe_user(Client, Input, []). + +-spec describe_user(aws_client:aws_client(), describe_user_request(), proplists:proplist()) -> + {ok, describe_user_result(), tuple()} | + {error, any()} | + {error, describe_user_errors(), tuple()}. +describe_user(Client, Input0, Options0) -> + Method = post, + Path = ["/Users/DescribeUser"], + SuccessStatusCode = 200, + {SendBodyAsBinary, Options1} = proplists_take(send_body_as_binary, Options0, false), + {ReceiveBodyAsBinary, Options2} = proplists_take(receive_body_as_binary, Options1, false), + Options = [{send_body_as_binary, SendBodyAsBinary}, + {receive_body_as_binary, ReceiveBodyAsBinary}, + {append_sha256_content_hash, false} + | Options2], + + Headers = [], + Input1 = Input0, + + CustomHeaders = [], + Input2 = Input1, + + QueryMapping = [ + {<<"DirectoryId">>, <<"DirectoryId">>} + ], + {Query_, Input} = aws_request:build_headers(QueryMapping, Input2), + request(Client, Method, Path, Query_, CustomHeaders ++ Headers, Input, Options, SuccessStatusCode). + +%% @doc Deactivates an active user account. +%% +%% For information about how to enable an inactive user +%% account, see ResetUserPassword: +%% https://docs.aws.amazon.com/directoryservice/latest/devguide/API_ResetUserPassword.html +%% in the Directory Service API Reference. +-spec disable_user(aws_client:aws_client(), disable_user_request()) -> + {ok, disable_user_result(), tuple()} | + {error, any()} | + {error, disable_user_errors(), tuple()}. +disable_user(Client, Input) -> + disable_user(Client, Input, []). + +-spec disable_user(aws_client:aws_client(), disable_user_request(), proplists:proplist()) -> + {ok, disable_user_result(), tuple()} | + {error, any()} | + {error, disable_user_errors(), tuple()}. +disable_user(Client, Input0, Options0) -> + Method = post, + Path = ["/Users/DisableUser"], + SuccessStatusCode = 200, + {SendBodyAsBinary, Options1} = proplists_take(send_body_as_binary, Options0, false), + {ReceiveBodyAsBinary, Options2} = proplists_take(receive_body_as_binary, Options1, false), + Options = [{send_body_as_binary, SendBodyAsBinary}, + {receive_body_as_binary, ReceiveBodyAsBinary}, + {append_sha256_content_hash, false} + | Options2], + + Headers = [], + Input1 = Input0, + + CustomHeaders = [], + Input2 = Input1, + + QueryMapping = [ + {<<"DirectoryId">>, <<"DirectoryId">>} + ], + {Query_, Input} = aws_request:build_headers(QueryMapping, Input2), + request(Client, Method, Path, Query_, CustomHeaders ++ Headers, Input, Options, SuccessStatusCode). + +%% @doc Returns member information for the specified group. +%% +%% This operation supports pagination with the use of the `NextToken' +%% request and +%% response parameters. If more results are available, the +%% `ListGroupMembers.NextToken' member contains a token that you pass in +%% the next +%% call to `ListGroupMembers'. This retrieves the next set of items. +%% +%% You can also specify a maximum number of return results with the +%% `MaxResults' +%% parameter. +-spec list_group_members(aws_client:aws_client(), list_group_members_request()) -> + {ok, list_group_members_result(), tuple()} | + {error, any()} | + {error, list_group_members_errors(), tuple()}. +list_group_members(Client, Input) -> + list_group_members(Client, Input, []). + +-spec list_group_members(aws_client:aws_client(), list_group_members_request(), proplists:proplist()) -> + {ok, list_group_members_result(), tuple()} | + {error, any()} | + {error, list_group_members_errors(), tuple()}. +list_group_members(Client, Input0, Options0) -> + Method = post, + Path = ["/GroupMemberships/ListGroupMembers"], + SuccessStatusCode = 200, + {SendBodyAsBinary, Options1} = proplists_take(send_body_as_binary, Options0, false), + {ReceiveBodyAsBinary, Options2} = proplists_take(receive_body_as_binary, Options1, false), + Options = [{send_body_as_binary, SendBodyAsBinary}, + {receive_body_as_binary, ReceiveBodyAsBinary}, + {append_sha256_content_hash, false} + | Options2], + + Headers = [], + Input1 = Input0, + + CustomHeaders = [], + Input2 = Input1, + + QueryMapping = [ + {<<"DirectoryId">>, <<"DirectoryId">>} + ], + {Query_, Input} = aws_request:build_headers(QueryMapping, Input2), + request(Client, Method, Path, Query_, CustomHeaders ++ Headers, Input, Options, SuccessStatusCode). + +%% @doc Returns group information for the specified directory. +%% +%% This operation supports pagination with the use of the `NextToken' +%% request and +%% response parameters. If more results are available, the +%% `ListGroups.NextToken' +%% member contains a token that you pass in the next call to +%% `ListGroups'. This +%% retrieves the next set of items. +%% +%% You can also specify a maximum number of return results with the +%% `MaxResults' +%% parameter. +-spec list_groups(aws_client:aws_client(), list_groups_request()) -> + {ok, list_groups_result(), tuple()} | + {error, any()} | + {error, list_groups_errors(), tuple()}. +list_groups(Client, Input) -> + list_groups(Client, Input, []). + +-spec list_groups(aws_client:aws_client(), list_groups_request(), proplists:proplist()) -> + {ok, list_groups_result(), tuple()} | + {error, any()} | + {error, list_groups_errors(), tuple()}. +list_groups(Client, Input0, Options0) -> + Method = post, + Path = ["/Groups/ListGroups"], + SuccessStatusCode = 200, + {SendBodyAsBinary, Options1} = proplists_take(send_body_as_binary, Options0, false), + {ReceiveBodyAsBinary, Options2} = proplists_take(receive_body_as_binary, Options1, false), + Options = [{send_body_as_binary, SendBodyAsBinary}, + {receive_body_as_binary, ReceiveBodyAsBinary}, + {append_sha256_content_hash, false} + | Options2], + + Headers = [], + Input1 = Input0, + + CustomHeaders = [], + Input2 = Input1, + + QueryMapping = [ + {<<"DirectoryId">>, <<"DirectoryId">>} + ], + {Query_, Input} = aws_request:build_headers(QueryMapping, Input2), + request(Client, Method, Path, Query_, CustomHeaders ++ Headers, Input, Options, SuccessStatusCode). + +%% @doc Returns group information for the specified member. +%% +%% This operation supports pagination with the use of the `NextToken' +%% request and +%% response parameters. If more results are available, the +%% `ListGroupsForMember.NextToken' member contains a token that you pass +%% in the next +%% call to `ListGroupsForMember'. This retrieves the next set of items. +%% +%% You can also specify a maximum number of return results with the +%% `MaxResults' +%% parameter. +-spec list_groups_for_member(aws_client:aws_client(), list_groups_for_member_request()) -> + {ok, list_groups_for_member_result(), tuple()} | + {error, any()} | + {error, list_groups_for_member_errors(), tuple()}. +list_groups_for_member(Client, Input) -> + list_groups_for_member(Client, Input, []). + +-spec list_groups_for_member(aws_client:aws_client(), list_groups_for_member_request(), proplists:proplist()) -> + {ok, list_groups_for_member_result(), tuple()} | + {error, any()} | + {error, list_groups_for_member_errors(), tuple()}. +list_groups_for_member(Client, Input0, Options0) -> + Method = post, + Path = ["/GroupMemberships/ListGroupsForMember"], + SuccessStatusCode = 200, + {SendBodyAsBinary, Options1} = proplists_take(send_body_as_binary, Options0, false), + {ReceiveBodyAsBinary, Options2} = proplists_take(receive_body_as_binary, Options1, false), + Options = [{send_body_as_binary, SendBodyAsBinary}, + {receive_body_as_binary, ReceiveBodyAsBinary}, + {append_sha256_content_hash, false} + | Options2], + + Headers = [], + Input1 = Input0, + + CustomHeaders = [], + Input2 = Input1, + + QueryMapping = [ + {<<"DirectoryId">>, <<"DirectoryId">>} + ], + {Query_, Input} = aws_request:build_headers(QueryMapping, Input2), + request(Client, Method, Path, Query_, CustomHeaders ++ Headers, Input, Options, SuccessStatusCode). + +%% @doc Returns user information for the specified directory. +%% +%% This operation supports pagination with the use of the `NextToken' +%% request and +%% response parameters. If more results are available, the +%% `ListUsers.NextToken' +%% member contains a token that you pass in the next call to `ListUsers'. +%% This +%% retrieves the next set of items. +%% +%% You can also specify a maximum number of return results with the +%% `MaxResults' +%% parameter. +-spec list_users(aws_client:aws_client(), list_users_request()) -> + {ok, list_users_result(), tuple()} | + {error, any()} | + {error, list_users_errors(), tuple()}. +list_users(Client, Input) -> + list_users(Client, Input, []). + +-spec list_users(aws_client:aws_client(), list_users_request(), proplists:proplist()) -> + {ok, list_users_result(), tuple()} | + {error, any()} | + {error, list_users_errors(), tuple()}. +list_users(Client, Input0, Options0) -> + Method = post, + Path = ["/Users/ListUsers"], + SuccessStatusCode = 200, + {SendBodyAsBinary, Options1} = proplists_take(send_body_as_binary, Options0, false), + {ReceiveBodyAsBinary, Options2} = proplists_take(receive_body_as_binary, Options1, false), + Options = [{send_body_as_binary, SendBodyAsBinary}, + {receive_body_as_binary, ReceiveBodyAsBinary}, + {append_sha256_content_hash, false} + | Options2], + + Headers = [], + Input1 = Input0, + + CustomHeaders = [], + Input2 = Input1, + + QueryMapping = [ + {<<"DirectoryId">>, <<"DirectoryId">>} + ], + {Query_, Input} = aws_request:build_headers(QueryMapping, Input2), + request(Client, Method, Path, Query_, CustomHeaders ++ Headers, Input, Options, SuccessStatusCode). + +%% @doc Removes a member from a group. +-spec remove_group_member(aws_client:aws_client(), remove_group_member_request()) -> + {ok, remove_group_member_result(), tuple()} | + {error, any()} | + {error, remove_group_member_errors(), tuple()}. +remove_group_member(Client, Input) -> + remove_group_member(Client, Input, []). + +-spec remove_group_member(aws_client:aws_client(), remove_group_member_request(), proplists:proplist()) -> + {ok, remove_group_member_result(), tuple()} | + {error, any()} | + {error, remove_group_member_errors(), tuple()}. +remove_group_member(Client, Input0, Options0) -> + Method = post, + Path = ["/GroupMemberships/RemoveGroupMember"], + SuccessStatusCode = 200, + {SendBodyAsBinary, Options1} = proplists_take(send_body_as_binary, Options0, false), + {ReceiveBodyAsBinary, Options2} = proplists_take(receive_body_as_binary, Options1, false), + Options = [{send_body_as_binary, SendBodyAsBinary}, + {receive_body_as_binary, ReceiveBodyAsBinary}, + {append_sha256_content_hash, false} + | Options2], + + Headers = [], + Input1 = Input0, + + CustomHeaders = [], + Input2 = Input1, + + QueryMapping = [ + {<<"DirectoryId">>, <<"DirectoryId">>} + ], + {Query_, Input} = aws_request:build_headers(QueryMapping, Input2), + request(Client, Method, Path, Query_, CustomHeaders ++ Headers, Input, Options, SuccessStatusCode). + +%% @doc Searches the specified directory for a group. +%% +%% You can find groups that match the +%% `SearchString' parameter with the value of their attributes included +%% in the +%% `SearchString' parameter. +%% +%% This operation supports pagination with the use of the `NextToken' +%% request and +%% response parameters. If more results are available, the +%% `SearchGroups.NextToken' +%% member contains a token that you pass in the next call to +%% `SearchGroups'. This +%% retrieves the next set of items. +%% +%% You can also specify a maximum number of return results with the +%% `MaxResults' +%% parameter. +-spec search_groups(aws_client:aws_client(), search_groups_request()) -> + {ok, search_groups_result(), tuple()} | + {error, any()} | + {error, search_groups_errors(), tuple()}. +search_groups(Client, Input) -> + search_groups(Client, Input, []). + +-spec search_groups(aws_client:aws_client(), search_groups_request(), proplists:proplist()) -> + {ok, search_groups_result(), tuple()} | + {error, any()} | + {error, search_groups_errors(), tuple()}. +search_groups(Client, Input0, Options0) -> + Method = post, + Path = ["/Groups/SearchGroups"], + SuccessStatusCode = 200, + {SendBodyAsBinary, Options1} = proplists_take(send_body_as_binary, Options0, false), + {ReceiveBodyAsBinary, Options2} = proplists_take(receive_body_as_binary, Options1, false), + Options = [{send_body_as_binary, SendBodyAsBinary}, + {receive_body_as_binary, ReceiveBodyAsBinary}, + {append_sha256_content_hash, false} + | Options2], + + Headers = [], + Input1 = Input0, + + CustomHeaders = [], + Input2 = Input1, + + QueryMapping = [ + {<<"DirectoryId">>, <<"DirectoryId">>} + ], + {Query_, Input} = aws_request:build_headers(QueryMapping, Input2), + request(Client, Method, Path, Query_, CustomHeaders ++ Headers, Input, Options, SuccessStatusCode). + +%% @doc Searches the specified directory for a user. +%% +%% You can find users that match the +%% `SearchString' parameter with the value of their attributes included +%% in the +%% `SearchString' parameter. +%% +%% This operation supports pagination with the use of the `NextToken' +%% request and +%% response parameters. If more results are available, the +%% `SearchUsers.NextToken' +%% member contains a token that you pass in the next call to +%% `SearchUsers'. This +%% retrieves the next set of items. +%% +%% You can also specify a maximum number of return results with the +%% `MaxResults' +%% parameter. +-spec search_users(aws_client:aws_client(), search_users_request()) -> + {ok, search_users_result(), tuple()} | + {error, any()} | + {error, search_users_errors(), tuple()}. +search_users(Client, Input) -> + search_users(Client, Input, []). + +-spec search_users(aws_client:aws_client(), search_users_request(), proplists:proplist()) -> + {ok, search_users_result(), tuple()} | + {error, any()} | + {error, search_users_errors(), tuple()}. +search_users(Client, Input0, Options0) -> + Method = post, + Path = ["/Users/SearchUsers"], + SuccessStatusCode = 200, + {SendBodyAsBinary, Options1} = proplists_take(send_body_as_binary, Options0, false), + {ReceiveBodyAsBinary, Options2} = proplists_take(receive_body_as_binary, Options1, false), + Options = [{send_body_as_binary, SendBodyAsBinary}, + {receive_body_as_binary, ReceiveBodyAsBinary}, + {append_sha256_content_hash, false} + | Options2], + + Headers = [], + Input1 = Input0, + + CustomHeaders = [], + Input2 = Input1, + + QueryMapping = [ + {<<"DirectoryId">>, <<"DirectoryId">>} + ], + {Query_, Input} = aws_request:build_headers(QueryMapping, Input2), + request(Client, Method, Path, Query_, CustomHeaders ++ Headers, Input, Options, SuccessStatusCode). + +%% @doc Updates group information. +-spec update_group(aws_client:aws_client(), update_group_request()) -> + {ok, update_group_result(), tuple()} | + {error, any()} | + {error, update_group_errors(), tuple()}. +update_group(Client, Input) -> + update_group(Client, Input, []). + +-spec update_group(aws_client:aws_client(), update_group_request(), proplists:proplist()) -> + {ok, update_group_result(), tuple()} | + {error, any()} | + {error, update_group_errors(), tuple()}. +update_group(Client, Input0, Options0) -> + Method = post, + Path = ["/Groups/UpdateGroup"], + SuccessStatusCode = 200, + {SendBodyAsBinary, Options1} = proplists_take(send_body_as_binary, Options0, false), + {ReceiveBodyAsBinary, Options2} = proplists_take(receive_body_as_binary, Options1, false), + Options = [{send_body_as_binary, SendBodyAsBinary}, + {receive_body_as_binary, ReceiveBodyAsBinary}, + {append_sha256_content_hash, false} + | Options2], + + Headers = [], + Input1 = Input0, + + CustomHeaders = [], + Input2 = Input1, + + QueryMapping = [ + {<<"DirectoryId">>, <<"DirectoryId">>} + ], + {Query_, Input} = aws_request:build_headers(QueryMapping, Input2), + request(Client, Method, Path, Query_, CustomHeaders ++ Headers, Input, Options, SuccessStatusCode). + +%% @doc Updates user information. +-spec update_user(aws_client:aws_client(), update_user_request()) -> + {ok, update_user_result(), tuple()} | + {error, any()} | + {error, update_user_errors(), tuple()}. +update_user(Client, Input) -> + update_user(Client, Input, []). + +-spec update_user(aws_client:aws_client(), update_user_request(), proplists:proplist()) -> + {ok, update_user_result(), tuple()} | + {error, any()} | + {error, update_user_errors(), tuple()}. +update_user(Client, Input0, Options0) -> + Method = post, + Path = ["/Users/UpdateUser"], + SuccessStatusCode = 200, + {SendBodyAsBinary, Options1} = proplists_take(send_body_as_binary, Options0, false), + {ReceiveBodyAsBinary, Options2} = proplists_take(receive_body_as_binary, Options1, false), + Options = [{send_body_as_binary, SendBodyAsBinary}, + {receive_body_as_binary, ReceiveBodyAsBinary}, + {append_sha256_content_hash, false} + | Options2], + + Headers = [], + Input1 = Input0, + + CustomHeaders = [], + Input2 = Input1, + + QueryMapping = [ + {<<"DirectoryId">>, <<"DirectoryId">>} + ], + {Query_, Input} = aws_request:build_headers(QueryMapping, Input2), + request(Client, Method, Path, Query_, CustomHeaders ++ Headers, Input, Options, SuccessStatusCode). + +%%==================================================================== +%% Internal functions +%%==================================================================== + +-spec proplists_take(any(), proplists:proplist(), any()) -> {any(), proplists:proplist()}. +proplists_take(Key, Proplist, Default) -> + Value = proplists:get_value(Key, Proplist, Default), + {Value, proplists:delete(Key, Proplist)}. + +-spec request(aws_client:aws_client(), atom(), iolist(), list(), + list(), map() | undefined, list(), pos_integer() | undefined) -> + {ok, {integer(), list()}} | + {ok, Result, {integer(), list(), hackney:client()}} | + {error, Error, {integer(), list(), hackney:client()}} | + {error, term()} when + Result :: map(), + Error :: map(). +request(Client, Method, Path, Query, Headers0, Input, Options, SuccessStatusCode) -> + RequestFun = fun() -> do_request(Client, Method, Path, Query, Headers0, Input, Options, SuccessStatusCode) end, + aws_request:request(RequestFun, Options). + +do_request(Client, Method, Path, Query, Headers0, Input, Options, SuccessStatusCode) -> + Client1 = Client#{service => <<"ds-data">>}, + Host = build_host(<<"ds-data">>, Client1), + URL0 = build_url(Host, Path, Client1), + URL = aws_request:add_query(URL0, Query), + AdditionalHeaders1 = [ {<<"Host">>, Host} + , {<<"Content-Type">>, <<"application/x-amz-json-1.1">>} + ], + Payload = + case proplists:get_value(send_body_as_binary, Options) of + true -> + maps:get(<<"Body">>, Input, <<"">>); + false -> + encode_payload(Input) + end, + AdditionalHeaders = case proplists:get_value(append_sha256_content_hash, Options, false) of + true -> + add_checksum_hash_header(AdditionalHeaders1, Payload); + false -> + AdditionalHeaders1 + end, + Headers1 = aws_request:add_headers(AdditionalHeaders, Headers0), + + MethodBin = aws_request:method_to_binary(Method), + SignedHeaders = aws_request:sign_request(Client1, MethodBin, URL, Headers1, Payload), + Response = hackney:request(Method, URL, SignedHeaders, Payload, Options), + DecodeBody = not proplists:get_value(receive_body_as_binary, Options), + handle_response(Response, SuccessStatusCode, DecodeBody). + +add_checksum_hash_header(Headers, Body) -> + [ {<<"X-Amz-CheckSum-SHA256">>, base64:encode(crypto:hash(sha256, Body))} + | Headers + ]. + +handle_response({ok, StatusCode, ResponseHeaders}, SuccessStatusCode, _DecodeBody) + when StatusCode =:= 200; + StatusCode =:= 202; + StatusCode =:= 204; + StatusCode =:= 206; + StatusCode =:= SuccessStatusCode -> + {ok, {StatusCode, ResponseHeaders}}; +handle_response({ok, StatusCode, ResponseHeaders}, _, _DecodeBody) -> + {error, {StatusCode, ResponseHeaders}}; +handle_response({ok, StatusCode, ResponseHeaders, Client}, SuccessStatusCode, DecodeBody) + when StatusCode =:= 200; + StatusCode =:= 202; + StatusCode =:= 204; + StatusCode =:= 206; + StatusCode =:= SuccessStatusCode -> + case hackney:body(Client) of + {ok, <<>>} when StatusCode =:= 200; + StatusCode =:= SuccessStatusCode -> + {ok, #{}, {StatusCode, ResponseHeaders, Client}}; + {ok, Body} -> + Result = case DecodeBody of + true -> + try + jsx:decode(Body) + catch + Error:Reason:Stack -> + erlang:raise(error, {body_decode_failed, Error, Reason, StatusCode, Body}, Stack) + end; + false -> #{<<"Body">> => Body} + end, + {ok, Result, {StatusCode, ResponseHeaders, Client}} + end; +handle_response({ok, StatusCode, _ResponseHeaders, _Client}, _, _DecodeBody) + when StatusCode =:= 503 -> + %% Retriable error if retries are enabled + {error, service_unavailable}; +handle_response({ok, StatusCode, ResponseHeaders, Client}, _, _DecodeBody) -> + {ok, Body} = hackney:body(Client), + try + DecodedError = jsx:decode(Body), + {error, DecodedError, {StatusCode, ResponseHeaders, Client}} + catch + Error:Reason:Stack -> + erlang:raise(error, {body_decode_failed, Error, Reason, StatusCode, Body}, Stack) + end; +handle_response({error, Reason}, _, _DecodeBody) -> + {error, Reason}. + +build_host(_EndpointPrefix, #{region := <<"local">>, endpoint := Endpoint}) -> + Endpoint; +build_host(_EndpointPrefix, #{region := <<"local">>}) -> + <<"localhost">>; +build_host(EndpointPrefix, #{region := Region, endpoint := Endpoint}) -> + aws_util:binary_join([EndpointPrefix, Region, Endpoint], <<".">>). + +build_url(Host, Path0, Client) -> + Proto = aws_client:proto(Client), + Path = erlang:iolist_to_binary(Path0), + Port = aws_client:port(Client), + aws_util:binary_join([Proto, <<"://">>, Host, <<":">>, Port, Path], <<"">>). + +-spec encode_payload(undefined | map()) -> binary(). +encode_payload(undefined) -> + <<>>; +encode_payload(Input) -> + jsx:encode(Input). diff --git a/src/aws_guardduty.erl b/src/aws_guardduty.erl index a060da16..aeb94f9b 100644 --- a/src/aws_guardduty.erl +++ b/src/aws_guardduty.erl @@ -1536,6 +1536,7 @@ %% <<"Containers">> => list(container()()), %% <<"DefinitionArn">> => string(), %% <<"Group">> => string(), +%% <<"LaunchType">> => string(), %% <<"StartedAt">> => non_neg_integer(), %% <<"StartedBy">> => string(), %% <<"Tags">> => list(tag()()), diff --git a/src/aws_mailmanager.erl b/src/aws_mailmanager.erl index e5279192..4cd177f0 100644 --- a/src/aws_mailmanager.erl +++ b/src/aws_mailmanager.erl @@ -1,11 +1,11 @@ %% WARNING: DO NOT EDIT, AUTO-GENERATED CODE! %% See https://github.com/aws-beam/aws-codegen for more details. -%% @doc AWS SES Mail Manager API +%% @doc Amazon SES Mail Manager API %% -%% AWS SES Mail Manager API: http://aws.amazon.com/ses contains operations -%% and data types -%% that comprise the Mail Manager feature of Amazon Simple Email Service. +%% The Amazon SES Mail Manager API contains operations and data types +%% that comprise the Mail Manager feature of Amazon Simple Email Service +%% (SES): http://aws.amazon.com/ses. %% %% Mail Manager is a set of Amazon SES email gateway features designed to %% help you strengthen @@ -600,7 +600,7 @@ %% archive_string_expression() :: #{ %% <<"Evaluate">> => list(), %% <<"Operator">> => list(any()), -%% <<"Values">> => list([string()]()) +%% <<"Values">> => list(string()()) %% } -type archive_string_expression() :: #{binary() => any()}. @@ -2216,7 +2216,7 @@ update_relay(Client, Input, Options) when is_map(Client), is_map(Input), is_list(Options) -> request(Client, <<"UpdateRelay">>, Input, Options). -%% @doc >Update attributes of an already provisioned rule set. +%% @doc Update attributes of an already provisioned rule set. -spec update_rule_set(aws_client:aws_client(), update_rule_set_request()) -> {ok, update_rule_set_response(), tuple()} | {error, any()} | diff --git a/src/aws_rds.erl b/src/aws_rds.erl index 636998ec..9100a79e 100644 --- a/src/aws_rds.erl +++ b/src/aws_rds.erl @@ -10556,6 +10556,16 @@ restore_db_cluster_to_point_in_time(Client, Input, Options) %% `DBSnapshotIdentifier' %% must be the ARN of the shared DB snapshot. %% +%% To restore from a DB snapshot with an unsupported engine version, you must +%% first upgrade the +%% engine version of the snapshot. For more information about upgrading a RDS +%% for MySQL DB snapshot engine version, see Upgrading a MySQL DB snapshot +%% engine version: +%% https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/mysql-upgrade-snapshot.html. +%% For more information about upgrading a RDS for PostgreSQL DB snapshot +%% engine version, Upgrading a PostgreSQL DB snapshot engine version: +%% https://docs.aws.amazon.com/USER_UpgradeDBSnapshot.PostgreSQL.html. +%% %% This command doesn't apply to Aurora MySQL and Aurora PostgreSQL. For %% Aurora, use `RestoreDBClusterFromSnapshot'. -spec restore_db_instance_from_db_snapshot(aws_client:aws_client(), restore_db_instance_from_db_snapshot_message()) -> diff --git a/src/aws_s3.erl b/src/aws_s3.erl index fff9037a..90c144d0 100644 --- a/src/aws_s3.erl +++ b/src/aws_s3.erl @@ -1327,6 +1327,10 @@ %% Example: %% create_session_request() :: #{ +%% <<"BucketKeyEnabled">> => boolean(), +%% <<"SSEKMSEncryptionContext">> => string(), +%% <<"SSEKMSKeyId">> => string(), +%% <<"ServerSideEncryption">> => list(any()), %% <<"SessionMode">> => list(any()) %% } -type create_session_request() :: #{binary() => any()}. @@ -1501,7 +1505,11 @@ %% Example: %% create_session_output() :: #{ -%% <<"Credentials">> => session_credentials() +%% <<"BucketKeyEnabled">> => boolean(), +%% <<"Credentials">> => session_credentials(), +%% <<"SSEKMSEncryptionContext">> => string(), +%% <<"SSEKMSKeyId">> => string(), +%% <<"ServerSideEncryption">> => list(any()) %% } -type create_session_output() :: #{binary() => any()}. @@ -3424,6 +3432,14 @@ abort_multipart_upload(Client, Bucket, Key, Input0, Options0) -> %% https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html in %% the Amazon S3 User Guide. %% +%% If you provide an additional checksum +%% value: https://docs.aws.amazon.com/AmazonS3/latest/API/API_Checksum.html +%% in your `MultipartUpload' requests and the +%% object is encrypted with Key Management Service, you must have permission +%% to use the +%% `kms:Decrypt' action for the +%% `CompleteMultipartUpload' request to succeed. +%% %% Directory bucket permissions - To grant access to this API operation on a %% directory bucket, we recommend that you use the %% `CreateSession' @@ -3441,13 +3457,10 @@ abort_multipart_upload(Client, Bucket, Key, Input0, Options0) -> %% `CreateSession' %% : https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateSession.html. %% -%% If you provide an additional checksum -%% value: https://docs.aws.amazon.com/AmazonS3/latest/API/API_Checksum.html -%% in your `MultipartUpload' requests and the -%% object is encrypted with Key Management Service, you must have permission -%% to use the -%% `kms:Decrypt' action for the -%% `CompleteMultipartUpload' request to succeed. +%% If the object is encrypted with +%% SSE-KMS, you must also have the +%% `kms:GenerateDataKey' and `kms:Decrypt' permissions in IAM +%% identity-based policies and KMS key policies for the KMS key. %% %% Special errors %% @@ -3684,6 +3697,11 @@ complete_multipart_upload(Client, Bucket, Key, Input0, Options0) -> %% to the destination. The `s3express:SessionMode' condition %% key can't be set to `ReadOnly' on the copy destination bucket. %% +%% If the object is encrypted with +%% SSE-KMS, you must also have the +%% `kms:GenerateDataKey' and `kms:Decrypt' permissions in IAM +%% identity-based policies and KMS key policies for the KMS key. +%% %% For example policies, see Example bucket policies for S3 Express One Zone: %% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-security-iam-example-bucket-policies.html %% and Amazon Web Services Identity and Access Management (IAM) @@ -4292,8 +4310,58 @@ create_bucket(Client, Bucket, Input0, Options0) -> %% https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html %% in the Amazon S3 User Guide. %% -%% Directory buckets -For directory buckets, only server-side encryption with -%% Amazon S3 managed keys (SSE-S3) (`AES256') is supported. +%% Directory buckets - For directory buckets, there are only two supported +%% options for server-side encryption: server-side encryption with Amazon S3 +%% managed keys (SSE-S3) (`AES256') and server-side encryption with KMS +%% keys (SSE-KMS) (`aws:kms'). We recommend that the bucket's default +%% encryption uses the desired encryption configuration and you don't +%% override the bucket default encryption in your +%% `CreateSession' requests or `PUT' object requests. Then, new +%% objects +%% are automatically encrypted with the desired encryption settings. For more +%% information, see Protecting data with server-side encryption: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-serv-side-encryption.html +%% in the Amazon S3 User Guide. For more information about the encryption +%% overriding behaviors in directory buckets, see Specifying server-side +%% encryption with KMS for new object uploads: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-specifying-kms-encryption.html. +%% +%% In the Zonal endpoint API calls (except CopyObject: +%% https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html and +%% UploadPartCopy: +%% https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html) +%% using the REST API, the encryption request headers must match the +%% encryption settings that are specified in the `CreateSession' request. +%% You can't override the values of the encryption settings +%% (`x-amz-server-side-encryption', +%% `x-amz-server-side-encryption-aws-kms-key-id', +%% `x-amz-server-side-encryption-context', and +%% `x-amz-server-side-encryption-bucket-key-enabled') that are specified +%% in the `CreateSession' request. +%% You don't need to explicitly specify these encryption settings values +%% in Zonal endpoint API calls, and +%% Amazon S3 will use the encryption settings values from the +%% `CreateSession' request to protect new objects in the directory +%% bucket. +%% +%% When you use the CLI or the Amazon Web Services SDKs, for +%% `CreateSession', the session token refreshes automatically to avoid +%% service interruptions when a session expires. The CLI or the Amazon Web +%% Services SDKs use the bucket's default encryption configuration for +%% the +%% `CreateSession' request. It's not supported to override the +%% encryption settings values in the `CreateSession' request. +%% So in the Zonal endpoint API calls (except CopyObject: +%% https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html and +%% UploadPartCopy: +%% https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html), +%% the encryption request headers must match the default encryption +%% configuration of the directory bucket. +%% +%% For directory buckets, when you perform a `CreateMultipartUpload' +%% operation and an `UploadPartCopy' operation, +%% the request headers you provide in the `CreateMultipartUpload' request +%% must match the default encryption configuration of the destination bucket. %% %% HTTP Host header syntax %% @@ -4403,10 +4471,10 @@ create_multipart_upload(Client, Bucket, Key, Input0, Options0) -> end. %% @doc Creates a session that establishes temporary security credentials to -%% support fast authentication and authorization for the Zonal endpoint APIs -%% on directory buckets. +%% support fast authentication and authorization for the Zonal endpoint API +%% operations on directory buckets. %% -%% For more information about Zonal endpoint APIs that include the +%% For more information about Zonal endpoint API operations that include the %% Availability Zone in the request endpoint, see %% S3 Express One Zone APIs: %% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-APIs.html @@ -4423,7 +4491,7 @@ create_multipart_upload(Client, Bucket, Key, Input0, Options0) -> %% credentials that include the access key ID, secret access key, session %% token, and %% expiration. These credentials have associated permissions to access the -%% Zonal endpoint APIs. After +%% Zonal endpoint API operations. After %% the session is created, you don’t need to use other policies to grant %% permissions to each %% Zonal endpoint API individually. Instead, in your Zonal endpoint API @@ -4463,20 +4531,20 @@ create_multipart_upload(Client, Bucket, Key, Input0, Options0) -> %% in the %% Amazon S3 User Guide. %% -%% `CopyObject' API operation - Unlike other Zonal endpoint APIs, the -%% `CopyObject' API operation doesn't use the temporary security -%% credentials returned from the `CreateSession' API operation for -%% authentication and authorization. For information about authentication and -%% authorization of the `CopyObject' API operation on directory buckets, -%% see CopyObject: +%% `CopyObject' API operation - Unlike other Zonal endpoint API +%% operations, the `CopyObject' API operation doesn't use the +%% temporary security credentials returned from the `CreateSession' API +%% operation for authentication and authorization. For information about +%% authentication and authorization of the `CopyObject' API operation on +%% directory buckets, see CopyObject: %% https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html. %% -%% `HeadBucket' API operation - Unlike other Zonal endpoint APIs, the -%% `HeadBucket' API operation doesn't use the temporary security -%% credentials returned from the `CreateSession' API operation for -%% authentication and authorization. For information about authentication and -%% authorization of the `HeadBucket' API operation on directory buckets, -%% see HeadBucket: +%% `HeadBucket' API operation - Unlike other Zonal endpoint API +%% operations, the `HeadBucket' API operation doesn't use the +%% temporary security credentials returned from the `CreateSession' API +%% operation for authentication and authorization. For information about +%% authentication and authorization of the `HeadBucket' API operation on +%% directory buckets, see HeadBucket: %% https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadBucket.html. %% %% Permissions @@ -4500,10 +4568,90 @@ create_multipart_upload(Client, Bucket, Key, Input0, Options0) -> %% in the %% Amazon S3 User Guide. %% -%% To grant cross-account access to Zonal endpoint APIs, the bucket policy -%% should also grant both accounts the `s3express:CreateSession' +%% To grant cross-account access to Zonal endpoint API operations, the bucket +%% policy should also grant both accounts the `s3express:CreateSession' %% permission. %% +%% If you want to encrypt objects with SSE-KMS, you must also have the +%% `kms:GenerateDataKey' and the `kms:Decrypt' permissions in IAM +%% identity-based policies and KMS key policies for the target KMS key. +%% +%% Encryption +%% +%% For directory buckets, there are only two supported options for +%% server-side encryption: server-side encryption with Amazon S3 managed keys +%% (SSE-S3) (`AES256') and server-side encryption with KMS keys (SSE-KMS) +%% (`aws:kms'). We recommend that the bucket's default encryption +%% uses the desired encryption configuration and you don't override the +%% bucket default encryption in your +%% `CreateSession' requests or `PUT' object requests. Then, new +%% objects +%% are automatically encrypted with the desired encryption settings. For more +%% information, see Protecting data with server-side encryption: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-serv-side-encryption.html +%% in the Amazon S3 User Guide. For more information about the encryption +%% overriding behaviors in directory buckets, see Specifying server-side +%% encryption with KMS for new object uploads: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-specifying-kms-encryption.html. +%% +%% For Zonal endpoint (object-level) API operations: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-differences.html#s3-express-differences-api-operations +%% except CopyObject: +%% https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html and +%% UploadPartCopy: +%% https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html, +%% you authenticate and authorize requests through CreateSession: +%% https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateSession.html for +%% low latency. +%% To encrypt new objects in a directory bucket with SSE-KMS, you must +%% specify SSE-KMS as the directory bucket's default encryption +%% configuration with a KMS key (specifically, a customer managed key: +%% https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#customer-cmk). +%% Then, when a session is created for Zonal endpoint API operations, new +%% objects are automatically encrypted and decrypted with SSE-KMS and S3 +%% Bucket Keys during the session. +%% +%% Only 1 customer managed key: +%% https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#customer-cmk +%% is supported per directory bucket for the lifetime of the bucket. Amazon +%% Web Services managed key: +%% https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#aws-managed-cmk +%% (`aws/s3') isn't supported. +%% After you specify SSE-KMS as your bucket's default encryption +%% configuration with a customer managed key, you can't change the +%% customer managed key for the bucket's SSE-KMS configuration. +%% +%% In the Zonal endpoint API calls (except CopyObject: +%% https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html and +%% UploadPartCopy: +%% https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html) +%% using the REST API, +%% you can't override the values of the encryption settings +%% (`x-amz-server-side-encryption', +%% `x-amz-server-side-encryption-aws-kms-key-id', +%% `x-amz-server-side-encryption-context', and +%% `x-amz-server-side-encryption-bucket-key-enabled') from the +%% `CreateSession' request. +%% You don't need to explicitly specify these encryption settings values +%% in Zonal endpoint API calls, and +%% Amazon S3 will use the encryption settings values from the +%% `CreateSession' request to protect new objects in the directory +%% bucket. +%% +%% When you use the CLI or the Amazon Web Services SDKs, for +%% `CreateSession', the session token refreshes automatically to avoid +%% service interruptions when a session expires. The CLI or the Amazon Web +%% Services SDKs use the bucket's default encryption configuration for +%% the +%% `CreateSession' request. It's not supported to override the +%% encryption settings values in the `CreateSession' request. +%% Also, in the Zonal endpoint API calls (except CopyObject: +%% https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html and +%% UploadPartCopy: +%% https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html), +%% it's not supported to override the values of the encryption settings +%% from the `CreateSession' request. +%% %% HTTP Host header syntax %% %% Directory buckets - The HTTP Host header syntax is @@ -4542,13 +4690,36 @@ create_session(Client, Bucket, QueryMap, HeadersMap, Options0) Headers0 = [ + {<<"x-amz-server-side-encryption-bucket-key-enabled">>, maps:get(<<"x-amz-server-side-encryption-bucket-key-enabled">>, HeadersMap, undefined)}, + {<<"x-amz-server-side-encryption-context">>, maps:get(<<"x-amz-server-side-encryption-context">>, HeadersMap, undefined)}, + {<<"x-amz-server-side-encryption-aws-kms-key-id">>, maps:get(<<"x-amz-server-side-encryption-aws-kms-key-id">>, HeadersMap, undefined)}, + {<<"x-amz-server-side-encryption">>, maps:get(<<"x-amz-server-side-encryption">>, HeadersMap, undefined)}, {<<"x-amz-create-session-mode">>, maps:get(<<"x-amz-create-session-mode">>, HeadersMap, undefined)} ], Headers = [H || {_, V} = H <- Headers0, V =/= undefined], Query_ = [], - request(Client, get, Path, Query_, Headers, undefined, Options, SuccessStatusCode, Bucket). + case request(Client, get, Path, Query_, Headers, undefined, Options, SuccessStatusCode, Bucket) of + {ok, Body0, {_, ResponseHeaders, _} = Response} -> + ResponseHeadersParams = + [ + {<<"x-amz-server-side-encryption-bucket-key-enabled">>, <<"BucketKeyEnabled">>}, + {<<"x-amz-server-side-encryption-context">>, <<"SSEKMSEncryptionContext">>}, + {<<"x-amz-server-side-encryption-aws-kms-key-id">>, <<"SSEKMSKeyId">>}, + {<<"x-amz-server-side-encryption">>, <<"ServerSideEncryption">>} + ], + FoldFun = fun({Name_, Key_}, Acc_) -> + case lists:keyfind(Name_, 1, ResponseHeaders) of + false -> Acc_; + {_, Value_} -> Acc_#{Key_ => Value_} + end + end, + Body = lists:foldl(FoldFun, Body0, ResponseHeadersParams), + {ok, Body, Response}; + Result -> + Result + end. %% @doc Deletes the S3 bucket. %% @@ -4756,30 +4927,51 @@ delete_bucket_cors(Client, Bucket, Input0, Options0) -> request(Client, Method, Path, Query_, CustomHeaders ++ Headers, Input, Options, SuccessStatusCode, Bucket). -%% @doc -%% This operation is not supported by directory buckets. +%% @doc This implementation of the DELETE action resets the default +%% encryption for the bucket as +%% server-side encryption with Amazon S3 managed keys (SSE-S3). %% -%% This implementation of the DELETE action resets the default encryption for -%% the bucket as -%% server-side encryption with Amazon S3 managed keys (SSE-S3). For -%% information about the bucket -%% default encryption feature, see Amazon S3 Bucket Default Encryption: -%% https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html -%% in the Amazon S3 User Guide. +%% General purpose buckets - For information about the bucket default +%% encryption feature, see Amazon S3 Bucket +%% Default Encryption: +%% https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html in +%% the Amazon S3 User Guide. %% -%% To use this operation, you must have permissions to perform the -%% `s3:PutEncryptionConfiguration' action. The bucket owner has this -%% permission +%% Directory buckets - For directory buckets, there are only two supported +%% options for server-side encryption: SSE-S3 and SSE-KMS. For information +%% about the default encryption configuration in directory buckets, see +%% Setting default server-side encryption behavior +%% for directory buckets: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-bucket-encryption.html. +%% +%% Permissions +%% +%% General purpose bucket permissions - The +%% `s3:PutEncryptionConfiguration' permission is required in a policy. +%% The bucket owner has this permission %% by default. The bucket owner can grant this permission to others. For more %% information -%% about permissions, see Permissions Related to Bucket Subresource -%% Operations: +%% about permissions, see Permissions Related to Bucket Operations: %% https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources %% and Managing -%% Access Permissions to your Amazon S3 Resources: -%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html -%% in the -%% Amazon S3 User Guide. +%% Access Permissions to Your Amazon S3 Resources: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html. +%% +%% Directory bucket permissions - To grant access to this API operation, you +%% must have the `s3express:PutEncryptionConfiguration' permission in an +%% IAM identity-based policy instead of a bucket policy. Cross-account access +%% to this API operation isn't supported. This operation can only be +%% performed by the Amazon Web Services account that owns the resource. For +%% more information about directory bucket policies and permissions, see +%% Amazon Web Services Identity and Access Management (IAM) for S3 Express +%% One Zone: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-security-iam.html +%% in the Amazon S3 User Guide. +%% +%% HTTP Host header syntax +%% +%% Directory buckets - The HTTP Host header syntax is +%% `s3express-control.region.amazonaws.com'. %% %% The following operations are related to `DeleteBucketEncryption': %% @@ -6270,31 +6462,55 @@ get_bucket_cors(Client, Bucket, QueryMap, HeadersMap, Options0) request(Client, get, Path, Query_, Headers, undefined, Options, SuccessStatusCode, Bucket). -%% @doc -%% This operation is not supported by directory buckets. +%% @doc Returns the default encryption configuration for an Amazon S3 bucket. %% -%% Returns the default encryption configuration for an Amazon S3 bucket. By -%% default, all buckets +%% By default, all buckets %% have a default encryption configuration that uses server-side encryption %% with Amazon S3 managed -%% keys (SSE-S3). For information about the bucket default encryption -%% feature, see Amazon S3 Bucket +%% keys (SSE-S3). +%% +%% General purpose buckets - For information about the bucket default +%% encryption feature, see Amazon S3 Bucket %% Default Encryption: %% https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html in %% the Amazon S3 User Guide. %% -%% To use this operation, you must have permission to perform the -%% `s3:GetEncryptionConfiguration' action. The bucket owner has this -%% permission +%% Directory buckets - For directory buckets, there are only two supported +%% options for server-side encryption: SSE-S3 and SSE-KMS. For information +%% about the default encryption configuration in directory buckets, see +%% Setting default server-side encryption behavior +%% for directory buckets: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-bucket-encryption.html. +%% +%% Permissions +%% +%% General purpose bucket permissions - The +%% `s3:GetEncryptionConfiguration' permission is required in a policy. +%% The bucket owner has this permission %% by default. The bucket owner can grant this permission to others. For more %% information -%% about permissions, see Permissions Related to Bucket Subresource -%% Operations: +%% about permissions, see Permissions Related to Bucket Operations: %% https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources %% and Managing %% Access Permissions to Your Amazon S3 Resources: %% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html. %% +%% Directory bucket permissions - To grant access to this API operation, you +%% must have the `s3express:GetEncryptionConfiguration' permission in an +%% IAM identity-based policy instead of a bucket policy. Cross-account access +%% to this API operation isn't supported. This operation can only be +%% performed by the Amazon Web Services account that owns the resource. For +%% more information about directory bucket policies and permissions, see +%% Amazon Web Services Identity and Access Management (IAM) for S3 Express +%% One Zone: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-security-iam.html +%% in the Amazon S3 User Guide. +%% +%% HTTP Host header syntax +%% +%% Directory buckets - The HTTP Host header syntax is +%% `s3express-control.region.amazonaws.com'. +%% %% The following operations are related to `GetBucketEncryption': %% %% PutBucketEncryption: @@ -7515,6 +7731,11 @@ get_bucket_website(Client, Bucket, QueryMap, HeadersMap, Options0) %% `CreateSession' %% : https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateSession.html. %% +%% If the object is encrypted using +%% SSE-KMS, you must also have the +%% `kms:GenerateDataKey' and `kms:Decrypt' permissions in IAM +%% identity-based policies and KMS key policies for the KMS key. +%% %% Storage classes %% %% If the object you are retrieving is stored in the S3 Glacier Flexible @@ -7550,6 +7771,13 @@ get_bucket_website(Client, Bucket, QueryMap, HeadersMap, Options0) %% `GetObject' requests for the object that uses %% these types of keys, you’ll get an HTTP `400 Bad Request' error. %% +%% Directory buckets - For directory buckets, there are only two supported +%% options for server-side encryption: SSE-S3 and SSE-KMS. SSE-C isn't +%% supported. For more +%% information, see Protecting data with server-side encryption: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-serv-side-encryption.html +%% in the Amazon S3 User Guide. +%% %% Overriding response header values through the request %% %% There are times when you want to override certain response header values @@ -7848,7 +8076,7 @@ get_object_acl(Client, Bucket, Key, QueryMap, HeadersMap, Options0) %% %% General purpose bucket permissions - To use %% `GetObjectAttributes', you must have READ access to the object. The -%% permissions that you need to use this operation with depend on whether the +%% permissions that you need to use this operation depend on whether the %% bucket is versioned. If the bucket is versioned, you need both the %% `s3:GetObjectVersion' and `s3:GetObjectVersionAttributes' %% permissions for this operation. If the bucket is not versioned, you need @@ -7888,6 +8116,11 @@ get_object_acl(Client, Bucket, Key, QueryMap, HeadersMap, Options0) %% `CreateSession' %% : https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateSession.html. %% +%% If the object is encrypted with +%% SSE-KMS, you must also have the +%% `kms:GenerateDataKey' and `kms:Decrypt' permissions in IAM +%% identity-based policies and KMS key policies for the KMS key. +%% %% Encryption %% %% Encryption request headers, like `x-amz-server-side-encryption', @@ -7924,9 +8157,21 @@ get_object_acl(Client, Bucket, Key, QueryMap, HeadersMap, Options0) %% in the Amazon S3 %% User Guide. %% -%% Directory bucket permissions - For directory buckets, only server-side -%% encryption with Amazon S3 managed keys (SSE-S3) (`AES256') is -%% supported. +%% Directory bucket permissions - For directory buckets, there are only two +%% supported options for server-side encryption: server-side encryption with +%% Amazon S3 managed keys (SSE-S3) (`AES256') and server-side encryption +%% with KMS keys (SSE-KMS) (`aws:kms'). We recommend that the +%% bucket's default encryption uses the desired encryption configuration +%% and you don't override the bucket default encryption in your +%% `CreateSession' requests or `PUT' object requests. Then, new +%% objects +%% are automatically encrypted with the desired encryption settings. For more +%% information, see Protecting data with server-side encryption: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-serv-side-encryption.html +%% in the Amazon S3 User Guide. For more information about the encryption +%% overriding behaviors in directory buckets, see Specifying server-side +%% encryption with KMS for new object uploads: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-specifying-kms-encryption.html. %% %% Versioning %% @@ -8679,6 +8924,14 @@ head_bucket(Client, Bucket, Input0, Options0) -> %% `CreateSession' %% : https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateSession.html. %% +%% If you enable `x-amz-checksum-mode' in the request and the object is +%% encrypted with +%% Amazon Web Services Key Management Service (Amazon Web Services KMS), you +%% must also have the +%% `kms:GenerateDataKey' and `kms:Decrypt' permissions in IAM +%% identity-based policies and KMS key policies for the KMS key to retrieve +%% the checksum of the object. +%% %% Encryption %% %% Encryption request headers, like `x-amz-server-side-encryption', @@ -8715,9 +8968,12 @@ head_bucket(Client, Bucket, Input0, Options0) -> %% in the Amazon S3 %% User Guide. %% -%% Directory bucket permissions - For directory buckets, only server-side -%% encryption with Amazon S3 managed keys (SSE-S3) (`AES256') is -%% supported. +%% Directory bucket - For directory buckets, there are only two supported +%% options for server-side encryption: SSE-S3 and SSE-KMS. SSE-C isn't +%% supported. For more +%% information, see Protecting data with server-side encryption: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-serv-side-encryption.html +%% in the Amazon S3 User Guide. %% %% Versioning %% @@ -10565,27 +10821,94 @@ put_bucket_cors(Client, Bucket, Input0, Options0) -> request(Client, Method, Path, Query_, CustomHeaders ++ Headers, Input, Options, SuccessStatusCode, Bucket). -%% @doc -%% This operation is not supported by directory buckets. -%% -%% This action uses the `encryption' subresource to configure default -%% encryption +%% @doc This operation configures default encryption %% and Amazon S3 Bucket Keys for an existing bucket. %% +%% Directory buckets - For directory buckets, you must make requests for this +%% API operation to the Regional endpoint. These endpoints support path-style +%% requests in the format +%% ``` +%% https://s3express-control.region_code.amazonaws.com/bucket-name +%% '''. Virtual-hosted-style requests aren't supported. +%% For more information, see Regional and Zonal endpoints: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-Regions-and-Zones.html +%% in the +%% Amazon S3 User Guide. +%% %% By default, all buckets have a default encryption configuration that uses %% server-side -%% encryption with Amazon S3 managed keys (SSE-S3). You can optionally -%% configure default encryption +%% encryption with Amazon S3 managed keys (SSE-S3). +%% +%% General purpose buckets +%% +%% You can optionally configure default encryption %% for a bucket by using server-side encryption with Key Management Service %% (KMS) keys (SSE-KMS) or %% dual-layer server-side encryption with Amazon Web Services KMS keys -%% (DSSE-KMS). If you specify default encryption by using +%% (DSSE-KMS). +%% If you specify default encryption by using %% SSE-KMS, you can also configure Amazon S3 Bucket -%% Keys: https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-key.html. If -%% you use PutBucketEncryption to set your default bucket encryption: +%% Keys: https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-key.html. For +%% information about the bucket default +%% encryption feature, see Amazon S3 Bucket Default Encryption: +%% https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html +%% in the Amazon S3 User Guide. +%% +%% If you use PutBucketEncryption to set your default bucket encryption: %% https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html to -%% SSE-KMS, you should verify that your KMS key ID is correct. Amazon S3 does -%% not validate the KMS key ID provided in PutBucketEncryption requests. +%% SSE-KMS, you should verify that your KMS key ID is correct. Amazon S3 +%% doesn't validate the KMS key ID provided in PutBucketEncryption +%% requests. +%% +%% Directory buckets - You can optionally configure default encryption +%% for a bucket by using server-side encryption with Key Management Service +%% (KMS) keys (SSE-KMS). +%% +%% We recommend that the bucket's default encryption uses the desired +%% encryption configuration and you don't override the bucket default +%% encryption in your +%% `CreateSession' requests or `PUT' object requests. Then, new +%% objects +%% are automatically encrypted with the desired encryption settings. For more +%% information about the encryption overriding behaviors in directory +%% buckets, see Specifying server-side encryption with KMS for new object +%% uploads: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-specifying-kms-encryption.html. +%% +%% Your SSE-KMS configuration can only support 1 customer managed key: +%% https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#customer-cmk +%% per directory bucket for the lifetime of the bucket. +%% Amazon Web Services managed key: +%% https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#aws-managed-cmk +%% (`aws/s3') isn't supported. +%% +%% S3 Bucket Keys are always enabled for `GET' and `PUT' operations +%% in a directory bucket and can’t be disabled. S3 Bucket Keys aren't +%% supported, when you copy SSE-KMS encrypted objects from general purpose +%% buckets +%% to directory buckets, from directory buckets to general purpose buckets, +%% or between directory buckets, through CopyObject: +%% https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html, +%% UploadPartCopy: +%% https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html, +%% the Copy operation in Batch Operations: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/directory-buckets-objects-Batch-Ops, +%% or +%% the import jobs: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-import-job. +%% In this case, Amazon S3 makes a call to KMS every time a copy request is +%% made for a KMS-encrypted object. +%% +%% When you specify an KMS customer managed key: +%% https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#customer-cmk +%% for encryption in your directory bucket, only use the key ID or key ARN. +%% The key alias format of the KMS key isn't supported. +%% +%% For directory buckets, if you use PutBucketEncryption to set your default +%% bucket encryption: +%% https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html to +%% SSE-KMS, Amazon S3 validates the KMS key ID provided in +%% PutBucketEncryption requests. %% %% If you're specifying a customer managed KMS key, we recommend using a %% fully qualified @@ -10600,13 +10923,14 @@ put_bucket_cors(Client, Bucket, Input0, Options0) -> %% Authenticating Requests (Amazon Web Services Signature Version 4): %% https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html. %% -%% To use this operation, you must have permission to perform the -%% `s3:PutEncryptionConfiguration' action. The bucket owner has this -%% permission +%% Permissions +%% +%% General purpose bucket permissions - The +%% `s3:PutEncryptionConfiguration' permission is required in a policy. +%% The bucket owner has this permission %% by default. The bucket owner can grant this permission to others. For more %% information -%% about permissions, see Permissions Related to Bucket Subresource -%% Operations: +%% about permissions, see Permissions Related to Bucket Operations: %% https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources %% and Managing %% Access Permissions to Your Amazon S3 Resources: @@ -10614,6 +10938,27 @@ put_bucket_cors(Client, Bucket, Input0, Options0) -> %% in the %% Amazon S3 User Guide. %% +%% Directory bucket permissions - To grant access to this API operation, you +%% must have the `s3express:PutEncryptionConfiguration' permission in an +%% IAM identity-based policy instead of a bucket policy. Cross-account access +%% to this API operation isn't supported. This operation can only be +%% performed by the Amazon Web Services account that owns the resource. For +%% more information about directory bucket policies and permissions, see +%% Amazon Web Services Identity and Access Management (IAM) for S3 Express +%% One Zone: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-security-iam.html +%% in the Amazon S3 User Guide. +%% +%% To set a directory bucket default encryption with SSE-KMS, you must also +%% have the `kms:GenerateDataKey' and the `kms:Decrypt' permissions +%% in IAM identity-based policies and KMS key policies for the target KMS +%% key. +%% +%% HTTP Host header syntax +%% +%% Directory buckets - The HTTP Host header syntax is +%% `s3express-control.region.amazonaws.com'. +%% %% The following operations are related to `PutBucketEncryption': %% %% GetBucketEncryption: @@ -12134,6 +12479,11 @@ put_bucket_website(Client, Bucket, Input0, Options0) -> %% `CreateSession' %% : https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateSession.html. %% +%% If the object is encrypted with +%% SSE-KMS, you must also have the +%% `kms:GenerateDataKey' and `kms:Decrypt' permissions in IAM +%% identity-based policies and KMS key policies for the KMS key. +%% %% Data integrity with Content-MD5 %% %% General purpose bucket - To ensure that data is not corrupted traversing @@ -13434,6 +13784,11 @@ select_object_content(Client, Bucket, Key, Input0, Options0) -> %% `CreateSession' %% : https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateSession.html. %% +%% If the object is encrypted with +%% SSE-KMS, you must also have the +%% `kms:GenerateDataKey' and `kms:Decrypt' permissions in IAM +%% identity-based policies and KMS key policies for the KMS key. +%% %% Data integrity %% %% General purpose bucket - To ensure that data is not corrupted traversing @@ -13494,14 +13849,16 @@ select_object_content(Client, Bucket, Key, Input0, Options0) -> %% %% x-amz-server-side-encryption-customer-key-MD5 %% -%% Directory bucket - For directory buckets, only server-side encryption with -%% Amazon S3 managed keys (SSE-S3) (`AES256') is supported. -%% %% For more information, see Using Server-Side %% Encryption: %% https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingServerSideEncryption.html %% in the Amazon S3 User Guide. %% +%% Directory buckets - For directory buckets, there are only two supported +%% options for server-side encryption: server-side encryption with Amazon S3 +%% managed keys (SSE-S3) (`AES256') and server-side encryption with KMS +%% keys (SSE-KMS) (`aws:kms'). +%% %% Special errors %% %% Error Code: `NoSuchUpload' @@ -13744,6 +14101,11 @@ upload_part(Client, Bucket, Key, Input0, Options0) -> %% to the destination. The `s3express:SessionMode' condition %% key cannot be set to `ReadOnly' on the copy destination. %% +%% If the object is encrypted with +%% SSE-KMS, you must also have the +%% `kms:GenerateDataKey' and `kms:Decrypt' permissions in IAM +%% identity-based policies and KMS key policies for the KMS key. +%% %% For example policies, see Example bucket policies for S3 Express One Zone: %% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-security-iam-example-bucket-policies.html %% and Amazon Web Services Identity and Access Management (IAM) @@ -13762,8 +14124,26 @@ upload_part(Client, Bucket, Key, Input0, Options0) -> %% UploadPart: %% https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html. %% -%% Directory buckets - For directory buckets, only server-side encryption -%% with Amazon S3 managed keys (SSE-S3) (`AES256') is supported. +%% Directory buckets - For directory buckets, there are only two supported +%% options for server-side encryption: server-side encryption with Amazon S3 +%% managed keys (SSE-S3) (`AES256') and server-side encryption with KMS +%% keys (SSE-KMS) (`aws:kms'). For more +%% information, see Protecting data with server-side encryption: +%% https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-serv-side-encryption.html +%% in the Amazon S3 User Guide. +%% +%% For directory buckets, when you perform a `CreateMultipartUpload' +%% operation and an `UploadPartCopy' operation, +%% the request headers you provide in the `CreateMultipartUpload' request +%% must match the default encryption configuration of the destination bucket. +%% +%% S3 Bucket Keys aren't supported, when you copy SSE-KMS encrypted +%% objects from general purpose buckets +%% to directory buckets, from directory buckets to general purpose buckets, +%% or between directory buckets, through UploadPartCopy: +%% https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html. +%% In this case, Amazon S3 makes a call to KMS every time a copy request is +%% made for a KMS-encrypted object. %% %% Special errors %%