def test_is_docker_image_already_in_registry_401_unauthorized( mock_read_docker_registry_creds, mock_request_head, mock_get_service_docker_registry): mock_read_docker_registry_creds.return_value = (None, None) mock_request_head.side_effect = RequestException() with raises(RequestException): is_docker_image_already_in_registry("fake_service", "fake_soa_dir", "fake_sha")
def test_is_docker_image_already_in_registry_401_unauthorized( mock_read_docker_registy_creds, mock_request_get, mock_load_system_paasta_config, ): mock_read_docker_registy_creds.return_value = (None, None) mock_request_get.side_effect = RequestException() with raises(RequestException): is_docker_image_already_in_registry('fake_service', 'fake_soa_dir', 'fake_sha')
def test_is_docker_image_already_in_registry_tags_are_null( mock_read_docker_registy_creds, mock_request_get, mock_load_system_paasta_config, ): mock_read_docker_registy_creds.return_value = (None, None) mock_request_get.return_value = MagicMock( status_code=200, json=MagicMock(return_value={'tags': None})) assert not is_docker_image_already_in_registry('fake_service', 'fake_soa_dir', 'fake_sha')
def test_is_docker_image_already_in_registry_404_no_such_service_yet( mock_read_docker_registy_creds, mock_request_get, mock_load_system_paasta_config, ): mock_read_docker_registy_creds.return_value = (None, None) mock_request_get.return_value = MagicMock( status_code=404) # No Such Repository Error assert not is_docker_image_already_in_registry('fake_service', 'fake_soa_dir', 'fake_sha')
def test_is_docker_image_already_in_registry_success( mock_read_docker_registy_creds, mock_request_get, mock_load_system_paasta_config, ): mock_read_docker_registy_creds.return_value = (None, None) mock_load_system_paasta_config.get_docker_registry = MagicMock(return_value='fake_registry') mock_request_get.return_value = MagicMock(status_code=200, json=MagicMock(return_value={'tags': ['paasta-fake_sha']})) assert is_docker_image_already_in_registry('fake_service', 'fake_sha') assert mock_load_system_paasta_config.called
def test_is_docker_image_already_with_image_version( mock_read_docker_registry_creds, mock_request_head, mock_get_service_docker_registry): mock_read_docker_registry_creds.return_value = (None, None) mock_get_service_docker_registry.return_value = "registry" mock_request_head.return_value = MagicMock(status_code=404) assert not is_docker_image_already_in_registry( "fake_service", "fake_soa_dir", "fake_sha", "extrastuff") mock_request_head.assert_called_with( ANY, "https://registry/v2/services-fake_service/manifests/paasta-fake_sha-extrastuff", timeout=30, )
def test_is_docker_image_already_in_registry_404_no_such_service_yet( mock_read_docker_registry_creds, mock_request_head, mock_get_service_docker_registry, ): mock_read_docker_registry_creds.return_value = (None, None) mock_get_service_docker_registry.return_value = 'registry' mock_request_head.return_value = MagicMock(status_code=404) # No Such Repository Error assert not is_docker_image_already_in_registry('fake_service', 'fake_soa_dir', 'fake_sha') mock_request_head.assert_called_with( ANY, 'https://registry/v2/services-fake_service/manifests/paasta-fake_sha', timeout=30, )
def test_is_docker_image_already_when_image_does_not_exist( mock_read_docker_registy_creds, mock_request_head, mock_get_service_docker_registry, ): mock_read_docker_registy_creds.return_value = (None, None) mock_get_service_docker_registry.return_value = 'registry' mock_request_head.return_value = MagicMock(status_code=404, ) assert not is_docker_image_already_in_registry('fake_service', 'fake_soa_dir', 'fake_sha') mock_request_head.assert_called_with( ANY, 'https://registry/v2/services-fake_service/manifests/paasta-fake_sha', timeout=30, )
def test_is_docker_image_already_in_registry_success_with_registry_credentials( mock_read_docker_registry_creds, mock_request_head, mock_get_service_docker_registry): auth = ("username", "password") mock_read_docker_registry_creds.return_value = auth mock_get_service_docker_registry.return_value = "registry" mock_request_head.return_value = MagicMock(status_code=200) assert is_docker_image_already_in_registry("fake_service", "fake_soa_dir", "fake_sha") mock_request_head.assert_called_with( ANY, "https://registry/v2/services-fake_service/manifests/paasta-fake_sha", auth=auth, timeout=30, )
def test_is_docker_image_already_in_registry_success_with_registry_credentials( mock_read_docker_registry_creds, mock_request_head, mock_get_service_docker_registry, ): auth = ('username', 'password') mock_read_docker_registry_creds.return_value = auth mock_get_service_docker_registry.return_value = 'registry' mock_request_head.return_value = MagicMock(status_code=200, ) assert is_docker_image_already_in_registry('fake_service', 'fake_soa_dir', 'fake_sha') mock_request_head.assert_called_with( ANY, 'https://registry/v2/services-fake_service/manifests/paasta-fake_sha', auth=auth, timeout=30, )
def test_is_docker_image_already_in_registry_http( mock_read_docker_registy_creds, mock_request_get, mock_load_system_paasta_config, ): def mock_get(session, url, timeout): if url.startswith('https'): raise SSLError("Uh oh") return MagicMock( status_code=200, json=MagicMock(return_value={'tags': None}), ) mock_request_get.side_effect = mock_get mock_read_docker_registy_creds.return_value = (None, None) assert not is_docker_image_already_in_registry('fake_service', 'fake_soa_dir', 'fake_sha')
def test_is_docker_image_already_in_registry_http_when_image_does_not_exist( mock_read_docker_registry_creds, mock_request_head, mock_get_service_docker_registry): def mock_head(session, url, timeout): if url.startswith("https"): raise SSLError("Uh oh") return MagicMock(status_code=404) mock_get_service_docker_registry.return_value = "registry" mock_request_head.side_effect = mock_head mock_read_docker_registry_creds.return_value = (None, None) assert not is_docker_image_already_in_registry("fake_service", "fake_soa_dir", "fake_sha") mock_request_head.assert_called_with( ANY, "http://registry/v2/services-fake_service/manifests/paasta-fake_sha", timeout=30, )
def paasta_mark_for_deployment(args): """Wrapping mark_for_deployment""" if args.verbose: log.setLevel(level=logging.DEBUG) else: log.setLevel(level=logging.INFO) service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service, soa_dir=args.soa_dir) in_use_deploy_groups = list_deploy_groups( service=service, soa_dir=args.soa_dir, ) _, invalid_deploy_groups = validate_given_deploy_groups( in_use_deploy_groups, [args.deploy_group]) if len(invalid_deploy_groups) == 1: paasta_print( PaastaColors.red( "ERROR: These deploy groups are not currently used anywhere: %s.\n" % (",").join(invalid_deploy_groups), )) paasta_print( PaastaColors.red( "This isn't technically wrong because you can mark-for-deployment before deploying there", )) paasta_print( PaastaColors.red( "but this is probably a typo. Did you mean one of these in-use deploy groups?:" )) paasta_print( PaastaColors.red(" %s" % (",").join(in_use_deploy_groups))) paasta_print() paasta_print(PaastaColors.red("Continuing regardless...")) if args.git_url is None: args.git_url = get_git_url(service=service, soa_dir=args.soa_dir) try: validate_full_git_sha(args.commit) except ArgumentTypeError: refs = remote_git.list_remote_refs(args.git_url) commits = short_to_full_git_sha(short=args.commit, refs=refs) if len(commits) != 1: raise ValueError( "%s matched %d git shas (with refs pointing at them). Must match exactly 1." % (args.commit, len(commits)), ) args.commit = commits[0] old_git_sha = get_currently_deployed_sha(service=service, deploy_group=args.deploy_group) if old_git_sha == args.commit: paasta_print( "Warning: The sha asked to be deployed already matches what is set to be deployed:" ) paasta_print(old_git_sha) paasta_print("Continuing anyway.") if args.verify_image: if not is_docker_image_already_in_registry(service, args.soa_dir, args.commit): raise ValueError( 'Failed to find image in the registry for the following sha %s' % args.commit) ret = mark_for_deployment( git_url=args.git_url, deploy_group=args.deploy_group, service=service, commit=args.commit, ) if args.block and ret == 0: try: wait_for_deployment( service=service, deploy_group=args.deploy_group, git_sha=args.commit, soa_dir=args.soa_dir, timeout=args.timeout, ) line = "Deployment of {} for {} complete".format( args.commit, args.deploy_group) _log( service=service, component='deploy', line=line, level='event', ) except (KeyboardInterrupt, TimeoutError): if args.auto_rollback is True: if old_git_sha == args.commit: paasta_print( "Error: --auto-rollback was requested, but the previous sha" ) paasta_print( "is the same that was requested with --commit. Can't rollback" ) paasta_print("automatically.") else: paasta_print( "Auto-Rollback requested. Marking the previous sha") paasta_print("(%s) for %s as desired." % (args.deploy_group, old_git_sha)) mark_for_deployment( git_url=args.git_url, deploy_group=args.deploy_group, service=service, commit=old_git_sha, ) else: report_waiting_aborted(service, args.deploy_group) ret = 1 except NoSuchCluster: report_waiting_aborted(service, args.deploy_group) if old_git_sha is not None and old_git_sha != args.commit and not args.auto_rollback: paasta_print() paasta_print("If you wish to roll back, you can run:") paasta_print() paasta_print( PaastaColors.bold( " paasta rollback --service %s --deploy-group %s --commit %s " % ( service, args.deploy_group, old_git_sha, )), ) return ret
def paasta_mark_for_deployment(args): """Wrapping mark_for_deployment""" if args.verbose: log.setLevel(level=logging.DEBUG) else: log.setLevel(level=logging.INFO) service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service, soa_dir=args.soa_dir) deploy_group = args.deploy_group in_use_deploy_groups = list_deploy_groups( service=service, soa_dir=args.soa_dir, ) _, invalid_deploy_groups = validate_given_deploy_groups( in_use_deploy_groups, [deploy_group]) if len(invalid_deploy_groups) == 1: paasta_print( PaastaColors.red( "ERROR: These deploy groups are not currently used anywhere: %s.\n" % (",").join(invalid_deploy_groups), )) paasta_print( PaastaColors.red( "This isn't technically wrong because you can mark-for-deployment before deploying there", )) paasta_print( PaastaColors.red( "but this is probably a typo. Did you mean one of these in-use deploy groups?:" )) paasta_print( PaastaColors.red(" %s" % (",").join(in_use_deploy_groups))) paasta_print() paasta_print(PaastaColors.red("Continuing regardless...")) if args.git_url is None: args.git_url = get_git_url(service=service, soa_dir=args.soa_dir) commit = validate_git_sha(sha=args.commit, git_url=args.git_url) old_git_sha = get_currently_deployed_sha(service=service, deploy_group=deploy_group) if old_git_sha == commit: paasta_print( "Warning: The sha asked to be deployed already matches what is set to be deployed:" ) paasta_print(old_git_sha) paasta_print("Continuing anyway.") if args.verify_image: if not is_docker_image_already_in_registry(service, args.soa_dir, commit): raise ValueError( 'Failed to find image in the registry for the following sha %s' % commit) deploy_info = get_deploy_info(service=service, soa_dir=args.soa_dir) slack_notifier = SlackDeployNotifier( deploy_info=deploy_info, service=service, deploy_group=deploy_group, commit=commit, old_commit=old_git_sha, git_url=args.git_url, ) ret = mark_for_deployment( git_url=args.git_url, deploy_group=deploy_group, service=service, commit=commit, ) slack_notifier.notify_after_mark(ret=ret) if args.block and ret == 0: try: wait_for_deployment( service=service, deploy_group=deploy_group, git_sha=commit, soa_dir=args.soa_dir, timeout=args.timeout, ) line = f"Deployment of {commit} for {deploy_group} complete" _log( service=service, component='deploy', line=line, level='event', ) slack_notifier.notify_after_good_deploy() except (KeyboardInterrupt, TimeoutError): if args.auto_rollback is True: if old_git_sha == commit: paasta_print( "Error: --auto-rollback was requested, but the previous sha" ) paasta_print( "is the same that was requested with --commit. Can't rollback" ) paasta_print("automatically.") else: paasta_print( "Auto-Rollback requested. Marking the previous sha") paasta_print( f"({deploy_group}) for {old_git_sha} as desired.") mark_for_deployment( git_url=args.git_url, deploy_group=deploy_group, service=service, commit=old_git_sha, ) slack_notifier.notify_after_auto_rollback() else: report_waiting_aborted(service, deploy_group) slack_notifier.notify_after_abort() ret = 1 except NoSuchCluster: report_waiting_aborted(service, deploy_group) slack_notifier.notify_after_abort() if old_git_sha is not None and old_git_sha != commit and not args.auto_rollback: paasta_print() paasta_print("If you wish to roll back, you can run:") paasta_print() paasta_print( PaastaColors.bold( " paasta rollback --service {} --deploy-group {} --commit {} " .format( service, deploy_group, old_git_sha, )), ) return ret
def paasta_mark_for_deployment(args): """Wrapping mark_for_deployment""" if args.verbose: log.setLevel(level=logging.DEBUG) else: log.setLevel(level=logging.INFO) service = args.service if service and service.startswith("services-"): service = service.split("services-", 1)[1] validate_service_name(service, soa_dir=args.soa_dir) deploy_group = args.deploy_group in_use_deploy_groups = list_deploy_groups(service=service, soa_dir=args.soa_dir) _, invalid_deploy_groups = validate_given_deploy_groups( in_use_deploy_groups, [deploy_group] ) if len(invalid_deploy_groups) == 1: paasta_print( PaastaColors.red( "ERROR: These deploy groups are not currently used anywhere: %s.\n" % (",").join(invalid_deploy_groups) ) ) paasta_print( PaastaColors.red( "This isn't technically wrong because you can mark-for-deployment before deploying there" ) ) paasta_print( PaastaColors.red( "but this is probably a typo. Did you mean one of these in-use deploy groups?:" ) ) paasta_print(PaastaColors.red(" %s" % (",").join(in_use_deploy_groups))) paasta_print() paasta_print(PaastaColors.red("Continuing regardless...")) if args.git_url is None: args.git_url = get_git_url(service=service, soa_dir=args.soa_dir) commit = validate_git_sha(sha=args.commit, git_url=args.git_url) old_git_sha = get_currently_deployed_sha(service=service, deploy_group=deploy_group) if old_git_sha == commit: paasta_print( "Warning: The sha asked to be deployed already matches what is set to be deployed:" ) paasta_print(old_git_sha) paasta_print("Continuing anyway.") if args.verify_image: if not is_docker_image_already_in_registry(service, args.soa_dir, commit): raise ValueError( "Failed to find image in the registry for the following sha %s" % commit ) deploy_info = get_deploy_info(service=service, soa_dir=args.soa_dir) deploy_process = MarkForDeploymentProcess( service=service, deploy_info=deploy_info, deploy_group=deploy_group, commit=commit, old_git_sha=old_git_sha, git_url=args.git_url, auto_rollback=args.auto_rollback, block=args.block, soa_dir=args.soa_dir, timeout=args.timeout, auto_certify_delay=args.auto_certify_delay, auto_abandon_delay=args.auto_abandon_delay, auto_rollback_delay=args.auto_rollback_delay, ) ret = deploy_process.run() return ret