def test_return_immediately_if_deployment_is_successful(self):
        get_deployment_state_mock = MagicMock(side_effect=[
            self.create_deployment_state('deploymentSuccess'),
        ])
        url_mock = MagicMock(return_value='/deployments/events')
        conductr_host = '10.0.0.1'
        conductr_host_mock = MagicMock(return_value=conductr_host)
        get_events_mock = MagicMock()

        stdout = MagicMock()

        deployment_id = 'a101449418187d92c789d1adc240b6d6'
        resolved_version = {
            'org': 'typesafe',
            'repo': 'bundle',
            'package_name': 'cassandra',
            'compatibility_version': 'v1',
            'digest': 'abcdef',
            'resolver': bintray_resolver.__name__
        }
        dcos_mode = False
        args = MagicMock(
            **{
                'dcos_mode': dcos_mode,
                'long_ids': False,
                'wait_timeout': 10,
                'conductr_auth': self.conductr_auth,
                'server_verification_file': self.server_verification_file
            })
        with patch('conductr_cli.conduct_url.url', url_mock), \
                patch('conductr_cli.conduct_url.conductr_host', conductr_host_mock), \
                patch('conductr_cli.bundle_deploy.get_deployment_state', get_deployment_state_mock), \
                patch('conductr_cli.sse_client.get_events', get_events_mock):
            logging_setup.configure_logging(args, stdout)
            bundle_deploy.wait_for_deployment_complete(deployment_id,
                                                       resolved_version, args)

        self.assertEqual(get_deployment_state_mock.call_args_list,
                         [call(deployment_id, args)])

        url_mock.assert_not_called()

        conductr_host_mock.assert_not_called()

        get_events_mock.assert_not_called()

        self.assertEqual(stdout.method_calls, [
            call.write('Deploying cassandra:v1-abcdef'),
            call.write('\n'),
            call.flush(),
            call.write('Success'),
            call.write('\n'),
            call.flush()
        ])
Beispiel #2
0
def deploy(args):
    """`conduct deploy` command"""

    log = logging.getLogger(__name__)

    bintray_webhook_secret = custom_settings.load_bintray_webhook_secret(args)
    if not bintray_webhook_secret:
        log.error(
            'The deploy command requires bintray webhook secret to be configured'
        )
        log.error('Add the following configuration to the '
                  'custom settings file {}'.format(
                      vars(args).get('custom_settings_file')))
        log.error(
            '  conductr.continuous-delivery.bintray-webhook-secret = "configured-continuous-delivery-secret"'
        )
        return

    resolved_version = resolver.resolve_bundle_version(args.custom_settings,
                                                       args.bundle)
    if not resolved_version:
        log.error('Unable to resolve bundle {}'.format(args.bundle))
        return

    # Build Continuous Delivery URL using our resolver mechanism
    deploy_uri = resolver.continuous_delivery_uri(args.custom_settings,
                                                  resolved_version)
    if not deploy_uri:
        log.error('Unable to form Continuous Delivery uri for {}'.format(
            args.bundle))
        return

    # Confirm with the user unless auto deploy is enabled
    accepted = True if args.auto_deploy else request_deploy_confirmation(
        resolved_version, args)
    if not accepted:
        log.info('Abort')
        return

    url = conduct_url.url(deploy_uri, args)

    # JSON Payload for deployment request
    payload = {
        'package':
        resolved_version['package_name'],
        'version':
        '{}-{}'.format(resolved_version['compatibility_version'],
                       resolved_version['digest'])
    }

    # HTTP headers required for deployment request
    hmac_digest = bundle_deploy.generate_hmac_signature(
        bintray_webhook_secret, resolved_version['package_name'])
    headers = {'X-Bintray-WebHook-Hmac': hmac_digest}

    response = conduct_request.post(args.dcos_mode,
                                    conductr_host(args),
                                    url,
                                    json=payload,
                                    headers=headers,
                                    auth=args.conductr_auth,
                                    verify=args.server_verification_file)

    validation.raise_for_status_inc_3xx(response)

    deployment_id = response.text

    log.info('Deployment request sent.')
    log.info('Deployment id {}'.format(deployment_id))

    if not args.no_wait:
        bundle_deploy.wait_for_deployment_complete(deployment_id,
                                                   resolved_version, args)

    return True
