From 076c8ace5f4db82f82f35c16a6d74725be2ca5aa Mon Sep 17 00:00:00 2001 From: gruebel Date: Sun, 15 Dec 2019 16:06:08 +0100 Subject: [PATCH 1/9] Add codepipeline.create_pipeline --- IMPLEMENTATION_COVERAGE.md | 188 +++++++++- moto/__init__.py | 1 + moto/backends.py | 2 + moto/codepipeline/__init__.py | 4 + moto/codepipeline/exceptions.py | 10 + moto/codepipeline/models.py | 78 ++++ moto/codepipeline/responses.py | 17 + moto/codepipeline/urls.py | 6 + tests/test_codepipeline/test_codepipeline.py | 363 +++++++++++++++++++ 9 files changed, 649 insertions(+), 20 deletions(-) create mode 100644 moto/codepipeline/__init__.py create mode 100644 moto/codepipeline/exceptions.py create mode 100644 moto/codepipeline/models.py create mode 100644 moto/codepipeline/responses.py create mode 100644 moto/codepipeline/urls.py create mode 100644 tests/test_codepipeline/test_codepipeline.py diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md index 5d9f18ebf..24009f948 100644 --- a/IMPLEMENTATION_COVERAGE.md +++ b/IMPLEMENTATION_COVERAGE.md @@ -137,11 +137,13 @@ ## amplify 0% implemented - [ ] create_app +- [ ] create_backend_environment - [ ] create_branch - [ ] create_deployment - [ ] create_domain_association - [ ] create_webhook - [ ] delete_app +- [ ] delete_backend_environment - [ ] delete_branch - [ ] delete_domain_association - [ ] delete_job @@ -149,12 +151,14 @@ - [ ] generate_access_logs - [ ] get_app - [ ] get_artifact_url +- [ ] get_backend_environment - [ ] get_branch - [ ] get_domain_association - [ ] get_job - [ ] get_webhook - [ ] list_apps - [ ] list_artifacts +- [ ] list_backend_environments - [ ] list_branches - [ ] list_domain_associations - [ ] list_jobs @@ -477,18 +481,22 @@ ## appsync 0% implemented +- [ ] create_api_cache - [ ] create_api_key - [ ] create_data_source - [ ] create_function - [ ] create_graphql_api - [ ] create_resolver - [ ] create_type +- [ ] delete_api_cache - [ ] delete_api_key - [ ] delete_data_source - [ ] delete_function - [ ] delete_graphql_api - [ ] delete_resolver - [ ] delete_type +- [ ] flush_api_cache +- [ ] get_api_cache - [ ] get_data_source - [ ] get_function - [ ] get_graphql_api @@ -507,6 +515,7 @@ - [ ] start_schema_creation - [ ] tag_resource - [ ] untag_resource +- [ ] update_api_cache - [ ] update_api_key - [ ] update_data_source - [ ] update_function @@ -706,6 +715,7 @@ - [ ] associate_phone_number_with_user - [ ] associate_phone_numbers_with_voice_connector - [ ] associate_phone_numbers_with_voice_connector_group +- [ ] batch_create_attendee - [ ] batch_create_room_membership - [ ] batch_delete_phone_number - [ ] batch_suspend_user @@ -713,14 +723,18 @@ - [ ] batch_update_phone_number - [ ] batch_update_user - [ ] create_account +- [ ] create_attendee - [ ] create_bot +- [ ] create_meeting - [ ] create_phone_number_order - [ ] create_room - [ ] create_room_membership - [ ] create_voice_connector - [ ] create_voice_connector_group - [ ] delete_account +- [ ] delete_attendee - [ ] delete_events_configuration +- [ ] delete_meeting - [ ] delete_phone_number - [ ] delete_room - [ ] delete_room_membership @@ -735,9 +749,11 @@ - [ ] disassociate_phone_numbers_from_voice_connector_group - [ ] get_account - [ ] get_account_settings +- [ ] get_attendee - [ ] get_bot - [ ] get_events_configuration - [ ] get_global_settings +- [ ] get_meeting - [ ] get_phone_number - [ ] get_phone_number_order - [ ] get_phone_number_settings @@ -753,7 +769,9 @@ - [ ] get_voice_connector_termination_health - [ ] invite_users - [ ] list_accounts +- [ ] list_attendees - [ ] list_bots +- [ ] list_meetings - [ ] list_phone_number_orders - [ ] list_phone_numbers - [ ] list_room_memberships @@ -869,7 +887,7 @@ - [ ] upgrade_published_schema ## cloudformation -40% implemented +32% implemented - [ ] cancel_update_stack - [ ] continue_update_rollback - [X] create_change_set @@ -880,6 +898,7 @@ - [X] delete_stack - [X] delete_stack_instances - [X] delete_stack_set +- [ ] deregister_type - [ ] describe_account_limits - [X] describe_change_set - [ ] describe_stack_drift_detection_status @@ -891,8 +910,11 @@ - [ ] describe_stack_set - [ ] describe_stack_set_operation - [X] describe_stacks +- [ ] describe_type +- [ ] describe_type_registration - [ ] detect_stack_drift - [ ] detect_stack_resource_drift +- [ ] detect_stack_set_drift - [ ] estimate_template_cost - [X] execute_change_set - [ ] get_stack_policy @@ -907,7 +929,13 @@ - [ ] list_stack_set_operations - [ ] list_stack_sets - [X] list_stacks +- [ ] list_type_registrations +- [ ] list_type_versions +- [ ] list_types +- [ ] record_handler_progress +- [ ] register_type - [ ] set_stack_policy +- [ ] set_type_default_version - [ ] signal_resource - [ ] stop_stack_set_operation - [X] update_stack @@ -1045,6 +1073,7 @@ - [ ] delete_trail - [ ] describe_trails - [ ] get_event_selectors +- [ ] get_insight_selectors - [ ] get_trail - [ ] get_trail_status - [ ] list_public_keys @@ -1052,13 +1081,14 @@ - [ ] list_trails - [ ] lookup_events - [ ] put_event_selectors +- [ ] put_insight_selectors - [ ] remove_tags - [ ] start_logging - [ ] stop_logging - [ ] update_trail ## cloudwatch -39% implemented +43% implemented - [X] delete_alarms - [ ] delete_anomaly_detector - [X] delete_dashboards @@ -1073,7 +1103,7 @@ - [X] get_metric_statistics - [ ] get_metric_widget_image - [X] list_dashboards -- [ ] list_metrics +- [X] list_metrics - [ ] list_tags_for_resource - [ ] put_anomaly_detector - [X] put_dashboard @@ -1107,20 +1137,30 @@ ## codecommit 0% implemented +- [ ] associate_approval_rule_template_with_repository +- [ ] batch_associate_approval_rule_template_with_repositories - [ ] batch_describe_merge_conflicts +- [ ] batch_disassociate_approval_rule_template_from_repositories - [ ] batch_get_commits - [ ] batch_get_repositories +- [ ] create_approval_rule_template - [ ] create_branch - [ ] create_commit - [ ] create_pull_request +- [ ] create_pull_request_approval_rule - [ ] create_repository - [ ] create_unreferenced_merge_commit +- [ ] delete_approval_rule_template - [ ] delete_branch - [ ] delete_comment_content - [ ] delete_file +- [ ] delete_pull_request_approval_rule - [ ] delete_repository - [ ] describe_merge_conflicts - [ ] describe_pull_request_events +- [ ] disassociate_approval_rule_template_from_repository +- [ ] evaluate_pull_request_approval_rules +- [ ] get_approval_rule_template - [ ] get_blob - [ ] get_branch - [ ] get_comment @@ -1134,11 +1174,16 @@ - [ ] get_merge_conflicts - [ ] get_merge_options - [ ] get_pull_request +- [ ] get_pull_request_approval_states +- [ ] get_pull_request_override_state - [ ] get_repository - [ ] get_repository_triggers +- [ ] list_approval_rule_templates +- [ ] list_associated_approval_rule_templates_for_repository - [ ] list_branches - [ ] list_pull_requests - [ ] list_repositories +- [ ] list_repositories_for_approval_rule_template - [ ] list_tags_for_resource - [ ] merge_branches_by_fast_forward - [ ] merge_branches_by_squash @@ -1146,6 +1191,7 @@ - [ ] merge_pull_request_by_fast_forward - [ ] merge_pull_request_by_squash - [ ] merge_pull_request_by_three_way +- [ ] override_pull_request_approval_rules - [ ] post_comment_for_compared_commit - [ ] post_comment_for_pull_request - [ ] post_comment_reply @@ -1154,8 +1200,13 @@ - [ ] tag_resource - [ ] test_repository_triggers - [ ] untag_resource +- [ ] update_approval_rule_template_content +- [ ] update_approval_rule_template_description +- [ ] update_approval_rule_template_name - [ ] update_comment - [ ] update_default_branch +- [ ] update_pull_request_approval_rule_content +- [ ] update_pull_request_approval_state - [ ] update_pull_request_description - [ ] update_pull_request_status - [ ] update_pull_request_title @@ -1212,11 +1263,11 @@ - [ ] update_deployment_group ## codepipeline -0% implemented +2% implemented - [ ] acknowledge_job - [ ] acknowledge_third_party_job - [ ] create_custom_action_type -- [ ] create_pipeline +- [X] create_pipeline - [ ] delete_custom_action_type - [ ] delete_pipeline - [ ] delete_webhook @@ -1497,19 +1548,22 @@ - [ ] stop_phi_detection_job ## config -31% implemented +25% implemented - [X] batch_get_aggregate_resource_config - [X] batch_get_resource_config - [X] delete_aggregation_authorization - [ ] delete_config_rule - [X] delete_configuration_aggregator - [X] delete_configuration_recorder +- [ ] delete_conformance_pack - [X] delete_delivery_channel - [ ] delete_evaluation_results - [ ] delete_organization_config_rule +- [ ] delete_organization_conformance_pack - [ ] delete_pending_aggregation_request - [ ] delete_remediation_configuration - [ ] delete_remediation_exceptions +- [ ] delete_resource_config - [ ] delete_retention_configuration - [ ] deliver_config_snapshot - [ ] describe_aggregate_compliance_by_config_rules @@ -1522,10 +1576,15 @@ - [X] describe_configuration_aggregators - [X] describe_configuration_recorder_status - [X] describe_configuration_recorders +- [ ] describe_conformance_pack_compliance +- [ ] describe_conformance_pack_status +- [ ] describe_conformance_packs - [ ] describe_delivery_channel_status - [X] describe_delivery_channels - [ ] describe_organization_config_rule_statuses - [ ] describe_organization_config_rules +- [ ] describe_organization_conformance_pack_statuses +- [ ] describe_organization_conformance_packs - [ ] describe_pending_aggregation_requests - [ ] describe_remediation_configurations - [ ] describe_remediation_exceptions @@ -1539,8 +1598,11 @@ - [ ] get_compliance_details_by_resource - [ ] get_compliance_summary_by_config_rule - [ ] get_compliance_summary_by_resource_type +- [ ] get_conformance_pack_compliance_details +- [ ] get_conformance_pack_compliance_summary - [ ] get_discovered_resource_counts - [ ] get_organization_config_rule_detailed_status +- [ ] get_organization_conformance_pack_detailed_status - [X] get_resource_config_history - [X] list_aggregate_discovered_resources - [X] list_discovered_resources @@ -1549,11 +1611,14 @@ - [ ] put_config_rule - [X] put_configuration_aggregator - [X] put_configuration_recorder +- [ ] put_conformance_pack - [X] put_delivery_channel - [ ] put_evaluations - [ ] put_organization_config_rule +- [ ] put_organization_conformance_pack - [ ] put_remediation_configurations - [ ] put_remediation_exceptions +- [ ] put_resource_config - [ ] put_retention_configuration - [ ] select_resource_config - [ ] start_config_rules_evaluation @@ -1583,6 +1648,7 @@ - [ ] list_tags_for_resource - [ ] list_user_hierarchy_groups - [ ] list_users +- [ ] start_chat_contact - [ ] start_outbound_voice_contact - [ ] stop_contact - [ ] tag_resource @@ -1594,6 +1660,14 @@ - [ ] update_user_routing_profile - [ ] update_user_security_profiles +## connectparticipant +0% implemented +- [ ] create_participant_connection +- [ ] disconnect_participant +- [ ] get_transcript +- [ ] send_event +- [ ] send_message + ## cur 0% implemented - [ ] delete_report_definition @@ -2016,7 +2090,7 @@ - [ ] verify_trust ## dynamodb -19% implemented +18% implemented - [ ] batch_get_item - [ ] batch_write_item - [ ] create_backup @@ -2032,6 +2106,7 @@ - [ ] describe_global_table_settings - [ ] describe_limits - [ ] describe_table +- [ ] describe_table_replica_auto_scaling - [ ] describe_time_to_live - [X] get_item - [ ] list_backups @@ -2052,6 +2127,7 @@ - [ ] update_global_table_settings - [ ] update_item - [ ] update_table +- [ ] update_table_replica_auto_scaling - [ ] update_time_to_live ## dynamodbstreams @@ -2216,6 +2292,7 @@ - [ ] describe_elastic_gpus - [ ] describe_export_image_tasks - [ ] describe_export_tasks +- [ ] describe_fast_snapshot_restores - [ ] describe_fleet_history - [ ] describe_fleet_instances - [ ] describe_fleets @@ -2283,8 +2360,8 @@ - [X] describe_volumes - [ ] describe_volumes_modifications - [X] describe_vpc_attribute -- [X] describe_vpc_classic_link -- [X] describe_vpc_classic_link_dns_support +- [ ] describe_vpc_classic_link +- [ ] describe_vpc_classic_link_dns_support - [ ] describe_vpc_endpoint_connection_notifications - [ ] describe_vpc_endpoint_connections - [ ] describe_vpc_endpoint_service_configurations @@ -2301,6 +2378,7 @@ - [X] detach_volume - [X] detach_vpn_gateway - [ ] disable_ebs_encryption_by_default +- [ ] disable_fast_snapshot_restores - [ ] disable_transit_gateway_route_table_propagation - [ ] disable_vgw_route_propagation - [X] disable_vpc_classic_link @@ -2313,6 +2391,7 @@ - [ ] disassociate_transit_gateway_route_table - [X] disassociate_vpc_cidr_block - [ ] enable_ebs_encryption_by_default +- [ ] enable_fast_snapshot_restores - [ ] enable_transit_gateway_route_table_propagation - [ ] enable_vgw_route_propagation - [ ] enable_volume_io @@ -2353,6 +2432,7 @@ - [ ] modify_instance_capacity_reservation_attributes - [ ] modify_instance_credit_specification - [ ] modify_instance_event_start_time +- [ ] modify_instance_metadata_options - [ ] modify_instance_placement - [ ] modify_launch_template - [X] modify_network_interface_attribute @@ -3344,7 +3424,7 @@ - [ ] describe_events ## iam -65% implemented +67% implemented - [ ] add_client_id_to_open_id_connect_provider - [X] add_role_to_instance_profile - [X] add_user_to_group @@ -3385,7 +3465,7 @@ - [ ] delete_service_linked_role - [ ] delete_service_specific_credential - [X] delete_signing_certificate -- [ ] delete_ssh_public_key +- [X] delete_ssh_public_key - [X] delete_user - [ ] delete_user_permissions_boundary - [X] delete_user_policy @@ -3419,7 +3499,7 @@ - [ ] get_service_last_accessed_details - [ ] get_service_last_accessed_details_with_entities - [ ] get_service_linked_role_deletion_status -- [ ] get_ssh_public_key +- [X] get_ssh_public_key - [X] get_user - [X] get_user_policy - [ ] list_access_keys @@ -3480,11 +3560,11 @@ - [ ] update_server_certificate - [ ] update_service_specific_credential - [X] update_signing_certificate -- [ ] update_ssh_public_key +- [X] update_ssh_public_key - [X] update_user - [X] upload_server_certificate - [X] upload_signing_certificate -- [ ] upload_ssh_public_key +- [X] upload_ssh_public_key ## importexport 0% implemented @@ -3551,6 +3631,7 @@ - [ ] cancel_job - [ ] cancel_job_execution - [ ] clear_default_authorizer +- [ ] confirm_topic_rule_destination - [ ] create_authorizer - [ ] create_billing_group - [ ] create_certificate_from_csr @@ -3569,6 +3650,7 @@ - [X] create_thing_group - [X] create_thing_type - [ ] create_topic_rule +- [ ] create_topic_rule_destination - [ ] delete_account_audit_configuration - [ ] delete_authorizer - [ ] delete_billing_group @@ -3590,6 +3672,7 @@ - [X] delete_thing_group - [X] delete_thing_type - [ ] delete_topic_rule +- [ ] delete_topic_rule_destination - [ ] delete_v2_logging_level - [ ] deprecate_thing_type - [ ] describe_account_audit_configuration @@ -3633,6 +3716,7 @@ - [ ] get_registration_code - [ ] get_statistics - [ ] get_topic_rule +- [ ] get_topic_rule_destination - [ ] get_v2_logging_options - [ ] list_active_violations - [ ] list_attached_policies @@ -3674,6 +3758,7 @@ - [X] list_things - [ ] list_things_in_billing_group - [X] list_things_in_thing_group +- [ ] list_topic_rule_destinations - [ ] list_topic_rules - [ ] list_v2_logging_levels - [ ] list_violation_events @@ -3716,6 +3801,7 @@ - [X] update_thing - [X] update_thing_group - [X] update_thing_groups_for_thing +- [ ] update_topic_rule_destination - [ ] validate_security_profile_behaviors ## iot-data @@ -4575,6 +4661,12 @@ - [ ] notify_migration_task_state - [ ] put_resource_attributes +## migrationhub-config +0% implemented +- [ ] create_home_region_control +- [ ] describe_home_region_controls +- [ ] get_home_region + ## mobile 0% implemented - [ ] create_project @@ -4811,7 +4903,7 @@ - [ ] update_server_engine_attributes ## organizations -43% implemented +50% implemented - [ ] accept_handshake - [X] attach_policy - [ ] cancel_handshake @@ -4850,12 +4942,12 @@ - [X] list_policies - [X] list_policies_for_target - [X] list_roots -- [x] list_tags_for_resource +- [X] list_tags_for_resource - [X] list_targets_for_policy - [X] move_account - [ ] remove_account_from_organization -- [x] tag_resource -- [x] untag_resource +- [X] tag_resource +- [X] untag_resource - [ ] update_organizational_unit - [ ] update_policy @@ -4926,6 +5018,7 @@ - [ ] create_push_template - [ ] create_segment - [ ] create_sms_template +- [ ] create_voice_template - [ ] delete_adm_channel - [ ] delete_apns_channel - [ ] delete_apns_sandbox_channel @@ -4946,6 +5039,7 @@ - [ ] delete_sms_template - [ ] delete_user_endpoints - [ ] delete_voice_channel +- [ ] delete_voice_template - [ ] get_adm_channel - [ ] get_apns_channel - [ ] get_apns_sandbox_channel @@ -4987,6 +5081,7 @@ - [ ] get_sms_template - [ ] get_user_endpoints - [ ] get_voice_channel +- [ ] get_voice_template - [ ] list_journeys - [ ] list_tags_for_resource - [ ] list_templates @@ -5018,6 +5113,7 @@ - [ ] update_sms_channel - [ ] update_sms_template - [ ] update_voice_channel +- [ ] update_voice_template ## pinpoint-email 0% implemented @@ -5116,21 +5212,70 @@ ## quicksight 0% implemented +- [ ] cancel_ingestion +- [ ] create_dashboard +- [ ] create_data_set +- [ ] create_data_source - [ ] create_group - [ ] create_group_membership +- [ ] create_iam_policy_assignment +- [ ] create_ingestion +- [ ] create_template +- [ ] create_template_alias +- [ ] delete_dashboard +- [ ] delete_data_set +- [ ] delete_data_source - [ ] delete_group - [ ] delete_group_membership +- [ ] delete_iam_policy_assignment +- [ ] delete_template +- [ ] delete_template_alias - [ ] delete_user - [ ] delete_user_by_principal_id +- [ ] describe_dashboard +- [ ] describe_dashboard_permissions +- [ ] describe_data_set +- [ ] describe_data_set_permissions +- [ ] describe_data_source +- [ ] describe_data_source_permissions - [ ] describe_group +- [ ] describe_iam_policy_assignment +- [ ] describe_ingestion +- [ ] describe_template +- [ ] describe_template_alias +- [ ] describe_template_permissions - [ ] describe_user - [ ] get_dashboard_embed_url +- [ ] list_dashboard_versions +- [ ] list_dashboards +- [ ] list_data_sets +- [ ] list_data_sources - [ ] list_group_memberships - [ ] list_groups +- [ ] list_iam_policy_assignments +- [ ] list_iam_policy_assignments_for_user +- [ ] list_ingestions +- [ ] list_tags_for_resource +- [ ] list_template_aliases +- [ ] list_template_versions +- [ ] list_templates - [ ] list_user_groups - [ ] list_users - [ ] register_user +- [ ] tag_resource +- [ ] untag_resource +- [ ] update_dashboard +- [ ] update_dashboard_permissions +- [ ] update_dashboard_published_version +- [ ] update_data_set +- [ ] update_data_set_permissions +- [ ] update_data_source +- [ ] update_data_source_permissions - [ ] update_group +- [ ] update_iam_policy_assignment +- [ ] update_template +- [ ] update_template_alias +- [ ] update_template_permissions - [ ] update_user ## ram @@ -5786,14 +5931,14 @@ - [ ] select ## secretsmanager -55% implemented +61% implemented - [ ] cancel_rotate_secret - [X] create_secret - [ ] delete_resource_policy - [X] delete_secret - [X] describe_secret - [X] get_random_password -- [ ] get_resource_policy +- [X] get_resource_policy - [X] get_secret_value - [X] list_secret_version_ids - [X] list_secrets @@ -6390,6 +6535,7 @@ - [ ] update_managed_instance_role - [ ] update_ops_item - [ ] update_patch_baseline +- [ ] update_resource_data_sync - [ ] update_service_setting ## sso @@ -6457,6 +6603,7 @@ - [ ] delete_tape - [ ] delete_tape_archive - [ ] delete_volume +- [ ] describe_availability_monitor_test - [ ] describe_bandwidth_rate_limit - [ ] describe_cache - [ ] describe_cached_iscsi_volumes @@ -6494,6 +6641,7 @@ - [ ] set_local_console_password - [ ] set_smb_guest_password - [ ] shutdown_gateway +- [ ] start_availability_monitor_test - [ ] start_gateway - [ ] update_bandwidth_rate_limit - [ ] update_chap_credentials diff --git a/moto/__init__.py b/moto/__init__.py index 767c0ee27..a9f1bb8ba 100644 --- a/moto/__init__.py +++ b/moto/__init__.py @@ -9,6 +9,7 @@ from .batch import mock_batch # noqa from .cloudformation import mock_cloudformation # noqa from .cloudformation import mock_cloudformation_deprecated # noqa from .cloudwatch import mock_cloudwatch, mock_cloudwatch_deprecated # noqa +from .codepipeline import mock_codepipeline # noqa from .cognitoidentity import mock_cognitoidentity # noqa from .cognitoidentity import mock_cognitoidentity_deprecated # noqa from .cognitoidp import mock_cognitoidp, mock_cognitoidp_deprecated # noqa diff --git a/moto/backends.py b/moto/backends.py index 53a5cafc3..9295bc758 100644 --- a/moto/backends.py +++ b/moto/backends.py @@ -8,6 +8,7 @@ from moto.awslambda import lambda_backends from moto.batch import batch_backends from moto.cloudformation import cloudformation_backends from moto.cloudwatch import cloudwatch_backends +from moto.codepipeline import codepipeline_backends from moto.cognitoidentity import cognitoidentity_backends from moto.cognitoidp import cognitoidp_backends from moto.config import config_backends @@ -60,6 +61,7 @@ BACKENDS = { "batch": batch_backends, "cloudformation": cloudformation_backends, "cloudwatch": cloudwatch_backends, + "codepipeline": codepipeline_backends, "cognito-identity": cognitoidentity_backends, "cognito-idp": cognitoidp_backends, "config": config_backends, diff --git a/moto/codepipeline/__init__.py b/moto/codepipeline/__init__.py new file mode 100644 index 000000000..da1f1fa9d --- /dev/null +++ b/moto/codepipeline/__init__.py @@ -0,0 +1,4 @@ +from .models import codepipeline_backends +from ..core.models import base_decorator + +mock_codepipeline = base_decorator(codepipeline_backends) diff --git a/moto/codepipeline/exceptions.py b/moto/codepipeline/exceptions.py new file mode 100644 index 000000000..82bf6192a --- /dev/null +++ b/moto/codepipeline/exceptions.py @@ -0,0 +1,10 @@ +from moto.core.exceptions import JsonRESTError + + +class InvalidStructureException(JsonRESTError): + code = 400 + + def __init__(self, message): + super(InvalidStructureException, self).__init__( + "InvalidStructureException", message + ) diff --git a/moto/codepipeline/models.py b/moto/codepipeline/models.py new file mode 100644 index 000000000..98975c242 --- /dev/null +++ b/moto/codepipeline/models.py @@ -0,0 +1,78 @@ +import json + +from boto3 import Session +from moto.iam.exceptions import IAMNotFoundException + +from moto.iam import iam_backends + +from moto.codepipeline.exceptions import InvalidStructureException +from moto.core import BaseBackend, BaseModel + +DEFAULT_ACCOUNT_ID = "123456789012" + + +class CodePipeline(BaseModel): + def __init__(self, pipeline): + self.pipeline = self._add_default_values(pipeline) + self.tags = {} + + def _add_default_values(self, pipeline): + for stage in pipeline["stages"]: + for action in stage["actions"]: + if "runOrder" not in action: + action["runOrder"] = 1 + if "configuration" not in action: + action["configuration"] = {} + if "outputArtifacts" not in action: + action["outputArtifacts"] = [] + if "inputArtifacts" not in action: + action["inputArtifacts"] = [] + + +class CodePipelineBackend(BaseBackend): + def __init__(self): + self.pipelines = {} + + @property + def iam_backend(self): + return iam_backends["global"] + + def create_pipeline(self, pipeline, tags): + if pipeline["name"] in self.pipelines: + raise InvalidStructureException( + "A pipeline with the name '{0}' already exists in account '{1}'".format( + pipeline["name"], DEFAULT_ACCOUNT_ID + ) + ) + + try: + role = self.iam_backend.get_role_by_arn(pipeline["roleArn"]) + service_principal = json.loads(role.assume_role_policy_document)[ + "Statement" + ][0]["Principal"]["Service"] + if "codepipeline.amazonaws.com" not in service_principal: + raise IAMNotFoundException("") + except IAMNotFoundException: + raise InvalidStructureException( + "CodePipeline is not authorized to perform AssumeRole on role {}".format( + pipeline["roleArn"] + ) + ) + + if len(pipeline["stages"]) < 2: + raise InvalidStructureException( + "Pipeline has only 1 stage(s). There should be a minimum of 2 stages in a pipeline" + ) + + self.pipelines[pipeline["name"]] = CodePipeline(pipeline) + + if tags: + new_tags = {tag["key"]: tag["value"] for tag in tags} + self.pipelines[pipeline["name"]].tags.update(new_tags) + + return pipeline, tags + + +codepipeline_backends = {} +for region in Session().get_available_regions("codepipeline"): + codepipeline_backends[region] = CodePipelineBackend() diff --git a/moto/codepipeline/responses.py b/moto/codepipeline/responses.py new file mode 100644 index 000000000..9bff98bb1 --- /dev/null +++ b/moto/codepipeline/responses.py @@ -0,0 +1,17 @@ +import json + +from moto.core.responses import BaseResponse +from .models import codepipeline_backends + + +class CodePipelineResponse(BaseResponse): + @property + def codepipeline_backend(self): + return codepipeline_backends[self.region] + + def create_pipeline(self): + pipeline, tags = self.codepipeline_backend.create_pipeline( + self._get_param("pipeline"), self._get_param("tags") + ) + + return json.dumps({"pipeline": pipeline, "tags": tags}) diff --git a/moto/codepipeline/urls.py b/moto/codepipeline/urls.py new file mode 100644 index 000000000..7111020a5 --- /dev/null +++ b/moto/codepipeline/urls.py @@ -0,0 +1,6 @@ +from __future__ import unicode_literals +from .responses import CodePipelineResponse + +url_bases = ["https?://codepipeline.(.+).amazonaws.com"] + +url_paths = {"{0}/$": CodePipelineResponse.dispatch} diff --git a/tests/test_codepipeline/test_codepipeline.py b/tests/test_codepipeline/test_codepipeline.py new file mode 100644 index 000000000..f9eb5624c --- /dev/null +++ b/tests/test_codepipeline/test_codepipeline.py @@ -0,0 +1,363 @@ +import json + +import boto3 +import sure # noqa +from botocore.exceptions import ClientError +from nose.tools import assert_raises + +from moto import mock_codepipeline, mock_iam + + +@mock_codepipeline +def test_create_pipeline(): + client = boto3.client("codepipeline", region_name="us-east-1") + + response = client.create_pipeline( + pipeline={ + "name": "test-pipeline", + "roleArn": get_role_arn(), + "artifactStore": { + "type": "S3", + "location": "codepipeline-us-east-1-123456789012", + }, + "stages": [ + { + "name": "Stage-1", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Source", + "owner": "AWS", + "provider": "S3", + "version": "1", + }, + "configuration": { + "S3Bucket": "test-bucket", + "S3ObjectKey": "test-object", + }, + "outputArtifacts": [{"name": "artifact"},], + }, + ], + }, + { + "name": "Stage-2", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Approval", + "owner": "AWS", + "provider": "Manual", + "version": "1", + }, + }, + ], + }, + ], + }, + tags=[{"key": "key", "value": "value"}], + ) + + response["pipeline"].should.equal( + { + "name": "test-pipeline", + "roleArn": "arn:aws:iam::123456789012:role/test-role", + "artifactStore": { + "type": "S3", + "location": "codepipeline-us-east-1-123456789012", + }, + "stages": [ + { + "name": "Stage-1", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Source", + "owner": "AWS", + "provider": "S3", + "version": "1", + }, + "runOrder": 1, + "configuration": { + "S3Bucket": "test-bucket", + "S3ObjectKey": "test-object", + }, + "outputArtifacts": [{"name": "artifact"}], + "inputArtifacts": [], + } + ], + }, + { + "name": "Stage-2", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Approval", + "owner": "AWS", + "provider": "Manual", + "version": "1", + }, + "runOrder": 1, + "configuration": {}, + "outputArtifacts": [], + "inputArtifacts": [], + } + ], + }, + ], + } + ) + response["tags"].should.equal([{"key": "key", "value": "value"}]) + + +@mock_codepipeline +@mock_iam +def test_create_pipeline_errors(): + client = boto3.client("codepipeline", region_name="us-east-1") + client_iam = boto3.client("iam", region_name="us-east-1") + client.create_pipeline( + pipeline={ + "name": "test-pipeline", + "roleArn": get_role_arn(), + "artifactStore": { + "type": "S3", + "location": "codepipeline-us-east-1-123456789012", + }, + "stages": [ + { + "name": "Stage-1", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Source", + "owner": "AWS", + "provider": "S3", + "version": "1", + }, + "configuration": { + "S3Bucket": "test-bucket", + "S3ObjectKey": "test-object", + }, + "outputArtifacts": [{"name": "artifact"},], + }, + ], + }, + { + "name": "Stage-2", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Approval", + "owner": "AWS", + "provider": "Manual", + "version": "1", + }, + }, + ], + }, + ], + } + ) + + with assert_raises(ClientError) as e: + client.create_pipeline( + pipeline={ + "name": "test-pipeline", + "roleArn": get_role_arn(), + "artifactStore": { + "type": "S3", + "location": "codepipeline-us-east-1-123456789012", + }, + "stages": [ + { + "name": "Stage-1", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Source", + "owner": "AWS", + "provider": "S3", + "version": "1", + }, + "configuration": { + "S3Bucket": "test-bucket", + "S3ObjectKey": "test-object", + }, + "outputArtifacts": [{"name": "artifact"},], + }, + ], + }, + { + "name": "Stage-2", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Approval", + "owner": "AWS", + "provider": "Manual", + "version": "1", + }, + }, + ], + }, + ], + } + ) + ex = e.exception + ex.operation_name.should.equal("CreatePipeline") + ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) + ex.response["Error"]["Code"].should.contain("InvalidStructureException") + ex.response["Error"]["Message"].should.equal( + "A pipeline with the name 'test-pipeline' already exists in account '123456789012'" + ) + + with assert_raises(ClientError) as e: + client.create_pipeline( + pipeline={ + "name": "invalid-pipeline", + "roleArn": "arn:aws:iam::123456789012:role/not-existing", + "artifactStore": { + "type": "S3", + "location": "codepipeline-us-east-1-123456789012", + }, + "stages": [ + { + "name": "Stage-1", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Source", + "owner": "AWS", + "provider": "S3", + "version": "1", + }, + "runOrder": 1, + }, + ], + }, + ], + } + ) + ex = e.exception + ex.operation_name.should.equal("CreatePipeline") + ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) + ex.response["Error"]["Code"].should.contain("InvalidStructureException") + ex.response["Error"]["Message"].should.equal( + "CodePipeline is not authorized to perform AssumeRole on role arn:aws:iam::123456789012:role/not-existing" + ) + + wrong_role_arn = client_iam.create_role( + RoleName="wrong-role", + AssumeRolePolicyDocument=json.dumps( + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": {"Service": "s3.amazonaws.com"}, + "Action": "sts:AssumeRole", + } + ], + } + ), + )["Role"]["Arn"] + + with assert_raises(ClientError) as e: + client.create_pipeline( + pipeline={ + "name": "invalid-pipeline", + "roleArn": wrong_role_arn, + "artifactStore": { + "type": "S3", + "location": "codepipeline-us-east-1-123456789012", + }, + "stages": [ + { + "name": "Stage-1", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Source", + "owner": "AWS", + "provider": "S3", + "version": "1", + }, + "runOrder": 1, + }, + ], + }, + ], + } + ) + ex = e.exception + ex.operation_name.should.equal("CreatePipeline") + ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) + ex.response["Error"]["Code"].should.contain("InvalidStructureException") + ex.response["Error"]["Message"].should.equal( + "CodePipeline is not authorized to perform AssumeRole on role arn:aws:iam::123456789012:role/wrong-role" + ) + + with assert_raises(ClientError) as e: + client.create_pipeline( + pipeline={ + "name": "invalid-pipeline", + "roleArn": get_role_arn(), + "artifactStore": { + "type": "S3", + "location": "codepipeline-us-east-1-123456789012", + }, + "stages": [ + { + "name": "Stage-1", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Source", + "owner": "AWS", + "provider": "S3", + "version": "1", + }, + "runOrder": 1, + }, + ], + }, + ], + } + ) + ex = e.exception + ex.operation_name.should.equal("CreatePipeline") + ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) + ex.response["Error"]["Code"].should.contain("InvalidStructureException") + ex.response["Error"]["Message"].should.equal( + "Pipeline has only 1 stage(s). There should be a minimum of 2 stages in a pipeline" + ) + + +@mock_iam +def get_role_arn(): + iam = boto3.client("iam", region_name="us-east-1") + return iam.create_role( + RoleName="test-role", + AssumeRolePolicyDocument=json.dumps( + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": {"Service": "codepipeline.amazonaws.com"}, + "Action": "sts:AssumeRole", + } + ], + } + ), + )["Role"]["Arn"] From c84e465e4c97ebb390ed792cd83a7510a2189fb6 Mon Sep 17 00:00:00 2001 From: gruebel Date: Sun, 15 Dec 2019 16:54:58 +0100 Subject: [PATCH 2/9] Add codepipeline.get_pipeline --- IMPLEMENTATION_COVERAGE.md | 4 +- moto/codepipeline/exceptions.py | 9 ++ moto/codepipeline/models.py | 42 +++++- moto/codepipeline/responses.py | 9 +- tests/test_codepipeline/test_codepipeline.py | 130 +++++++++++++++++++ 5 files changed, 187 insertions(+), 7 deletions(-) diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md index 24009f948..fa9efc21e 100644 --- a/IMPLEMENTATION_COVERAGE.md +++ b/IMPLEMENTATION_COVERAGE.md @@ -1263,7 +1263,7 @@ - [ ] update_deployment_group ## codepipeline -2% implemented +5% implemented - [ ] acknowledge_job - [ ] acknowledge_third_party_job - [ ] create_custom_action_type @@ -1275,7 +1275,7 @@ - [ ] disable_stage_transition - [ ] enable_stage_transition - [ ] get_job_details -- [ ] get_pipeline +- [X] get_pipeline - [ ] get_pipeline_execution - [ ] get_pipeline_state - [ ] get_third_party_job_details diff --git a/moto/codepipeline/exceptions.py b/moto/codepipeline/exceptions.py index 82bf6192a..360647058 100644 --- a/moto/codepipeline/exceptions.py +++ b/moto/codepipeline/exceptions.py @@ -8,3 +8,12 @@ class InvalidStructureException(JsonRESTError): super(InvalidStructureException, self).__init__( "InvalidStructureException", message ) + + +class PipelineNotFoundException(JsonRESTError): + code = 400 + + def __init__(self, message): + super(PipelineNotFoundException, self).__init__( + "PipelineNotFoundException", message + ) diff --git a/moto/codepipeline/models.py b/moto/codepipeline/models.py index 98975c242..4ea05298d 100644 --- a/moto/codepipeline/models.py +++ b/moto/codepipeline/models.py @@ -1,21 +1,41 @@ import json +from datetime import datetime from boto3 import Session +from moto.core.utils import iso_8601_datetime_with_milliseconds + from moto.iam.exceptions import IAMNotFoundException from moto.iam import iam_backends -from moto.codepipeline.exceptions import InvalidStructureException +from moto.codepipeline.exceptions import ( + InvalidStructureException, + PipelineNotFoundException, +) from moto.core import BaseBackend, BaseModel DEFAULT_ACCOUNT_ID = "123456789012" class CodePipeline(BaseModel): - def __init__(self, pipeline): + def __init__(self, region, pipeline): self.pipeline = self._add_default_values(pipeline) self.tags = {} + self._arn = "arn:aws:codepipeline:{0}:{1}:{2}".format( + region, DEFAULT_ACCOUNT_ID, pipeline["name"] + ) + self._created = datetime.utcnow() + self._updated = datetime.utcnow() + + @property + def metadata(self): + return { + "pipelineArn": self._arn, + "created": iso_8601_datetime_with_milliseconds(self._created), + "updated": iso_8601_datetime_with_milliseconds(self._updated), + } + def _add_default_values(self, pipeline): for stage in pipeline["stages"]: for action in stage["actions"]: @@ -28,6 +48,8 @@ class CodePipeline(BaseModel): if "inputArtifacts" not in action: action["inputArtifacts"] = [] + return pipeline + class CodePipelineBackend(BaseBackend): def __init__(self): @@ -37,7 +59,7 @@ class CodePipelineBackend(BaseBackend): def iam_backend(self): return iam_backends["global"] - def create_pipeline(self, pipeline, tags): + def create_pipeline(self, region, pipeline, tags): if pipeline["name"] in self.pipelines: raise InvalidStructureException( "A pipeline with the name '{0}' already exists in account '{1}'".format( @@ -64,7 +86,7 @@ class CodePipelineBackend(BaseBackend): "Pipeline has only 1 stage(s). There should be a minimum of 2 stages in a pipeline" ) - self.pipelines[pipeline["name"]] = CodePipeline(pipeline) + self.pipelines[pipeline["name"]] = CodePipeline(region, pipeline) if tags: new_tags = {tag["key"]: tag["value"] for tag in tags} @@ -72,6 +94,18 @@ class CodePipelineBackend(BaseBackend): return pipeline, tags + def get_pipeline(self, name): + codepipeline = self.pipelines.get(name) + + if not codepipeline: + raise PipelineNotFoundException( + "Account '{0}' does not have a pipeline with name '{1}'".format( + DEFAULT_ACCOUNT_ID, name + ) + ) + + return codepipeline.pipeline, codepipeline.metadata + codepipeline_backends = {} for region in Session().get_available_regions("codepipeline"): diff --git a/moto/codepipeline/responses.py b/moto/codepipeline/responses.py index 9bff98bb1..3d41d60a1 100644 --- a/moto/codepipeline/responses.py +++ b/moto/codepipeline/responses.py @@ -11,7 +11,14 @@ class CodePipelineResponse(BaseResponse): def create_pipeline(self): pipeline, tags = self.codepipeline_backend.create_pipeline( - self._get_param("pipeline"), self._get_param("tags") + self.region, self._get_param("pipeline"), self._get_param("tags") ) return json.dumps({"pipeline": pipeline, "tags": tags}) + + def get_pipeline(self): + pipeline, metadata = self.codepipeline_backend.get_pipeline( + self._get_param("name") + ) + + return json.dumps({"pipeline": pipeline, "metadata": metadata}) diff --git a/tests/test_codepipeline/test_codepipeline.py b/tests/test_codepipeline/test_codepipeline.py index f9eb5624c..59273c5f1 100644 --- a/tests/test_codepipeline/test_codepipeline.py +++ b/tests/test_codepipeline/test_codepipeline.py @@ -1,8 +1,10 @@ import json +from datetime import datetime, timezone import boto3 import sure # noqa from botocore.exceptions import ClientError +from freezegun import freeze_time from nose.tools import assert_raises from moto import mock_codepipeline, mock_iam @@ -343,6 +345,134 @@ def test_create_pipeline_errors(): ) +@freeze_time("2019-01-01 12:00:00") +@mock_codepipeline +def test_get_pipeline(): + client = boto3.client("codepipeline", region_name="us-east-1") + client.create_pipeline( + pipeline={ + "name": "test-pipeline", + "roleArn": get_role_arn(), + "artifactStore": { + "type": "S3", + "location": "codepipeline-us-east-1-123456789012", + }, + "stages": [ + { + "name": "Stage-1", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Source", + "owner": "AWS", + "provider": "S3", + "version": "1", + }, + "configuration": { + "S3Bucket": "test-bucket", + "S3ObjectKey": "test-object", + }, + "outputArtifacts": [{"name": "artifact"},], + }, + ], + }, + { + "name": "Stage-2", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Approval", + "owner": "AWS", + "provider": "Manual", + "version": "1", + }, + }, + ], + }, + ], + }, + tags=[{"key": "key", "value": "value"}], + ) + + response = client.get_pipeline(name="test-pipeline") + + response["pipeline"].should.equal( + { + "name": "test-pipeline", + "roleArn": "arn:aws:iam::123456789012:role/test-role", + "artifactStore": { + "type": "S3", + "location": "codepipeline-us-east-1-123456789012", + }, + "stages": [ + { + "name": "Stage-1", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Source", + "owner": "AWS", + "provider": "S3", + "version": "1", + }, + "runOrder": 1, + "configuration": { + "S3Bucket": "test-bucket", + "S3ObjectKey": "test-object", + }, + "outputArtifacts": [{"name": "artifact"}], + "inputArtifacts": [], + } + ], + }, + { + "name": "Stage-2", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Approval", + "owner": "AWS", + "provider": "Manual", + "version": "1", + }, + "runOrder": 1, + "configuration": {}, + "outputArtifacts": [], + "inputArtifacts": [], + } + ], + }, + ], + } + ) + response["metadata"].should.equal( + { + "pipelineArn": "arn:aws:codepipeline:us-east-1:123456789012:test-pipeline", + "created": datetime.now(timezone.utc), + "updated": datetime.now(timezone.utc), + } + ) + + +@mock_codepipeline +def test_get_pipeline_errors(): + client = boto3.client("codepipeline", region_name="us-east-1") + + with assert_raises(ClientError) as e: + response = client.get_pipeline(name="not-existing") + ex = e.exception + ex.operation_name.should.equal("GetPipeline") + ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) + ex.response["Error"]["Code"].should.contain("PipelineNotFoundException") + ex.response["Error"]["Message"].should.equal( + "Account '123456789012' does not have a pipeline with name 'not-existing'" + ) + + @mock_iam def get_role_arn(): iam = boto3.client("iam", region_name="us-east-1") From b2c44ce50d0d03f7280d706922952b45ed73e602 Mon Sep 17 00:00:00 2001 From: gruebel Date: Sun, 15 Dec 2019 17:28:59 +0100 Subject: [PATCH 3/9] Add codepipeline.update_pipeline --- IMPLEMENTATION_COVERAGE.md | 4 +- moto/codepipeline/exceptions.py | 9 + moto/codepipeline/models.py | 25 +- moto/codepipeline/responses.py | 7 + tests/test_codepipeline/test_codepipeline.py | 227 ++++++++++++++++++- 5 files changed, 267 insertions(+), 5 deletions(-) diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md index fa9efc21e..297e842eb 100644 --- a/IMPLEMENTATION_COVERAGE.md +++ b/IMPLEMENTATION_COVERAGE.md @@ -1263,7 +1263,7 @@ - [ ] update_deployment_group ## codepipeline -5% implemented +8% implemented - [ ] acknowledge_job - [ ] acknowledge_third_party_job - [ ] create_custom_action_type @@ -1299,7 +1299,7 @@ - [ ] start_pipeline_execution - [ ] tag_resource - [ ] untag_resource -- [ ] update_pipeline +- [X] update_pipeline ## codestar 0% implemented diff --git a/moto/codepipeline/exceptions.py b/moto/codepipeline/exceptions.py index 360647058..e455298cd 100644 --- a/moto/codepipeline/exceptions.py +++ b/moto/codepipeline/exceptions.py @@ -17,3 +17,12 @@ class PipelineNotFoundException(JsonRESTError): super(PipelineNotFoundException, self).__init__( "PipelineNotFoundException", message ) + + +class ResourceNotFoundException(JsonRESTError): + code = 400 + + def __init__(self, message): + super(ResourceNotFoundException, self).__init__( + "ResourceNotFoundException", message + ) diff --git a/moto/codepipeline/models.py b/moto/codepipeline/models.py index 4ea05298d..de89f21f3 100644 --- a/moto/codepipeline/models.py +++ b/moto/codepipeline/models.py @@ -11,6 +11,7 @@ from moto.iam import iam_backends from moto.codepipeline.exceptions import ( InvalidStructureException, PipelineNotFoundException, + ResourceNotFoundException, ) from moto.core import BaseBackend, BaseModel @@ -19,7 +20,10 @@ DEFAULT_ACCOUNT_ID = "123456789012" class CodePipeline(BaseModel): def __init__(self, region, pipeline): - self.pipeline = self._add_default_values(pipeline) + # the version number for a new pipeline is always 1 + pipeline["version"] = 1 + + self.pipeline = self.add_default_values(pipeline) self.tags = {} self._arn = "arn:aws:codepipeline:{0}:{1}:{2}".format( @@ -36,7 +40,7 @@ class CodePipeline(BaseModel): "updated": iso_8601_datetime_with_milliseconds(self._updated), } - def _add_default_values(self, pipeline): + def add_default_values(self, pipeline): for stage in pipeline["stages"]: for action in stage["actions"]: if "runOrder" not in action: @@ -106,6 +110,23 @@ class CodePipelineBackend(BaseBackend): return codepipeline.pipeline, codepipeline.metadata + def update_pipeline(self, pipeline): + codepipeline = self.pipelines.get(pipeline["name"]) + + if not codepipeline: + raise ResourceNotFoundException( + "The account with id '{0}' does not include a pipeline with the name '{1}'".format( + DEFAULT_ACCOUNT_ID, pipeline["name"] + ) + ) + + # version number is auto incremented + pipeline["version"] = codepipeline.pipeline["version"] + 1 + codepipeline._updated = datetime.utcnow() + codepipeline.pipeline = codepipeline.add_default_values(pipeline) + + return codepipeline.pipeline + codepipeline_backends = {} for region in Session().get_available_regions("codepipeline"): diff --git a/moto/codepipeline/responses.py b/moto/codepipeline/responses.py index 3d41d60a1..c1aa4dc76 100644 --- a/moto/codepipeline/responses.py +++ b/moto/codepipeline/responses.py @@ -22,3 +22,10 @@ class CodePipelineResponse(BaseResponse): ) return json.dumps({"pipeline": pipeline, "metadata": metadata}) + + def update_pipeline(self): + pipeline = self.codepipeline_backend.update_pipeline( + self._get_param("pipeline") + ) + + return json.dumps({"pipeline": pipeline}) diff --git a/tests/test_codepipeline/test_codepipeline.py b/tests/test_codepipeline/test_codepipeline.py index 59273c5f1..f4d7e1ccb 100644 --- a/tests/test_codepipeline/test_codepipeline.py +++ b/tests/test_codepipeline/test_codepipeline.py @@ -110,6 +110,7 @@ def test_create_pipeline(): ], }, ], + "version": 1, } ) response["tags"].should.equal([{"key": "key", "value": "value"}]) @@ -447,6 +448,7 @@ def test_get_pipeline(): ], }, ], + "version": 1, } ) response["metadata"].should.equal( @@ -463,7 +465,7 @@ def test_get_pipeline_errors(): client = boto3.client("codepipeline", region_name="us-east-1") with assert_raises(ClientError) as e: - response = client.get_pipeline(name="not-existing") + client.get_pipeline(name="not-existing") ex = e.exception ex.operation_name.should.equal("GetPipeline") ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) @@ -473,6 +475,229 @@ def test_get_pipeline_errors(): ) +@mock_codepipeline +def test_update_pipeline(): + client = boto3.client("codepipeline", region_name="us-east-1") + role_arn = get_role_arn() + with freeze_time("2019-01-01 12:00:00"): + created_time = datetime.now(timezone.utc) + client.create_pipeline( + pipeline={ + "name": "test-pipeline", + "roleArn": role_arn, + "artifactStore": { + "type": "S3", + "location": "codepipeline-us-east-1-123456789012", + }, + "stages": [ + { + "name": "Stage-1", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Source", + "owner": "AWS", + "provider": "S3", + "version": "1", + }, + "configuration": { + "S3Bucket": "test-bucket", + "S3ObjectKey": "test-object", + }, + "outputArtifacts": [{"name": "artifact"},], + }, + ], + }, + { + "name": "Stage-2", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Approval", + "owner": "AWS", + "provider": "Manual", + "version": "1", + }, + }, + ], + }, + ], + }, + tags=[{"key": "key", "value": "value"}], + ) + + with freeze_time("2019-01-02 12:00:00"): + updated_time = datetime.now(timezone.utc) + response = client.update_pipeline( + pipeline={ + "name": "test-pipeline", + "roleArn": role_arn, + "artifactStore": { + "type": "S3", + "location": "codepipeline-us-east-1-123456789012", + }, + "stages": [ + { + "name": "Stage-1", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Source", + "owner": "AWS", + "provider": "S3", + "version": "1", + }, + "configuration": { + "S3Bucket": "different-bucket", + "S3ObjectKey": "test-object", + }, + "outputArtifacts": [{"name": "artifact"},], + }, + ], + }, + { + "name": "Stage-2", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Approval", + "owner": "AWS", + "provider": "Manual", + "version": "1", + }, + }, + ], + }, + ], + } + ) + + response["pipeline"].should.equal( + { + "name": "test-pipeline", + "roleArn": "arn:aws:iam::123456789012:role/test-role", + "artifactStore": { + "type": "S3", + "location": "codepipeline-us-east-1-123456789012", + }, + "stages": [ + { + "name": "Stage-1", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Source", + "owner": "AWS", + "provider": "S3", + "version": "1", + }, + "runOrder": 1, + "configuration": { + "S3Bucket": "different-bucket", + "S3ObjectKey": "test-object", + }, + "outputArtifacts": [{"name": "artifact"}], + "inputArtifacts": [], + } + ], + }, + { + "name": "Stage-2", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Approval", + "owner": "AWS", + "provider": "Manual", + "version": "1", + }, + "runOrder": 1, + "configuration": {}, + "outputArtifacts": [], + "inputArtifacts": [], + } + ], + }, + ], + "version": 2, + } + ) + + response = client.get_pipeline(name="test-pipeline") + response["metadata"].should.equal( + { + "pipelineArn": "arn:aws:codepipeline:us-east-1:123456789012:test-pipeline", + "created": created_time, + "updated": updated_time, + } + ) + + +@mock_codepipeline +def test_update_pipeline_errors(): + client = boto3.client("codepipeline", region_name="us-east-1") + + with assert_raises(ClientError) as e: + client.update_pipeline( + pipeline={ + "name": "not-existing", + "roleArn": get_role_arn(), + "artifactStore": { + "type": "S3", + "location": "codepipeline-us-east-1-123456789012", + }, + "stages": [ + { + "name": "Stage-1", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Source", + "owner": "AWS", + "provider": "S3", + "version": "1", + }, + "configuration": { + "S3Bucket": "test-bucket", + "S3ObjectKey": "test-object", + }, + "outputArtifacts": [{"name": "artifact"},], + }, + ], + }, + { + "name": "Stage-2", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Approval", + "owner": "AWS", + "provider": "Manual", + "version": "1", + }, + }, + ], + }, + ], + } + ) + ex = e.exception + ex.operation_name.should.equal("UpdatePipeline") + ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) + ex.response["Error"]["Code"].should.contain("ResourceNotFoundException") + ex.response["Error"]["Message"].should.equal( + "The account with id '123456789012' does not include a pipeline with the name 'not-existing'" + ) + + @mock_iam def get_role_arn(): iam = boto3.client("iam", region_name="us-east-1") From 9871eda3c944be6986ecf8712f2f977c9c477c7a Mon Sep 17 00:00:00 2001 From: gruebel Date: Sun, 15 Dec 2019 17:44:54 +0100 Subject: [PATCH 4/9] Add codepipeline.list_pipelines --- IMPLEMENTATION_COVERAGE.md | 4 +- moto/codepipeline/models.py | 15 +++ moto/codepipeline/responses.py | 5 + tests/test_codepipeline/test_codepipeline.py | 115 +++++++++++++++++++ 4 files changed, 137 insertions(+), 2 deletions(-) diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md index 297e842eb..b4e0b1ee6 100644 --- a/IMPLEMENTATION_COVERAGE.md +++ b/IMPLEMENTATION_COVERAGE.md @@ -1263,7 +1263,7 @@ - [ ] update_deployment_group ## codepipeline -8% implemented +11% implemented - [ ] acknowledge_job - [ ] acknowledge_third_party_job - [ ] create_custom_action_type @@ -1282,7 +1282,7 @@ - [ ] list_action_executions - [ ] list_action_types - [ ] list_pipeline_executions -- [ ] list_pipelines +- [X] list_pipelines - [ ] list_tags_for_resource - [ ] list_webhooks - [ ] poll_for_jobs diff --git a/moto/codepipeline/models.py b/moto/codepipeline/models.py index de89f21f3..758c41555 100644 --- a/moto/codepipeline/models.py +++ b/moto/codepipeline/models.py @@ -127,6 +127,21 @@ class CodePipelineBackend(BaseBackend): return codepipeline.pipeline + def list_pipelines(self): + pipelines = [] + + for name, codepipeline in self.pipelines.items(): + pipelines.append( + { + "name": name, + "version": codepipeline.pipeline["version"], + "created": codepipeline.metadata["created"], + "updated": codepipeline.metadata["updated"], + } + ) + + return sorted(pipelines, key=lambda i: i["name"]) + codepipeline_backends = {} for region in Session().get_available_regions("codepipeline"): diff --git a/moto/codepipeline/responses.py b/moto/codepipeline/responses.py index c1aa4dc76..6611f9257 100644 --- a/moto/codepipeline/responses.py +++ b/moto/codepipeline/responses.py @@ -29,3 +29,8 @@ class CodePipelineResponse(BaseResponse): ) return json.dumps({"pipeline": pipeline}) + + def list_pipelines(self): + pipelines = self.codepipeline_backend.list_pipelines() + + return json.dumps({"pipelines": pipelines}) diff --git a/tests/test_codepipeline/test_codepipeline.py b/tests/test_codepipeline/test_codepipeline.py index f4d7e1ccb..12b3b7975 100644 --- a/tests/test_codepipeline/test_codepipeline.py +++ b/tests/test_codepipeline/test_codepipeline.py @@ -698,6 +698,121 @@ def test_update_pipeline_errors(): ) +@freeze_time("2019-01-01 12:00:00") +@mock_codepipeline +def test_list_pipelines(): + client = boto3.client("codepipeline", region_name="us-east-1") + client.create_pipeline( + pipeline={ + "name": "test-pipeline-1", + "roleArn": get_role_arn(), + "artifactStore": { + "type": "S3", + "location": "codepipeline-us-east-1-123456789012", + }, + "stages": [ + { + "name": "Stage-1", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Source", + "owner": "AWS", + "provider": "S3", + "version": "1", + }, + "configuration": { + "S3Bucket": "test-bucket", + "S3ObjectKey": "test-object", + }, + "outputArtifacts": [{"name": "artifact"},], + }, + ], + }, + { + "name": "Stage-2", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Approval", + "owner": "AWS", + "provider": "Manual", + "version": "1", + }, + }, + ], + }, + ], + }, + ) + client.create_pipeline( + pipeline={ + "name": "test-pipeline-2", + "roleArn": get_role_arn(), + "artifactStore": { + "type": "S3", + "location": "codepipeline-us-east-1-123456789012", + }, + "stages": [ + { + "name": "Stage-1", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Source", + "owner": "AWS", + "provider": "S3", + "version": "1", + }, + "configuration": { + "S3Bucket": "test-bucket", + "S3ObjectKey": "test-object", + }, + "outputArtifacts": [{"name": "artifact"},], + }, + ], + }, + { + "name": "Stage-2", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Approval", + "owner": "AWS", + "provider": "Manual", + "version": "1", + }, + }, + ], + }, + ], + }, + ) + + response = client.list_pipelines() + + response["pipelines"].should.equal( + [ + { + "name": "test-pipeline-1", + "version": 1, + "created": datetime.now(timezone.utc), + "updated": datetime.now(timezone.utc), + }, + { + "name": "test-pipeline-2", + "version": 1, + "created": datetime.now(timezone.utc), + "updated": datetime.now(timezone.utc), + }, + ] + ) + + @mock_iam def get_role_arn(): iam = boto3.client("iam", region_name="us-east-1") From 8e03b1d525b73cf6bd86815cba20bca30ece44d7 Mon Sep 17 00:00:00 2001 From: gruebel Date: Sun, 15 Dec 2019 17:58:38 +0100 Subject: [PATCH 5/9] Add codepipeline.delete_pipeline --- IMPLEMENTATION_COVERAGE.md | 620 ++++++++++++++++++- moto/codepipeline/models.py | 3 + moto/codepipeline/responses.py | 5 + tests/test_codepipeline/test_codepipeline.py | 68 ++ 4 files changed, 683 insertions(+), 13 deletions(-) diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md index b4e0b1ee6..5e6ef1c9e 100644 --- a/IMPLEMENTATION_COVERAGE.md +++ b/IMPLEMENTATION_COVERAGE.md @@ -1,4 +1,25 @@ +## accessanalyzer +0% implemented +- [ ] create_analyzer +- [ ] create_archive_rule +- [ ] delete_analyzer +- [ ] delete_archive_rule +- [ ] get_analyzed_resource +- [ ] get_analyzer +- [ ] get_archive_rule +- [ ] get_finding +- [ ] list_analyzed_resources +- [ ] list_analyzers +- [ ] list_archive_rules +- [ ] list_findings +- [ ] list_tags_for_resource +- [ ] start_resource_scan +- [ ] tag_resource +- [ ] untag_resource +- [ ] update_archive_rule +- [ ] update_findings + ## acm 38% implemented - [X] add_tags_to_certificate @@ -319,6 +340,7 @@ - [ ] delete_api - [ ] delete_api_mapping - [ ] delete_authorizer +- [ ] delete_cors_configuration - [ ] delete_deployment - [ ] delete_domain_name - [ ] delete_integration @@ -326,6 +348,7 @@ - [ ] delete_model - [ ] delete_route - [ ] delete_route_response +- [ ] delete_route_settings - [ ] delete_stage - [ ] get_api - [ ] get_api_mapping @@ -351,6 +374,8 @@ - [ ] get_stage - [ ] get_stages - [ ] get_tags +- [ ] import_api +- [ ] reimport_api - [ ] tag_resource - [ ] untag_resource - [ ] update_api @@ -365,6 +390,38 @@ - [ ] update_route_response - [ ] update_stage +## appconfig +0% implemented +- [ ] create_application +- [ ] create_configuration_profile +- [ ] create_deployment_strategy +- [ ] create_environment +- [ ] delete_application +- [ ] delete_configuration_profile +- [ ] delete_deployment_strategy +- [ ] delete_environment +- [ ] get_application +- [ ] get_configuration +- [ ] get_configuration_profile +- [ ] get_deployment +- [ ] get_deployment_strategy +- [ ] get_environment +- [ ] list_applications +- [ ] list_configuration_profiles +- [ ] list_deployment_strategies +- [ ] list_deployments +- [ ] list_environments +- [ ] list_tags_for_resource +- [ ] start_deployment +- [ ] stop_deployment +- [ ] tag_resource +- [ ] untag_resource +- [ ] update_application +- [ ] update_configuration_profile +- [ ] update_deployment_strategy +- [ ] update_environment +- [ ] validate_configuration + ## application-autoscaling 0% implemented - [ ] delete_scaling_policy @@ -382,21 +439,30 @@ 0% implemented - [ ] create_application - [ ] create_component +- [ ] create_log_pattern - [ ] delete_application - [ ] delete_component +- [ ] delete_log_pattern - [ ] describe_application - [ ] describe_component - [ ] describe_component_configuration - [ ] describe_component_configuration_recommendation +- [ ] describe_log_pattern - [ ] describe_observation - [ ] describe_problem - [ ] describe_problem_observations - [ ] list_applications - [ ] list_components +- [ ] list_log_pattern_sets +- [ ] list_log_patterns - [ ] list_problems +- [ ] list_tags_for_resource +- [ ] tag_resource +- [ ] untag_resource - [ ] update_application - [ ] update_component - [ ] update_component_configuration +- [ ] update_log_pattern ## appmesh 0% implemented @@ -695,6 +761,9 @@ ## ce 0% implemented +- [ ] create_cost_category_definition +- [ ] delete_cost_category_definition +- [ ] describe_cost_category_definition - [ ] get_cost_and_usage - [ ] get_cost_and_usage_with_resources - [ ] get_cost_forecast @@ -709,6 +778,8 @@ - [ ] get_savings_plans_utilization_details - [ ] get_tags - [ ] get_usage_forecast +- [ ] list_cost_category_definitions +- [ ] update_cost_category_definition ## chime 0% implemented @@ -1088,17 +1159,22 @@ - [ ] update_trail ## cloudwatch -43% implemented +34% implemented - [X] delete_alarms - [ ] delete_anomaly_detector - [X] delete_dashboards +- [ ] delete_insight_rules - [ ] describe_alarm_history - [ ] describe_alarms - [ ] describe_alarms_for_metric - [ ] describe_anomaly_detectors +- [ ] describe_insight_rules - [ ] disable_alarm_actions +- [ ] disable_insight_rules - [ ] enable_alarm_actions +- [ ] enable_insight_rules - [X] get_dashboard +- [ ] get_insight_rule_report - [ ] get_metric_data - [X] get_metric_statistics - [ ] get_metric_widget_image @@ -1107,6 +1183,7 @@ - [ ] list_tags_for_resource - [ ] put_anomaly_detector - [X] put_dashboard +- [ ] put_insight_rule - [X] put_metric_alarm - [X] put_metric_data - [X] set_alarm_state @@ -1118,21 +1195,36 @@ - [ ] batch_delete_builds - [ ] batch_get_builds - [ ] batch_get_projects +- [ ] batch_get_report_groups +- [ ] batch_get_reports - [ ] create_project +- [ ] create_report_group - [ ] create_webhook - [ ] delete_project +- [ ] delete_report +- [ ] delete_report_group +- [ ] delete_resource_policy - [ ] delete_source_credentials - [ ] delete_webhook +- [ ] describe_test_cases +- [ ] get_resource_policy - [ ] import_source_credentials - [ ] invalidate_project_cache - [ ] list_builds - [ ] list_builds_for_project - [ ] list_curated_environment_images - [ ] list_projects +- [ ] list_report_groups +- [ ] list_reports +- [ ] list_reports_for_report_group +- [ ] list_shared_projects +- [ ] list_shared_report_groups - [ ] list_source_credentials +- [ ] put_resource_policy - [ ] start_build - [ ] stop_build - [ ] update_project +- [ ] update_report_group - [ ] update_webhook ## codecommit @@ -1262,14 +1354,33 @@ - [ ] update_application - [ ] update_deployment_group +## codeguru-reviewer +0% implemented +- [ ] associate_repository +- [ ] describe_repository_association +- [ ] disassociate_repository +- [ ] list_repository_associations + +## codeguruprofiler +0% implemented +- [ ] configure_agent +- [ ] create_profiling_group +- [ ] delete_profiling_group +- [ ] describe_profiling_group +- [ ] get_profile +- [ ] list_profile_times +- [ ] list_profiling_groups +- [ ] post_agent_profile +- [ ] update_profiling_group + ## codepipeline -11% implemented +13% implemented - [ ] acknowledge_job - [ ] acknowledge_third_party_job - [ ] create_custom_action_type - [X] create_pipeline - [ ] delete_custom_action_type -- [ ] delete_pipeline +- [X] delete_pipeline - [ ] delete_webhook - [ ] deregister_webhook_with_third_party - [ ] disable_stage_transition @@ -1492,13 +1603,17 @@ - [ ] batch_detect_key_phrases - [ ] batch_detect_sentiment - [ ] batch_detect_syntax +- [ ] classify_document - [ ] create_document_classifier +- [ ] create_endpoint - [ ] create_entity_recognizer - [ ] delete_document_classifier +- [ ] delete_endpoint - [ ] delete_entity_recognizer - [ ] describe_document_classification_job - [ ] describe_document_classifier - [ ] describe_dominant_language_detection_job +- [ ] describe_endpoint - [ ] describe_entities_detection_job - [ ] describe_entity_recognizer - [ ] describe_key_phrases_detection_job @@ -1512,6 +1627,7 @@ - [ ] list_document_classification_jobs - [ ] list_document_classifiers - [ ] list_dominant_language_detection_jobs +- [ ] list_endpoints - [ ] list_entities_detection_jobs - [ ] list_entity_recognizers - [ ] list_key_phrases_detection_jobs @@ -1532,6 +1648,7 @@ - [ ] stop_training_entity_recognizer - [ ] tag_resource - [ ] untag_resource +- [ ] update_endpoint ## comprehendmedical 0% implemented @@ -1547,6 +1664,15 @@ - [ ] stop_entities_detection_v2_job - [ ] stop_phi_detection_job +## compute-optimizer +0% implemented +- [ ] get_auto_scaling_group_recommendations +- [ ] get_ec2_instance_recommendations +- [ ] get_ec2_recommendation_projected_metrics +- [ ] get_enrollment_status +- [ ] get_recommendation_summaries +- [ ] update_enrollment_status + ## config 25% implemented - [X] batch_get_aggregate_resource_config @@ -1776,6 +1902,20 @@ - [ ] update_parameter_group - [ ] update_subnet_group +## detective +0% implemented +- [ ] accept_invitation +- [ ] create_graph +- [ ] create_members +- [ ] delete_graph +- [ ] delete_members +- [ ] disassociate_membership +- [ ] get_members +- [ ] list_graphs +- [ ] list_invitations +- [ ] list_members +- [ ] reject_invitation + ## devicefarm 0% implemented - [ ] create_device_pool @@ -2056,24 +2196,31 @@ - [ ] delete_log_subscription - [ ] delete_snapshot - [ ] delete_trust +- [ ] deregister_certificate - [ ] deregister_event_topic +- [ ] describe_certificate - [ ] describe_conditional_forwarders - [ ] describe_directories - [ ] describe_domain_controllers - [ ] describe_event_topics +- [ ] describe_ldaps_settings - [ ] describe_shared_directories - [ ] describe_snapshots - [ ] describe_trusts +- [ ] disable_ldaps - [ ] disable_radius - [ ] disable_sso +- [ ] enable_ldaps - [ ] enable_radius - [ ] enable_sso - [ ] get_directory_limits - [ ] get_snapshot_limits +- [ ] list_certificates - [ ] list_ip_routes - [ ] list_log_subscriptions - [ ] list_schema_extensions - [ ] list_tags_for_resource +- [ ] register_certificate - [ ] register_event_topic - [ ] reject_shared_directory - [ ] remove_ip_routes @@ -2090,7 +2237,7 @@ - [ ] verify_trust ## dynamodb -18% implemented +17% implemented - [ ] batch_get_item - [ ] batch_write_item - [ ] create_backup @@ -2101,6 +2248,7 @@ - [X] delete_table - [ ] describe_backup - [ ] describe_continuous_backups +- [ ] describe_contributor_insights - [ ] describe_endpoints - [ ] describe_global_table - [ ] describe_global_table_settings @@ -2110,6 +2258,7 @@ - [ ] describe_time_to_live - [X] get_item - [ ] list_backups +- [ ] list_contributor_insights - [ ] list_global_tables - [ ] list_tables - [ ] list_tags_of_resource @@ -2123,6 +2272,7 @@ - [ ] transact_write_items - [ ] untag_resource - [ ] update_continuous_backups +- [ ] update_contributor_insights - [ ] update_global_table - [ ] update_global_table_settings - [ ] update_item @@ -2137,9 +2287,16 @@ - [X] get_shard_iterator - [X] list_streams +## ebs +0% implemented +- [ ] get_snapshot_block +- [ ] list_changed_blocks +- [ ] list_snapshot_blocks + ## ec2 -28% implemented +26% implemented - [ ] accept_reserved_instances_exchange_quote +- [ ] accept_transit_gateway_peering_attachment - [ ] accept_transit_gateway_vpc_attachment - [ ] accept_vpc_endpoint_connections - [X] accept_vpc_peering_connection @@ -2155,6 +2312,7 @@ - [ ] associate_iam_instance_profile - [X] associate_route_table - [ ] associate_subnet_cidr_block +- [ ] associate_transit_gateway_multicast_domain - [ ] associate_transit_gateway_route_table - [X] associate_vpc_cidr_block - [ ] attach_classic_link_vpc @@ -2195,6 +2353,8 @@ - [X] create_key_pair - [X] create_launch_template - [ ] create_launch_template_version +- [ ] create_local_gateway_route +- [ ] create_local_gateway_route_table_vpc_association - [X] create_nat_gateway - [X] create_network_acl - [X] create_network_acl_entry @@ -2215,6 +2375,8 @@ - [ ] create_traffic_mirror_session - [ ] create_traffic_mirror_target - [ ] create_transit_gateway +- [ ] create_transit_gateway_multicast_domain +- [ ] create_transit_gateway_peering_attachment - [ ] create_transit_gateway_route - [ ] create_transit_gateway_route_table - [ ] create_transit_gateway_vpc_attachment @@ -2239,6 +2401,8 @@ - [X] delete_key_pair - [ ] delete_launch_template - [ ] delete_launch_template_versions +- [ ] delete_local_gateway_route +- [ ] delete_local_gateway_route_table_vpc_association - [X] delete_nat_gateway - [X] delete_network_acl - [X] delete_network_acl_entry @@ -2258,6 +2422,8 @@ - [ ] delete_traffic_mirror_session - [ ] delete_traffic_mirror_target - [ ] delete_transit_gateway +- [ ] delete_transit_gateway_multicast_domain +- [ ] delete_transit_gateway_peering_attachment - [ ] delete_transit_gateway_route - [ ] delete_transit_gateway_route_table - [ ] delete_transit_gateway_vpc_attachment @@ -2272,6 +2438,8 @@ - [X] delete_vpn_gateway - [ ] deprovision_byoip_cidr - [X] deregister_image +- [ ] deregister_transit_gateway_multicast_group_members +- [ ] deregister_transit_gateway_multicast_group_sources - [ ] describe_account_attributes - [X] describe_addresses - [ ] describe_aggregate_id_format @@ -2285,6 +2453,7 @@ - [ ] describe_client_vpn_endpoints - [ ] describe_client_vpn_routes - [ ] describe_client_vpn_target_networks +- [ ] describe_coip_pools - [ ] describe_conversion_tasks - [ ] describe_customer_gateways - [X] describe_dhcp_options @@ -2312,11 +2481,19 @@ - [X] describe_instance_attribute - [ ] describe_instance_credit_specifications - [ ] describe_instance_status +- [ ] describe_instance_type_offerings +- [ ] describe_instance_types - [ ] describe_instances - [X] describe_internet_gateways - [X] describe_key_pairs - [ ] describe_launch_template_versions - [ ] describe_launch_templates +- [ ] describe_local_gateway_route_table_virtual_interface_group_associations +- [ ] describe_local_gateway_route_table_vpc_associations +- [ ] describe_local_gateway_route_tables +- [ ] describe_local_gateway_virtual_interface_groups +- [ ] describe_local_gateway_virtual_interfaces +- [ ] describe_local_gateways - [ ] describe_moving_addresses - [ ] describe_nat_gateways - [ ] describe_network_acls @@ -2352,6 +2529,8 @@ - [ ] describe_traffic_mirror_sessions - [ ] describe_traffic_mirror_targets - [ ] describe_transit_gateway_attachments +- [ ] describe_transit_gateway_multicast_domains +- [ ] describe_transit_gateway_peering_attachments - [ ] describe_transit_gateway_route_tables - [ ] describe_transit_gateway_vpc_attachments - [ ] describe_transit_gateways @@ -2388,6 +2567,7 @@ - [ ] disassociate_iam_instance_profile - [X] disassociate_route_table - [ ] disassociate_subnet_cidr_block +- [ ] disassociate_transit_gateway_multicast_domain - [ ] disassociate_transit_gateway_route_table - [X] disassociate_vpc_cidr_block - [ ] enable_ebs_encryption_by_default @@ -2402,8 +2582,10 @@ - [ ] export_image - [ ] export_transit_gateway_routes - [ ] get_capacity_reservation_usage +- [ ] get_coip_pool_usage - [ ] get_console_output - [ ] get_console_screenshot +- [ ] get_default_credit_specification - [ ] get_ebs_default_kms_key_id - [ ] get_ebs_encryption_by_default - [ ] get_host_reservation_purchase_preview @@ -2411,6 +2593,7 @@ - [ ] get_password_data - [ ] get_reserved_instances_exchange_quote - [ ] get_transit_gateway_attachment_propagations +- [ ] get_transit_gateway_multicast_domain_associations - [ ] get_transit_gateway_route_table_associations - [ ] get_transit_gateway_route_table_propagations - [ ] import_client_vpn_client_certificate_revocation_list @@ -2421,6 +2604,7 @@ - [ ] import_volume - [ ] modify_capacity_reservation - [ ] modify_client_vpn_endpoint +- [ ] modify_default_credit_specification - [ ] modify_ebs_default_kms_key_id - [ ] modify_fleet - [ ] modify_fpga_image_attribute @@ -2464,6 +2648,9 @@ - [ ] purchase_scheduled_instances - [X] reboot_instances - [ ] register_image +- [ ] register_transit_gateway_multicast_group_members +- [ ] register_transit_gateway_multicast_group_sources +- [ ] reject_transit_gateway_peering_attachment - [ ] reject_transit_gateway_vpc_attachment - [ ] reject_vpc_endpoint_connections - [X] reject_vpc_peering_connection @@ -2490,6 +2677,8 @@ - [X] revoke_security_group_ingress - [ ] run_instances - [ ] run_scheduled_instances +- [ ] search_local_gateway_routes +- [ ] search_transit_gateway_multicast_groups - [ ] search_transit_gateway_routes - [ ] send_diagnostic_interrupt - [X] start_instances @@ -2540,7 +2729,8 @@ - [ ] upload_layer_part ## ecs -66% implemented +62% implemented +- [ ] create_capacity_provider - [X] create_cluster - [X] create_service - [ ] create_task_set @@ -2551,6 +2741,7 @@ - [ ] delete_task_set - [X] deregister_container_instance - [X] deregister_task_definition +- [ ] describe_capacity_providers - [X] describe_clusters - [X] describe_container_instances - [X] describe_services @@ -2570,6 +2761,7 @@ - [ ] put_account_setting - [ ] put_account_setting_default - [X] put_attributes +- [ ] put_cluster_capacity_providers - [X] register_container_instance - [X] register_task_definition - [X] run_task @@ -2607,13 +2799,17 @@ ## eks 0% implemented - [ ] create_cluster +- [ ] create_fargate_profile - [ ] create_nodegroup - [ ] delete_cluster +- [ ] delete_fargate_profile - [ ] delete_nodegroup - [ ] describe_cluster +- [ ] describe_fargate_profile - [ ] describe_nodegroup - [ ] describe_update - [ ] list_clusters +- [ ] list_fargate_profiles - [ ] list_nodegroups - [ ] list_tags_for_resource - [ ] list_updates @@ -2624,6 +2820,12 @@ - [ ] update_nodegroup_config - [ ] update_nodegroup_version +## elastic-inference +0% implemented +- [ ] list_tags_for_resource +- [ ] tag_resource +- [ ] untag_resource + ## elasticache 0% implemented - [ ] add_tags_to_resource @@ -2812,7 +3014,7 @@ - [X] set_subnets ## emr -51% implemented +50% implemented - [ ] add_instance_fleet - [X] add_instance_groups - [X] add_job_flow_steps @@ -2832,6 +3034,7 @@ - [ ] list_instances - [ ] list_security_configurations - [X] list_steps +- [ ] modify_cluster - [ ] modify_instance_fleet - [X] modify_instance_groups - [ ] put_auto_scaling_policy @@ -2968,6 +3171,39 @@ 0% implemented - [ ] query_forecast +## frauddetector +0% implemented +- [ ] batch_create_variable +- [ ] batch_get_variable +- [ ] create_detector_version +- [ ] create_model_version +- [ ] create_rule +- [ ] create_variable +- [ ] delete_detector_version +- [ ] delete_event +- [ ] describe_detector +- [ ] describe_model_versions +- [ ] get_detector_version +- [ ] get_detectors +- [ ] get_external_models +- [ ] get_model_version +- [ ] get_models +- [ ] get_outcomes +- [ ] get_prediction +- [ ] get_rules +- [ ] get_variables +- [ ] put_detector +- [ ] put_external_model +- [ ] put_model +- [ ] put_outcome +- [ ] update_detector_version +- [ ] update_detector_version_metadata +- [ ] update_detector_version_status +- [ ] update_model_version +- [ ] update_rule_metadata +- [ ] update_rule_version +- [ ] update_variable + ## fsx 0% implemented - [ ] create_backup @@ -3566,6 +3802,51 @@ - [X] upload_signing_certificate - [X] upload_ssh_public_key +## imagebuilder +0% implemented +- [ ] cancel_image_creation +- [ ] create_component +- [ ] create_distribution_configuration +- [ ] create_image +- [ ] create_image_pipeline +- [ ] create_image_recipe +- [ ] create_infrastructure_configuration +- [ ] delete_component +- [ ] delete_distribution_configuration +- [ ] delete_image +- [ ] delete_image_pipeline +- [ ] delete_image_recipe +- [ ] delete_infrastructure_configuration +- [ ] get_component +- [ ] get_component_policy +- [ ] get_distribution_configuration +- [ ] get_image +- [ ] get_image_pipeline +- [ ] get_image_policy +- [ ] get_image_recipe +- [ ] get_image_recipe_policy +- [ ] get_infrastructure_configuration +- [ ] import_component +- [ ] list_component_build_versions +- [ ] list_components +- [ ] list_distribution_configurations +- [ ] list_image_build_versions +- [ ] list_image_pipeline_images +- [ ] list_image_pipelines +- [ ] list_image_recipes +- [ ] list_images +- [ ] list_infrastructure_configurations +- [ ] list_tags_for_resource +- [ ] put_component_policy +- [ ] put_image_policy +- [ ] put_image_recipe_policy +- [ ] start_image_pipeline_execution +- [ ] tag_resource +- [ ] untag_resource +- [ ] update_distribution_configuration +- [ ] update_image_pipeline +- [ ] update_infrastructure_configuration + ## importexport 0% implemented - [ ] cancel_job @@ -3616,7 +3897,7 @@ - [ ] update_assessment_target ## iot -22% implemented +20% implemented - [ ] accept_certificate_transfer - [ ] add_thing_to_billing_group - [X] add_thing_to_thing_group @@ -3635,6 +3916,7 @@ - [ ] create_authorizer - [ ] create_billing_group - [ ] create_certificate_from_csr +- [ ] create_domain_configuration - [ ] create_dynamic_thing_group - [X] create_job - [X] create_keys_and_certificate @@ -3642,6 +3924,9 @@ - [ ] create_ota_update - [X] create_policy - [ ] create_policy_version +- [ ] create_provisioning_claim +- [ ] create_provisioning_template +- [ ] create_provisioning_template_version - [ ] create_role_alias - [ ] create_scheduled_audit - [ ] create_security_profile @@ -3656,6 +3941,7 @@ - [ ] delete_billing_group - [ ] delete_ca_certificate - [X] delete_certificate +- [ ] delete_domain_configuration - [ ] delete_dynamic_thing_group - [ ] delete_job - [ ] delete_job_execution @@ -3663,6 +3949,8 @@ - [ ] delete_ota_update - [X] delete_policy - [ ] delete_policy_version +- [ ] delete_provisioning_template +- [ ] delete_provisioning_template_version - [ ] delete_registration_code - [ ] delete_role_alias - [ ] delete_scheduled_audit @@ -3684,12 +3972,15 @@ - [ ] describe_ca_certificate - [X] describe_certificate - [ ] describe_default_authorizer +- [ ] describe_domain_configuration - [ ] describe_endpoint - [ ] describe_event_configurations - [ ] describe_index - [X] describe_job - [ ] describe_job_execution - [ ] describe_mitigation_action +- [ ] describe_provisioning_template +- [ ] describe_provisioning_template_version - [ ] describe_role_alias - [ ] describe_scheduled_audit - [ ] describe_security_profile @@ -3729,6 +4020,7 @@ - [ ] list_ca_certificates - [X] list_certificates - [ ] list_certificates_by_ca +- [ ] list_domain_configurations - [ ] list_indices - [ ] list_job_executions_for_job - [ ] list_job_executions_for_thing @@ -3741,6 +4033,8 @@ - [ ] list_policy_versions - [X] list_principal_policies - [X] list_principal_things +- [ ] list_provisioning_template_versions +- [ ] list_provisioning_templates - [ ] list_role_aliases - [ ] list_scheduled_audits - [ ] list_security_profiles @@ -3789,11 +4083,13 @@ - [ ] update_billing_group - [ ] update_ca_certificate - [X] update_certificate +- [ ] update_domain_configuration - [ ] update_dynamic_thing_group - [ ] update_event_configurations - [ ] update_indexing_configuration - [ ] update_job - [ ] update_mitigation_action +- [ ] update_provisioning_template - [ ] update_role_alias - [ ] update_scheduled_audit - [ ] update_security_profile @@ -3916,6 +4212,16 @@ - [ ] describe_detector - [ ] list_detectors +## iotsecuretunneling +0% implemented +- [ ] close_tunnel +- [ ] describe_tunnel +- [ ] list_tags_for_resource +- [ ] list_tunnels +- [ ] open_tunnel +- [ ] tag_resource +- [ ] untag_resource + ## iotthingsgraph 0% implemented - [ ] associate_entity_to_thing @@ -3975,6 +4281,30 @@ - [ ] update_broker_count - [ ] update_broker_storage - [ ] update_cluster_configuration +- [ ] update_monitoring + +## kendra +0% implemented +- [ ] batch_delete_document +- [ ] batch_put_document +- [ ] create_data_source +- [ ] create_faq +- [ ] create_index +- [ ] delete_faq +- [ ] delete_index +- [ ] describe_data_source +- [ ] describe_faq +- [ ] describe_index +- [ ] list_data_source_sync_jobs +- [ ] list_data_sources +- [ ] list_faqs +- [ ] list_indices +- [ ] query +- [ ] start_data_source_sync_job +- [ ] stop_data_source_sync_job +- [ ] submit_feedback +- [ ] update_data_source +- [ ] update_index ## kinesis 50% implemented @@ -4018,6 +4348,11 @@ 0% implemented - [ ] get_media +## kinesis-video-signaling +0% implemented +- [ ] get_ice_server_config +- [ ] send_alexa_offer_to_master + ## kinesisanalytics 0% implemented - [ ] add_application_cloud_watch_logging_option @@ -4048,6 +4383,7 @@ - [ ] add_application_input_processing_configuration - [ ] add_application_output - [ ] add_application_reference_data_source +- [ ] add_application_vpc_configuration - [ ] create_application - [ ] create_application_snapshot - [ ] delete_application @@ -4056,6 +4392,7 @@ - [ ] delete_application_output - [ ] delete_application_reference_data_source - [ ] delete_application_snapshot +- [ ] delete_application_vpc_configuration - [ ] describe_application - [ ] describe_application_snapshot - [ ] discover_input_schema @@ -4070,19 +4407,28 @@ ## kinesisvideo 0% implemented +- [ ] create_signaling_channel - [ ] create_stream +- [ ] delete_signaling_channel - [ ] delete_stream +- [ ] describe_signaling_channel - [ ] describe_stream - [ ] get_data_endpoint +- [ ] get_signaling_channel_endpoint +- [ ] list_signaling_channels - [ ] list_streams +- [ ] list_tags_for_resource - [ ] list_tags_for_stream +- [ ] tag_resource - [ ] tag_stream +- [ ] untag_resource - [ ] untag_stream - [ ] update_data_retention +- [ ] update_signaling_channel - [ ] update_stream ## kms -48% implemented +43% implemented - [X] cancel_key_deletion - [ ] connect_custom_key_store - [ ] create_alias @@ -4102,11 +4448,14 @@ - [X] enable_key_rotation - [X] encrypt - [X] generate_data_key +- [ ] generate_data_key_pair +- [ ] generate_data_key_pair_without_plaintext - [ ] generate_data_key_without_plaintext - [ ] generate_random - [X] get_key_policy - [X] get_key_rotation_status - [ ] get_parameters_for_import +- [ ] get_public_key - [ ] import_key_material - [ ] list_aliases - [ ] list_grants @@ -4119,11 +4468,13 @@ - [ ] retire_grant - [ ] revoke_grant - [X] schedule_key_deletion +- [ ] sign - [X] tag_resource - [ ] untag_resource - [ ] update_alias - [ ] update_custom_key_store - [X] update_key_description +- [ ] verify ## lakeformation 0% implemented @@ -4142,7 +4493,7 @@ - [ ] update_resource ## lambda -41% implemented +32% implemented - [ ] add_layer_version_permission - [ ] add_permission - [ ] create_alias @@ -4152,28 +4503,37 @@ - [X] delete_event_source_mapping - [X] delete_function - [ ] delete_function_concurrency +- [ ] delete_function_event_invoke_config - [ ] delete_layer_version +- [ ] delete_provisioned_concurrency_config - [ ] get_account_settings - [ ] get_alias - [X] get_event_source_mapping - [X] get_function +- [ ] get_function_concurrency - [ ] get_function_configuration +- [ ] get_function_event_invoke_config - [ ] get_layer_version - [ ] get_layer_version_by_arn - [ ] get_layer_version_policy - [ ] get_policy +- [ ] get_provisioned_concurrency_config - [X] invoke - [ ] invoke_async - [ ] list_aliases - [X] list_event_source_mappings +- [ ] list_function_event_invoke_configs - [X] list_functions - [ ] list_layer_versions - [ ] list_layers +- [ ] list_provisioned_concurrency_configs - [X] list_tags - [X] list_versions_by_function - [ ] publish_layer_version - [ ] publish_version - [ ] put_function_concurrency +- [ ] put_function_event_invoke_config +- [ ] put_provisioned_concurrency_config - [ ] remove_layer_version_permission - [ ] remove_permission - [X] tag_resource @@ -4182,6 +4542,7 @@ - [X] update_event_source_mapping - [X] update_function_code - [X] update_function_configuration +- [ ] update_function_event_invoke_config ## lex-models 0% implemented @@ -4237,6 +4598,7 @@ - [ ] get_license_configuration - [ ] get_service_settings - [ ] list_associations_for_license_configuration +- [ ] list_failures_for_license_configuration_operations - [ ] list_license_configurations - [ ] list_license_specifications_for_resource - [ ] list_resource_inventory @@ -4532,32 +4894,44 @@ - [ ] create_channel - [ ] create_input - [ ] create_input_security_group +- [ ] create_multiplex +- [ ] create_multiplex_program - [ ] create_tags - [ ] delete_channel - [ ] delete_input - [ ] delete_input_security_group +- [ ] delete_multiplex +- [ ] delete_multiplex_program - [ ] delete_reservation - [ ] delete_schedule - [ ] delete_tags - [ ] describe_channel - [ ] describe_input - [ ] describe_input_security_group +- [ ] describe_multiplex +- [ ] describe_multiplex_program - [ ] describe_offering - [ ] describe_reservation - [ ] describe_schedule - [ ] list_channels - [ ] list_input_security_groups - [ ] list_inputs +- [ ] list_multiplex_programs +- [ ] list_multiplexes - [ ] list_offerings - [ ] list_reservations - [ ] list_tags_for_resource - [ ] purchase_offering - [ ] start_channel +- [ ] start_multiplex - [ ] stop_channel +- [ ] stop_multiplex - [ ] update_channel - [ ] update_channel_class - [ ] update_input - [ ] update_input_security_group +- [ ] update_multiplex +- [ ] update_multiplex_program - [ ] update_reservation ## mediapackage @@ -4806,6 +5180,37 @@ - [ ] restore_db_cluster_from_snapshot - [ ] restore_db_cluster_to_point_in_time +## networkmanager +0% implemented +- [ ] associate_customer_gateway +- [ ] associate_link +- [ ] create_device +- [ ] create_global_network +- [ ] create_link +- [ ] create_site +- [ ] delete_device +- [ ] delete_global_network +- [ ] delete_link +- [ ] delete_site +- [ ] deregister_transit_gateway +- [ ] describe_global_networks +- [ ] disassociate_customer_gateway +- [ ] disassociate_link +- [ ] get_customer_gateway_associations +- [ ] get_devices +- [ ] get_link_associations +- [ ] get_links +- [ ] get_sites +- [ ] get_transit_gateway_registrations +- [ ] list_tags_for_resource +- [ ] register_transit_gateway +- [ ] tag_resource +- [ ] untag_resource +- [ ] update_device +- [ ] update_global_network +- [ ] update_link +- [ ] update_site + ## opsworks 12% implemented - [ ] assign_instance @@ -4903,7 +5308,7 @@ - [ ] update_server_engine_attributes ## organizations -50% implemented +48% implemented - [ ] accept_handshake - [X] attach_policy - [ ] cancel_handshake @@ -4918,6 +5323,7 @@ - [ ] delete_policy - [X] describe_account - [X] describe_create_account_status +- [ ] describe_effective_policy - [ ] describe_handshake - [X] describe_organization - [X] describe_organizational_unit @@ -4951,6 +5357,14 @@ - [ ] update_organizational_unit - [ ] update_policy +## outposts +0% implemented +- [ ] create_outpost +- [ ] get_outpost +- [ ] get_outpost_instance_types +- [ ] list_outposts +- [ ] list_sites + ## personalize 0% implemented - [ ] create_batch_inference_job @@ -5282,17 +5696,23 @@ 0% implemented - [ ] accept_resource_share_invitation - [ ] associate_resource_share +- [ ] associate_resource_share_permission - [ ] create_resource_share - [ ] delete_resource_share - [ ] disassociate_resource_share +- [ ] disassociate_resource_share_permission - [ ] enable_sharing_with_aws_organization +- [ ] get_permission - [ ] get_resource_policies - [ ] get_resource_share_associations - [ ] get_resource_share_invitations - [ ] get_resource_shares - [ ] list_pending_invitation_resources +- [ ] list_permissions - [ ] list_principals +- [ ] list_resource_share_permissions - [ ] list_resources +- [ ] promote_resource_share_created_from_policy - [ ] reject_resource_share_invitation - [ ] tag_resource - [ ] untag_resource @@ -5320,6 +5740,7 @@ - [ ] create_db_instance - [ ] create_db_instance_read_replica - [ ] create_db_parameter_group +- [ ] create_db_proxy - [ ] create_db_security_group - [ ] create_db_snapshot - [ ] create_db_subnet_group @@ -5334,6 +5755,7 @@ - [ ] delete_db_instance - [ ] delete_db_instance_automated_backup - [ ] delete_db_parameter_group +- [ ] delete_db_proxy - [ ] delete_db_security_group - [ ] delete_db_snapshot - [ ] delete_db_subnet_group @@ -5341,6 +5763,7 @@ - [ ] delete_global_cluster - [ ] delete_installation_media - [ ] delete_option_group +- [ ] deregister_db_proxy_targets - [ ] describe_account_attributes - [ ] describe_certificates - [ ] describe_custom_availability_zones @@ -5357,6 +5780,9 @@ - [ ] describe_db_log_files - [ ] describe_db_parameter_groups - [ ] describe_db_parameters +- [ ] describe_db_proxies +- [ ] describe_db_proxy_target_groups +- [ ] describe_db_proxy_targets - [ ] describe_db_security_groups - [ ] describe_db_snapshot_attributes - [ ] describe_db_snapshots @@ -5387,6 +5813,8 @@ - [ ] modify_db_cluster_snapshot_attribute - [ ] modify_db_instance - [ ] modify_db_parameter_group +- [ ] modify_db_proxy +- [ ] modify_db_proxy_target_group - [ ] modify_db_snapshot - [ ] modify_db_snapshot_attribute - [ ] modify_db_subnet_group @@ -5397,6 +5825,7 @@ - [ ] promote_read_replica_db_cluster - [ ] purchase_reserved_db_instances_offering - [ ] reboot_db_instance +- [ ] register_db_proxy_targets - [ ] remove_from_global_cluster - [ ] remove_role_from_db_cluster - [ ] remove_role_from_db_instance @@ -5428,7 +5857,7 @@ - [ ] rollback_transaction ## redshift -31% implemented +30% implemented - [ ] accept_reserved_node_exchange - [ ] authorize_cluster_security_group_ingress - [ ] authorize_snapshot_access @@ -5444,6 +5873,7 @@ - [ ] create_event_subscription - [ ] create_hsm_client_certificate - [ ] create_hsm_configuration +- [ ] create_scheduled_action - [X] create_snapshot_copy_grant - [ ] create_snapshot_schedule - [X] create_tags @@ -5455,6 +5885,7 @@ - [ ] delete_event_subscription - [ ] delete_hsm_client_certificate - [ ] delete_hsm_configuration +- [ ] delete_scheduled_action - [X] delete_snapshot_copy_grant - [ ] delete_snapshot_schedule - [X] delete_tags @@ -5480,6 +5911,7 @@ - [ ] describe_reserved_node_offerings - [ ] describe_reserved_nodes - [ ] describe_resize +- [ ] describe_scheduled_actions - [X] describe_snapshot_copy_grants - [ ] describe_snapshot_schedules - [ ] describe_storage @@ -5500,6 +5932,7 @@ - [ ] modify_cluster_snapshot_schedule - [ ] modify_cluster_subnet_group - [ ] modify_event_subscription +- [ ] modify_scheduled_action - [X] modify_snapshot_copy_retention_period - [ ] modify_snapshot_schedule - [ ] purchase_reserved_node_offering @@ -5516,12 +5949,17 @@ 0% implemented - [ ] compare_faces - [ ] create_collection +- [ ] create_project +- [ ] create_project_version - [ ] create_stream_processor - [ ] delete_collection - [ ] delete_faces - [ ] delete_stream_processor - [ ] describe_collection +- [ ] describe_project_versions +- [ ] describe_projects - [ ] describe_stream_processor +- [ ] detect_custom_labels - [ ] detect_faces - [ ] detect_labels - [ ] detect_moderation_labels @@ -5546,7 +5984,9 @@ - [ ] start_face_search - [ ] start_label_detection - [ ] start_person_tracking +- [ ] start_project_version - [ ] start_stream_processor +- [ ] stop_project_version - [ ] stop_stream_processor ## resource-groups @@ -5565,10 +6005,13 @@ - [X] update_group_query ## resourcegroupstaggingapi -60% implemented +37% implemented +- [ ] describe_report_creation +- [ ] get_compliance_summary - [X] get_resources - [X] get_tag_keys - [X] get_tag_values +- [ ] start_report_creation - [ ] tag_resources - [ ] untag_resources @@ -5815,11 +6258,19 @@ ## s3control 0% implemented +- [ ] create_access_point - [ ] create_job +- [ ] delete_access_point +- [ ] delete_access_point_policy - [ ] delete_public_access_block - [ ] describe_job +- [ ] get_access_point +- [ ] get_access_point_policy +- [ ] get_access_point_policy_status - [ ] get_public_access_block +- [ ] list_access_points - [ ] list_jobs +- [ ] put_access_point_policy - [ ] put_public_access_block - [ ] update_job_priority - [ ] update_job_status @@ -5827,81 +6278,145 @@ ## sagemaker 0% implemented - [ ] add_tags +- [ ] associate_trial_component - [ ] create_algorithm +- [ ] create_app +- [ ] create_auto_ml_job - [ ] create_code_repository - [ ] create_compilation_job +- [ ] create_domain - [ ] create_endpoint - [ ] create_endpoint_config +- [ ] create_experiment +- [ ] create_flow_definition +- [ ] create_human_task_ui - [ ] create_hyper_parameter_tuning_job - [ ] create_labeling_job - [ ] create_model - [ ] create_model_package +- [ ] create_monitoring_schedule - [ ] create_notebook_instance - [ ] create_notebook_instance_lifecycle_config +- [ ] create_presigned_domain_url - [ ] create_presigned_notebook_instance_url +- [ ] create_processing_job - [ ] create_training_job - [ ] create_transform_job +- [ ] create_trial +- [ ] create_trial_component +- [ ] create_user_profile - [ ] create_workteam - [ ] delete_algorithm +- [ ] delete_app - [ ] delete_code_repository +- [ ] delete_domain - [ ] delete_endpoint - [ ] delete_endpoint_config +- [ ] delete_experiment +- [ ] delete_flow_definition - [ ] delete_model - [ ] delete_model_package +- [ ] delete_monitoring_schedule - [ ] delete_notebook_instance - [ ] delete_notebook_instance_lifecycle_config - [ ] delete_tags +- [ ] delete_trial +- [ ] delete_trial_component +- [ ] delete_user_profile - [ ] delete_workteam - [ ] describe_algorithm +- [ ] describe_app +- [ ] describe_auto_ml_job - [ ] describe_code_repository - [ ] describe_compilation_job +- [ ] describe_domain - [ ] describe_endpoint - [ ] describe_endpoint_config +- [ ] describe_experiment +- [ ] describe_flow_definition +- [ ] describe_human_task_ui - [ ] describe_hyper_parameter_tuning_job - [ ] describe_labeling_job - [ ] describe_model - [ ] describe_model_package +- [ ] describe_monitoring_schedule - [ ] describe_notebook_instance - [ ] describe_notebook_instance_lifecycle_config +- [ ] describe_processing_job - [ ] describe_subscribed_workteam - [ ] describe_training_job - [ ] describe_transform_job +- [ ] describe_trial +- [ ] describe_trial_component +- [ ] describe_user_profile - [ ] describe_workteam +- [ ] disassociate_trial_component - [ ] get_search_suggestions - [ ] list_algorithms +- [ ] list_apps +- [ ] list_auto_ml_jobs +- [ ] list_candidates_for_auto_ml_job - [ ] list_code_repositories - [ ] list_compilation_jobs +- [ ] list_domains - [ ] list_endpoint_configs - [ ] list_endpoints +- [ ] list_experiments +- [ ] list_flow_definitions +- [ ] list_human_task_uis - [ ] list_hyper_parameter_tuning_jobs - [ ] list_labeling_jobs - [ ] list_labeling_jobs_for_workteam - [ ] list_model_packages - [ ] list_models +- [ ] list_monitoring_executions +- [ ] list_monitoring_schedules - [ ] list_notebook_instance_lifecycle_configs - [ ] list_notebook_instances +- [ ] list_processing_jobs - [ ] list_subscribed_workteams - [ ] list_tags - [ ] list_training_jobs - [ ] list_training_jobs_for_hyper_parameter_tuning_job - [ ] list_transform_jobs +- [ ] list_trial_components +- [ ] list_trials +- [ ] list_user_profiles - [ ] list_workteams - [ ] render_ui_template - [ ] search +- [ ] start_monitoring_schedule - [ ] start_notebook_instance +- [ ] stop_auto_ml_job - [ ] stop_compilation_job - [ ] stop_hyper_parameter_tuning_job - [ ] stop_labeling_job +- [ ] stop_monitoring_schedule - [ ] stop_notebook_instance +- [ ] stop_processing_job - [ ] stop_training_job - [ ] stop_transform_job - [ ] update_code_repository +- [ ] update_domain - [ ] update_endpoint - [ ] update_endpoint_weights_and_capacities +- [ ] update_experiment +- [ ] update_monitoring_schedule - [ ] update_notebook_instance - [ ] update_notebook_instance_lifecycle_config +- [ ] update_trial +- [ ] update_trial_component +- [ ] update_user_profile - [ ] update_workteam +## sagemaker-a2i-runtime +0% implemented +- [ ] delete_human_loop +- [ ] describe_human_loop +- [ ] list_human_loops +- [ ] start_human_loop +- [ ] stop_human_loop + ## sagemaker-runtime 0% implemented - [ ] invoke_endpoint @@ -5917,6 +6432,38 @@ - [ ] tag_resource - [ ] untag_resource +## schemas +0% implemented +- [ ] create_discoverer +- [ ] create_registry +- [ ] create_schema +- [ ] delete_discoverer +- [ ] delete_registry +- [ ] delete_schema +- [ ] delete_schema_version +- [ ] describe_code_binding +- [ ] describe_discoverer +- [ ] describe_registry +- [ ] describe_schema +- [ ] get_code_binding_source +- [ ] get_discovered_schema +- [ ] list_discoverers +- [ ] list_registries +- [ ] list_schema_versions +- [ ] list_schemas +- [ ] list_tags_for_resource +- [ ] lock_service_linked_role +- [ ] put_code_binding +- [ ] search_schemas +- [ ] start_discoverer +- [ ] stop_discoverer +- [ ] tag_resource +- [ ] unlock_service_linked_role +- [ ] untag_resource +- [ ] update_discoverer +- [ ] update_registry +- [ ] update_schema + ## sdb 0% implemented - [ ] batch_delete_attributes @@ -6221,6 +6768,7 @@ - [ ] delete_configuration_set_event_destination - [ ] delete_dedicated_ip_pool - [ ] delete_email_identity +- [ ] delete_suppressed_destination - [ ] get_account - [ ] get_blacklist_reports - [ ] get_configuration_set @@ -6232,24 +6780,30 @@ - [ ] get_domain_deliverability_campaign - [ ] get_domain_statistics_report - [ ] get_email_identity +- [ ] get_suppressed_destination - [ ] list_configuration_sets - [ ] list_dedicated_ip_pools - [ ] list_deliverability_test_reports - [ ] list_domain_deliverability_campaigns - [ ] list_email_identities +- [ ] list_suppressed_destinations - [ ] list_tags_for_resource - [ ] put_account_dedicated_ip_warmup_attributes - [ ] put_account_sending_attributes +- [ ] put_account_suppression_attributes - [ ] put_configuration_set_delivery_options - [ ] put_configuration_set_reputation_options - [ ] put_configuration_set_sending_options +- [ ] put_configuration_set_suppression_options - [ ] put_configuration_set_tracking_options - [ ] put_dedicated_ip_in_pool - [ ] put_dedicated_ip_warmup_attributes - [ ] put_deliverability_dashboard_option - [ ] put_email_identity_dkim_attributes +- [ ] put_email_identity_dkim_signing_attributes - [ ] put_email_identity_feedback_attributes - [ ] put_email_identity_mail_from_attributes +- [ ] put_suppressed_destination - [ ] send_email - [ ] tag_resource - [ ] untag_resource @@ -6473,6 +7027,7 @@ - [ ] describe_patch_properties - [ ] describe_sessions - [ ] get_automation_execution +- [ ] get_calendar_state - [X] get_command_invocation - [ ] get_connection_status - [ ] get_default_patch_baseline @@ -6934,6 +7489,45 @@ - [ ] update_web_acl - [ ] update_xss_match_set +## wafv2 +0% implemented +- [ ] associate_web_acl +- [ ] check_capacity +- [ ] create_ip_set +- [ ] create_regex_pattern_set +- [ ] create_rule_group +- [ ] create_web_acl +- [ ] delete_ip_set +- [ ] delete_logging_configuration +- [ ] delete_regex_pattern_set +- [ ] delete_rule_group +- [ ] delete_web_acl +- [ ] describe_managed_rule_group +- [ ] disassociate_web_acl +- [ ] get_ip_set +- [ ] get_logging_configuration +- [ ] get_rate_based_statement_managed_keys +- [ ] get_regex_pattern_set +- [ ] get_rule_group +- [ ] get_sampled_requests +- [ ] get_web_acl +- [ ] get_web_acl_for_resource +- [ ] list_available_managed_rule_groups +- [ ] list_ip_sets +- [ ] list_logging_configurations +- [ ] list_regex_pattern_sets +- [ ] list_resources_for_web_acl +- [ ] list_rule_groups +- [ ] list_tags_for_resource +- [ ] list_web_acls +- [ ] put_logging_configuration +- [ ] tag_resource +- [ ] untag_resource +- [ ] update_ip_set +- [ ] update_regex_pattern_set +- [ ] update_rule_group +- [ ] update_web_acl + ## workdocs 0% implemented - [ ] abort_document_version_upload diff --git a/moto/codepipeline/models.py b/moto/codepipeline/models.py index 758c41555..5b6828f11 100644 --- a/moto/codepipeline/models.py +++ b/moto/codepipeline/models.py @@ -142,6 +142,9 @@ class CodePipelineBackend(BaseBackend): return sorted(pipelines, key=lambda i: i["name"]) + def delete_pipeline(self, name): + self.pipelines.pop(name, None) + codepipeline_backends = {} for region in Session().get_available_regions("codepipeline"): diff --git a/moto/codepipeline/responses.py b/moto/codepipeline/responses.py index 6611f9257..f2eee4d4e 100644 --- a/moto/codepipeline/responses.py +++ b/moto/codepipeline/responses.py @@ -34,3 +34,8 @@ class CodePipelineResponse(BaseResponse): pipelines = self.codepipeline_backend.list_pipelines() return json.dumps({"pipelines": pipelines}) + + def delete_pipeline(self): + self.codepipeline_backend.delete_pipeline(self._get_param("name")) + + return "" diff --git a/tests/test_codepipeline/test_codepipeline.py b/tests/test_codepipeline/test_codepipeline.py index 12b3b7975..2bbb52898 100644 --- a/tests/test_codepipeline/test_codepipeline.py +++ b/tests/test_codepipeline/test_codepipeline.py @@ -813,6 +813,74 @@ def test_list_pipelines(): ) +@freeze_time("2019-01-01 12:00:00") +@mock_codepipeline +def test_delete_pipeline(): + client = boto3.client("codepipeline", region_name="us-east-1") + client.create_pipeline( + pipeline={ + "name": "test-pipeline", + "roleArn": get_role_arn(), + "artifactStore": { + "type": "S3", + "location": "codepipeline-us-east-1-123456789012", + }, + "stages": [ + { + "name": "Stage-1", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Source", + "owner": "AWS", + "provider": "S3", + "version": "1", + }, + "configuration": { + "S3Bucket": "test-bucket", + "S3ObjectKey": "test-object", + }, + "outputArtifacts": [{"name": "artifact"},], + }, + ], + }, + { + "name": "Stage-2", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Approval", + "owner": "AWS", + "provider": "Manual", + "version": "1", + }, + }, + ], + }, + ], + }, + ) + client.list_pipelines()["pipelines"].should.equal( + [ + { + "name": "test-pipeline", + "version": 1, + "created": datetime.now(timezone.utc), + "updated": datetime.now(timezone.utc), + } + ] + ) + + client.delete_pipeline(name="test-pipeline") + + client.list_pipelines()["pipelines"].should.have.length_of(0) + + # deleting a not existing pipeline, should raise no exception + client.delete_pipeline(name="test-pipeline") + + @mock_iam def get_role_arn(): iam = boto3.client("iam", region_name="us-east-1") From 03fd04db33ffe465edd04e6ecfe933c6439a5531 Mon Sep 17 00:00:00 2001 From: gruebel Date: Tue, 17 Dec 2019 17:01:02 +0100 Subject: [PATCH 6/9] Use pytz instead of timezone --- tests/test_codepipeline/test_codepipeline.py | 23 ++++++++++---------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/tests/test_codepipeline/test_codepipeline.py b/tests/test_codepipeline/test_codepipeline.py index 2bbb52898..05095f20a 100644 --- a/tests/test_codepipeline/test_codepipeline.py +++ b/tests/test_codepipeline/test_codepipeline.py @@ -1,7 +1,8 @@ import json -from datetime import datetime, timezone +from datetime import datetime import boto3 +import pytz import sure # noqa from botocore.exceptions import ClientError from freezegun import freeze_time @@ -454,8 +455,8 @@ def test_get_pipeline(): response["metadata"].should.equal( { "pipelineArn": "arn:aws:codepipeline:us-east-1:123456789012:test-pipeline", - "created": datetime.now(timezone.utc), - "updated": datetime.now(timezone.utc), + "created": datetime.now(pytz.utc), + "updated": datetime.now(pytz.utc), } ) @@ -480,7 +481,7 @@ def test_update_pipeline(): client = boto3.client("codepipeline", region_name="us-east-1") role_arn = get_role_arn() with freeze_time("2019-01-01 12:00:00"): - created_time = datetime.now(timezone.utc) + created_time = datetime.now(pytz.utc) client.create_pipeline( pipeline={ "name": "test-pipeline", @@ -529,7 +530,7 @@ def test_update_pipeline(): ) with freeze_time("2019-01-02 12:00:00"): - updated_time = datetime.now(timezone.utc) + updated_time = datetime.now(pytz.utc) response = client.update_pipeline( pipeline={ "name": "test-pipeline", @@ -800,14 +801,14 @@ def test_list_pipelines(): { "name": "test-pipeline-1", "version": 1, - "created": datetime.now(timezone.utc), - "updated": datetime.now(timezone.utc), + "created": datetime.now(pytz.utc), + "updated": datetime.now(pytz.utc), }, { "name": "test-pipeline-2", "version": 1, - "created": datetime.now(timezone.utc), - "updated": datetime.now(timezone.utc), + "created": datetime.now(pytz.utc), + "updated": datetime.now(pytz.utc), }, ] ) @@ -867,8 +868,8 @@ def test_delete_pipeline(): { "name": "test-pipeline", "version": 1, - "created": datetime.now(timezone.utc), - "updated": datetime.now(timezone.utc), + "created": datetime.now(pytz.utc), + "updated": datetime.now(pytz.utc), } ] ) From a67660b8a4af2062b7e12818ed5950126e66dd48 Mon Sep 17 00:00:00 2001 From: gruebel Date: Thu, 19 Dec 2019 21:41:32 +0100 Subject: [PATCH 7/9] Adjust tests to work in server mode --- tests/test_codepipeline/test_codepipeline.py | 248 ++++++++----------- 1 file changed, 110 insertions(+), 138 deletions(-) diff --git a/tests/test_codepipeline/test_codepipeline.py b/tests/test_codepipeline/test_codepipeline.py index 05095f20a..d853aa3b2 100644 --- a/tests/test_codepipeline/test_codepipeline.py +++ b/tests/test_codepipeline/test_codepipeline.py @@ -1,11 +1,9 @@ import json -from datetime import datetime +from datetime import datetime, timezone import boto3 -import pytz import sure # noqa from botocore.exceptions import ClientError -from freezegun import freeze_time from nose.tools import assert_raises from moto import mock_codepipeline, mock_iam @@ -347,7 +345,6 @@ def test_create_pipeline_errors(): ) -@freeze_time("2019-01-01 12:00:00") @mock_codepipeline def test_get_pipeline(): client = boto3.client("codepipeline", region_name="us-east-1") @@ -452,13 +449,11 @@ def test_get_pipeline(): "version": 1, } ) - response["metadata"].should.equal( - { - "pipelineArn": "arn:aws:codepipeline:us-east-1:123456789012:test-pipeline", - "created": datetime.now(pytz.utc), - "updated": datetime.now(pytz.utc), - } + response["metadata"]["pipelineArn"].should.equal( + "arn:aws:codepipeline:us-east-1:123456789012:test-pipeline" ) + response["metadata"]["created"].should.be.a(datetime) + response["metadata"]["updated"].should.be.a(datetime) @mock_codepipeline @@ -480,102 +475,102 @@ def test_get_pipeline_errors(): def test_update_pipeline(): client = boto3.client("codepipeline", region_name="us-east-1") role_arn = get_role_arn() - with freeze_time("2019-01-01 12:00:00"): - created_time = datetime.now(pytz.utc) - client.create_pipeline( - pipeline={ - "name": "test-pipeline", - "roleArn": role_arn, - "artifactStore": { - "type": "S3", - "location": "codepipeline-us-east-1-123456789012", - }, - "stages": [ - { - "name": "Stage-1", - "actions": [ - { - "name": "Action-1", - "actionTypeId": { - "category": "Source", - "owner": "AWS", - "provider": "S3", - "version": "1", - }, - "configuration": { - "S3Bucket": "test-bucket", - "S3ObjectKey": "test-object", - }, - "outputArtifacts": [{"name": "artifact"},], - }, - ], - }, - { - "name": "Stage-2", - "actions": [ - { - "name": "Action-1", - "actionTypeId": { - "category": "Approval", - "owner": "AWS", - "provider": "Manual", - "version": "1", - }, - }, - ], - }, - ], + client.create_pipeline( + pipeline={ + "name": "test-pipeline", + "roleArn": role_arn, + "artifactStore": { + "type": "S3", + "location": "codepipeline-us-east-1-123456789012", }, - tags=[{"key": "key", "value": "value"}], - ) - - with freeze_time("2019-01-02 12:00:00"): - updated_time = datetime.now(pytz.utc) - response = client.update_pipeline( - pipeline={ - "name": "test-pipeline", - "roleArn": role_arn, - "artifactStore": { - "type": "S3", - "location": "codepipeline-us-east-1-123456789012", + "stages": [ + { + "name": "Stage-1", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Source", + "owner": "AWS", + "provider": "S3", + "version": "1", + }, + "configuration": { + "S3Bucket": "test-bucket", + "S3ObjectKey": "test-object", + }, + "outputArtifacts": [{"name": "artifact"},], + }, + ], }, - "stages": [ - { - "name": "Stage-1", - "actions": [ - { - "name": "Action-1", - "actionTypeId": { - "category": "Source", - "owner": "AWS", - "provider": "S3", - "version": "1", - }, - "configuration": { - "S3Bucket": "different-bucket", - "S3ObjectKey": "test-object", - }, - "outputArtifacts": [{"name": "artifact"},], + { + "name": "Stage-2", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Approval", + "owner": "AWS", + "provider": "Manual", + "version": "1", }, - ], - }, - { - "name": "Stage-2", - "actions": [ - { - "name": "Action-1", - "actionTypeId": { - "category": "Approval", - "owner": "AWS", - "provider": "Manual", - "version": "1", - }, + }, + ], + }, + ], + }, + tags=[{"key": "key", "value": "value"}], + ) + + response = client.get_pipeline(name="test-pipeline") + created_time = response["metadata"]["created"] + updated_time = response["metadata"]["updated"] + + response = client.update_pipeline( + pipeline={ + "name": "test-pipeline", + "roleArn": role_arn, + "artifactStore": { + "type": "S3", + "location": "codepipeline-us-east-1-123456789012", + }, + "stages": [ + { + "name": "Stage-1", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Source", + "owner": "AWS", + "provider": "S3", + "version": "1", }, - ], - }, - ], - } - ) + "configuration": { + "S3Bucket": "different-bucket", + "S3ObjectKey": "test-object", + }, + "outputArtifacts": [{"name": "artifact"},], + }, + ], + }, + { + "name": "Stage-2", + "actions": [ + { + "name": "Action-1", + "actionTypeId": { + "category": "Approval", + "owner": "AWS", + "provider": "Manual", + "version": "1", + }, + }, + ], + }, + ], + } + ) response["pipeline"].should.equal( { @@ -630,14 +625,9 @@ def test_update_pipeline(): } ) - response = client.get_pipeline(name="test-pipeline") - response["metadata"].should.equal( - { - "pipelineArn": "arn:aws:codepipeline:us-east-1:123456789012:test-pipeline", - "created": created_time, - "updated": updated_time, - } - ) + metadata = client.get_pipeline(name="test-pipeline")["metadata"] + metadata["created"].should.equal(created_time) + metadata["updated"].should.be.greater_than(updated_time) @mock_codepipeline @@ -699,7 +689,6 @@ def test_update_pipeline_errors(): ) -@freeze_time("2019-01-01 12:00:00") @mock_codepipeline def test_list_pipelines(): client = boto3.client("codepipeline", region_name="us-east-1") @@ -796,25 +785,17 @@ def test_list_pipelines(): response = client.list_pipelines() - response["pipelines"].should.equal( - [ - { - "name": "test-pipeline-1", - "version": 1, - "created": datetime.now(pytz.utc), - "updated": datetime.now(pytz.utc), - }, - { - "name": "test-pipeline-2", - "version": 1, - "created": datetime.now(pytz.utc), - "updated": datetime.now(pytz.utc), - }, - ] - ) + response["pipelines"].should.have.length_of(2) + response["pipelines"][0]["name"].should.equal("test-pipeline-1") + response["pipelines"][0]["version"].should.equal(1) + response["pipelines"][0]["created"].should.be.a(datetime) + response["pipelines"][0]["updated"].should.be.a(datetime) + response["pipelines"][1]["name"].should.equal("test-pipeline-2") + response["pipelines"][1]["version"].should.equal(1) + response["pipelines"][1]["created"].should.be.a(datetime) + response["pipelines"][1]["updated"].should.be.a(datetime) -@freeze_time("2019-01-01 12:00:00") @mock_codepipeline def test_delete_pipeline(): client = boto3.client("codepipeline", region_name="us-east-1") @@ -863,16 +844,7 @@ def test_delete_pipeline(): ], }, ) - client.list_pipelines()["pipelines"].should.equal( - [ - { - "name": "test-pipeline", - "version": 1, - "created": datetime.now(pytz.utc), - "updated": datetime.now(pytz.utc), - } - ] - ) + client.list_pipelines()["pipelines"].should.have.length_of(1) client.delete_pipeline(name="test-pipeline") From 901be3a6d1643fb27712318f3d5d7edc0ea89916 Mon Sep 17 00:00:00 2001 From: gruebel Date: Fri, 20 Dec 2019 10:54:38 +0100 Subject: [PATCH 8/9] Remove unused import --- tests/test_codepipeline/test_codepipeline.py | 35 +++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/tests/test_codepipeline/test_codepipeline.py b/tests/test_codepipeline/test_codepipeline.py index d853aa3b2..926d7f873 100644 --- a/tests/test_codepipeline/test_codepipeline.py +++ b/tests/test_codepipeline/test_codepipeline.py @@ -1,5 +1,5 @@ import json -from datetime import datetime, timezone +from datetime import datetime import boto3 import sure # noqa @@ -857,18 +857,21 @@ def test_delete_pipeline(): @mock_iam def get_role_arn(): iam = boto3.client("iam", region_name="us-east-1") - return iam.create_role( - RoleName="test-role", - AssumeRolePolicyDocument=json.dumps( - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Principal": {"Service": "codepipeline.amazonaws.com"}, - "Action": "sts:AssumeRole", - } - ], - } - ), - )["Role"]["Arn"] + try: + return iam.get_role(RoleName="test-role")["Role"]["Arn"] + except ClientError: + return iam.create_role( + RoleName="test-role", + AssumeRolePolicyDocument=json.dumps( + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": {"Service": "codepipeline.amazonaws.com"}, + "Action": "sts:AssumeRole", + } + ], + } + ), + )["Role"]["Arn"] From 21770249488cb39b3a432144ca75f7556136ac7e Mon Sep 17 00:00:00 2001 From: gruebel Date: Fri, 20 Dec 2019 16:48:55 +0100 Subject: [PATCH 9/9] Use moto.iam.models.ACCOUNT_ID instead of hardcoded ID --- moto/codepipeline/models.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/moto/codepipeline/models.py b/moto/codepipeline/models.py index 5b6828f11..b3e76f838 100644 --- a/moto/codepipeline/models.py +++ b/moto/codepipeline/models.py @@ -15,7 +15,7 @@ from moto.codepipeline.exceptions import ( ) from moto.core import BaseBackend, BaseModel -DEFAULT_ACCOUNT_ID = "123456789012" +from moto.iam.models import ACCOUNT_ID class CodePipeline(BaseModel): @@ -27,7 +27,7 @@ class CodePipeline(BaseModel): self.tags = {} self._arn = "arn:aws:codepipeline:{0}:{1}:{2}".format( - region, DEFAULT_ACCOUNT_ID, pipeline["name"] + region, ACCOUNT_ID, pipeline["name"] ) self._created = datetime.utcnow() self._updated = datetime.utcnow() @@ -67,7 +67,7 @@ class CodePipelineBackend(BaseBackend): if pipeline["name"] in self.pipelines: raise InvalidStructureException( "A pipeline with the name '{0}' already exists in account '{1}'".format( - pipeline["name"], DEFAULT_ACCOUNT_ID + pipeline["name"], ACCOUNT_ID ) ) @@ -104,7 +104,7 @@ class CodePipelineBackend(BaseBackend): if not codepipeline: raise PipelineNotFoundException( "Account '{0}' does not have a pipeline with name '{1}'".format( - DEFAULT_ACCOUNT_ID, name + ACCOUNT_ID, name ) ) @@ -116,7 +116,7 @@ class CodePipelineBackend(BaseBackend): if not codepipeline: raise ResourceNotFoundException( "The account with id '{0}' does not include a pipeline with the name '{1}'".format( - DEFAULT_ACCOUNT_ID, pipeline["name"] + ACCOUNT_ID, pipeline["name"] ) )