Beispiel #3
0
def deploy(args):
    """`conduct deploy` command"""

    log = logging.getLogger(__name__)

    bintray_webhook_secret = custom_settings.load_bintray_webhook_secret(args)
    if not bintray_webhook_secret:
        log.error('The deploy command requires bintray webhook secret to be configured')
        log.error('Add the following configuration to the '
                  'custom settings file {}'.format(vars(args).get('custom_settings_file')))
        log.error('  conductr.continuous-delivery.bintray-webhook-secret = "configured-continuous-delivery-secret"')
        return

    resolved_version = resolver.resolve_bundle_version(args.custom_settings, args.bundle)
    if not resolved_version:
        log.error('Unable to resolve bundle {}'.format(args.bundle))
        return

    # Build Continuous Delivery URL using our resolver mechanism
    deploy_uri = resolver.continuous_delivery_uri(args.custom_settings, resolved_version)
    if not deploy_uri:
        log.error('Unable to form Continuous Delivery uri for {}'.format(args.bundle))
        return

    # Confirm with the user unless auto deploy is enabled
    accepted = True if args.auto_deploy else request_deploy_confirmation(resolved_version, args)
    if not accepted:
        log.info('Abort')
        return

    url = conduct_url.url(deploy_uri, args)

    # JSON Payload for deployment request
    payload = {
        'package': resolved_version['package_name'],
        'version': '{}-{}'.format(resolved_version['compatibility_version'], resolved_version['digest'])
    }

    # HTTP headers required for deployment request
    hmac_digest = bundle_deploy.generate_hmac_signature(bintray_webhook_secret, resolved_version['package_name'])
    headers = {
        'X-Bintray-WebHook-Hmac': hmac_digest
    }

    response = conduct_request.post(args.dcos_mode, conductr_host(args), url,
                                    json=payload,
                                    headers=headers,
                                    auth=args.conductr_auth,
                                    verify=args.server_verification_file)

    validation.raise_for_status_inc_3xx(response)

    deployment_id = response.text

    log.info('Deployment request sent.')
    log.info('Deployment id {}'.format(deployment_id))

    if not args.no_wait:
        bundle_deploy.wait_for_deployment_complete(deployment_id, resolved_version, args)

    return True
    def test_wait_for_deployment_with_initial_deployment_not_found(self):
        get_deployment_state_mock = MagicMock(side_effect=[
            None,
            self.create_deployment_state('deploymentStarted'),
            self.create_deployment_state('bundleDownload'),
            self.create_deployment_state(
                'configDownload', {
                    'compatibleBundleId':
                    'abf60451c6af18adcc851d67b369b7f5-a53237c1f4a067e13ef00090627fb3de'
                }),
            self.create_deployment_state(
                'load', {'configFileName': 'cassandra-prod-config.zip'}),
            self.create_deployment_state('deploy', {
                'bundleOld': {
                    'scale': 1
                },
                'bundleNew': {
                    'scale': 0
                }
            }),
            self.create_deployment_state('deploy', {
                'bundleOld': {
                    'scale': 0
                },
                'bundleNew': {
                    'scale': 1
                }
            }),
            self.create_deployment_state('deploymentSuccess'),
        ])
        url_mock = MagicMock(return_value='/deployments/events')
        conductr_host = '10.0.0.1'
        conductr_host_mock = MagicMock(return_value=conductr_host)
        get_events_mock = MagicMock(return_value=[
            self.create_test_event(None),
            self.create_test_event('deploymentStarted'),
            self.create_test_event(None),
            self.create_test_event('bundleDownload'),
            self.create_test_event(None),
            self.create_test_event(None),
            self.create_test_event(None),
            self.create_test_event('configDownload'),
            self.create_test_event('load'),
            self.create_test_event(None),
            self.create_test_event('deploy'),
            self.create_test_event(None),
            self.create_test_event(None),
            self.create_test_event(None),
            self.create_test_event('deploy'),
            self.create_test_event(None),
            self.create_test_event(None),
            self.create_test_event(None),
            self.create_test_event(None),
            self.create_test_event('deploymentSuccess')
        ])

        stdout = MagicMock()

        deployment_id = 'a101449418187d92c789d1adc240b6d6'
        resolved_version = {
            'org': 'typesafe',
            'repo': 'bundle',
            'package_name': 'cassandra',
            'compatibility_version': 'v1',
            'digest': 'abcdef',
            'resolver': bintray_resolver.__name__
        }
        dcos_mode = False
        args = MagicMock(
            **{
                'dcos_mode': dcos_mode,
                'long_ids': False,
                'wait_timeout': 10,
                'conductr_auth': self.conductr_auth,
                'server_verification_file': self.server_verification_file
            })
        with patch('conductr_cli.conduct_url.url', url_mock), \
                patch('conductr_cli.conduct_url.conductr_host', conductr_host_mock), \
                patch('conductr_cli.bundle_deploy.get_deployment_state', get_deployment_state_mock), \
                patch('conductr_cli.sse_client.get_events', get_events_mock):
            logging_setup.configure_logging(args, stdout)
            bundle_deploy.wait_for_deployment_complete(deployment_id,
                                                       resolved_version, args)

        self.assertEqual(get_deployment_state_mock.call_args_list, [
            call(deployment_id, args),
            call(deployment_id, args),
            call(deployment_id, args),
            call(deployment_id, args),
            call(deployment_id, args),
            call(deployment_id, args),
            call(deployment_id, args),
            call(deployment_id, args)
        ])

        url_mock.assert_called_with('deployments/events', args)

        conductr_host_mock.assert_called_with(args)

        get_events_mock.assert_called_with(
            dcos_mode,
            conductr_host,
            '/deployments/events',
            auth=self.conductr_auth,
            verify=self.server_verification_file)

        self.assertEqual(stdout.method_calls, [
            call.write('Deploying cassandra:v1-abcdef'),
            call.write('\n'),
            call.flush(),
            call.write('Deployment started\r'),
            call.write(''),
            call.flush(),
            call.write('Deployment started\n'),
            call.write(''),
            call.flush(),
            call.write('Downloading bundle\r'),
            call.write(''),
            call.flush(),
            call.write('Downloading bundle\n'),
            call.write(''),
            call.flush(),
            call.write('Downloading config from bundle abf6045-a53237c\r'),
            call.write(''),
            call.flush(),
            call.write('Downloading config from bundle abf6045-a53237c\n'),
            call.write(''),
            call.flush(),
            call.write('Loading bundle with config\r'),
            call.write(''),
            call.flush(),
            call.write('Loading bundle with config\n'),
            call.write(''),
            call.flush(),
            call.write('Deploying - 1 old instance vs 0 new instance\r'),
            call.write(''),
            call.flush(),
            call.write('Deploying - 1 old instance vs 0 new instance\n'),
            call.write(''),
            call.flush(),
            call.write('Deploying - 0 old instance vs 1 new instance\r'),
            call.write(''),
            call.flush(),
            call.write('Deploying - 0 old instance vs 1 new instance\n'),
            call.write(''),
            call.flush(),
            call.write('Success'),
            call.write('\n'),
            call.flush()
        ])