Exemplo n.º 1
0
def _get_amqp_client(agent):
    delete_cert_path = False
    if agent.get('broker_config'):
        broker_config = agent['broker_config']
        ssl_cert_path = _get_ssl_cert_path(broker_config)
        # Using a temp path, so we need to delete it
        delete_cert_path = True
    else:
        broker_config = _get_broker_config(agent)
        ssl_cert_path = get_local_rest_certificate()

    tenant = get_tenant()
    try:
        yield amqp_client.get_client(
            amqp_host=broker_config.get('broker_ip'),
            amqp_user=tenant.get('rabbitmq_username'),
            amqp_port=broker_config.get('broker_port'),
            amqp_pass=tenant.get('rabbitmq_password'),
            amqp_vhost=tenant.get('rabbitmq_vhost'),
            ssl_enabled=broker_config.get('broker_ssl_enabled'),
            ssl_cert_path=ssl_cert_path
        )
    finally:
        if delete_cert_path and ssl_cert_path:
            os.remove(ssl_cert_path)
Exemplo n.º 2
0
def start(cloudify_agent, **_):
    """
    Only called in "init_script"/"plugin" mode, where the agent is started
    externally (e.g. userdata script), and all we have to do is wait for it
    """
    update_agent_record(cloudify_agent, AgentState.STARTING)
    tenant = cloudify_utils.get_tenant()
    client = get_client(
        amqp_user=tenant['rabbitmq_username'],
        amqp_pass=tenant['rabbitmq_password'],
        amqp_vhost=tenant['rabbitmq_vhost']
    )
    agent_alive = utils.is_agent_alive(cloudify_agent['queue'], client)

    if not agent_alive:
        if ctx.operation.retry_number > 3:
            ctx.logger.warning('Waiting too long for Agent to start')
            update_agent_record(cloudify_agent, AgentState.NONRESPONSIVE)
        return ctx.operation.retry(
            message='Waiting for Agent to start...')

    ctx.logger.info('Agent has started')
    update_agent_record(cloudify_agent, AgentState.STARTED)
    if not cloudify_agent.is_provided:
        script.cleanup_scripts()
Exemplo n.º 3
0
def restart(new_name=None, delay_period=5, **_):

    cloudify_agent = ctx.instance.runtime_properties['cloudify_agent']
    if new_name is None:
        new_name = utils.internal.generate_new_agent_name(
            cloudify_agent.get('name', 'agent'))

    # update agent name in runtime properties so that the workflow will
    # what the name of the worker handling tasks to this instance.
    # the update cannot be done by setting a nested property directly
    # because they are not recognized as 'dirty'
    cloudify_agent['name'] = new_name
    update_agent_runtime_properties(cloudify_agent)

    daemon = _load_daemon(logger=ctx.logger)

    # make the current master stop listening to the current queue
    # to avoid a situation where we have two masters listening on the
    # same queue.
    rest_tenant = get_tenant()
    app = get_celery_app(tenant=rest_tenant)
    app.control.cancel_consumer(
        queue=daemon.queue,
        destination=['celery@{0}'.format(daemon.name)]
    )

    # clone the current daemon to preserve all the attributes
    attributes = utils.internal.daemon_to_dict(daemon)

    # give the new daemon the new name
    attributes['name'] = new_name

    # remove the log file and pid file so that new ones will be created
    # for the new agent
    del attributes['log_file']
    del attributes['pid_file']

    # Get the broker credentials for the daemon
    attributes.update(ctx.bootstrap_context.broker_config())

    new_daemon = DaemonFactory().new(logger=ctx.logger, **attributes)

    # create the new daemon
    new_daemon.create()
    _save_daemon(new_daemon)

    # configure the new daemon
    new_daemon.configure()
    new_daemon.start()

    # start a thread that will kill the current master.
    # this is done in a thread so that the current task will not result in
    # a failure
    thread = threading.Thread(target=shutdown_current_master,
                              args=[delay_period, ctx.logger])
    thread.daemon = True
    thread.start()
Exemplo n.º 4
0
    def tenant(self):
        """Full Cloudify tenant.

        This will go out to the REST API and fetch all the tenant details
        that the current user is allowed to obtain.
        """
        if self._tenant is None:
            self._tenant = self._context.get('tenant', {}).copy()
            self._tenant.update(utils.get_tenant())
        return self._tenant
Exemplo n.º 5
0
def restart(new_name=None, delay_period=5, **_):

    cloudify_agent = ctx.instance.runtime_properties['cloudify_agent']
    if new_name is None:
        new_name = utils.internal.generate_new_agent_name(
            cloudify_agent.get('name', 'agent'))

    # update agent name in runtime properties so that the workflow will
    # what the name of the worker handling tasks to this instance.
    # the update cannot be done by setting a nested property directly
    # because they are not recognized as 'dirty'
    cloudify_agent['name'] = new_name
    update_agent_runtime_properties(cloudify_agent)

    daemon = _load_daemon(logger=ctx.logger)

    # make the current master stop listening to the current queue
    # to avoid a situation where we have two masters listening on the
    # same queue.
    rest_tenant = get_tenant()
    app = get_celery_app(tenant=rest_tenant)
    app.control.cancel_consumer(queue=daemon.queue,
                                destination=['celery@{0}'.format(daemon.name)])

    # clone the current daemon to preserve all the attributes
    attributes = utils.internal.daemon_to_dict(daemon)

    # give the new daemon the new name
    attributes['name'] = new_name

    # remove the log file and pid file so that new ones will be created
    # for the new agent
    del attributes['log_file']
    del attributes['pid_file']

    # Get the broker credentials for the daemon
    attributes.update(ctx.bootstrap_context.broker_config())

    new_daemon = DaemonFactory().new(logger=ctx.logger, **attributes)

    # create the new daemon
    new_daemon.create()
    _save_daemon(new_daemon)

    # configure the new daemon
    new_daemon.configure()
    new_daemon.start()

    # start a thread that will kill the current master.
    # this is done in a thread so that the current task will not result in
    # a failure
    thread = threading.Thread(target=shutdown_current_master,
                              args=[delay_period, ctx.logger])
    thread.daemon = True
    thread.start()
Exemplo n.º 6
0
 def set_default_values(self):
     self._set_process_management()
     self._set_name()
     self._set_network()
     self.setdefault('queue', self['name'])
     self.setdefault('rest_token', cloudify_utils.get_rest_token())
     self.setdefault('rest_tenant', cloudify_utils.get_tenant())
     self.setdefault('rest_port',
                     cloudify_utils.get_manager_rest_service_port())
     self.setdefault('bypass_maintenance',
                     cloudify_utils.get_is_bypass_maintenance())
     self.setdefault('min_workers', 0)
     self.setdefault('max_workers', 5)
     self.setdefault('disable_requiretty', True)
     self.setdefault('env', {})
     self.setdefault('fabric_env', {})
     self.setdefault('system_python', 'python')
Exemplo n.º 7
0
def start(cloudify_agent, **_):
    """
    Only called in "init_script"/"plugin" mode, where the agent is started
    externally (e.g. userdata script), and all we have to do is wait for it
    """
    tenant = cloudify_utils.get_tenant()
    client = get_client(
        amqp_user=tenant['rabbitmq_username'],
        amqp_pass=tenant['rabbitmq_password'],
        amqp_vhost=tenant['rabbitmq_vhost']
    )
    agent_alive = utils.is_agent_alive(cloudify_agent['queue'], client)

    if not agent_alive:
        return ctx.operation.retry(
            message='Waiting for Agent to start...')

    ctx.logger.info('Agent has started')
    if not cloudify_agent.is_provided:
        script.cleanup_scripts()
Exemplo n.º 8
0
    def _send_cancel_task(self, target, execution_id):
        """Send a cancel-operation task to the agent given by `target`"""
        message = {
            'service_task': {
                'task_name': 'cancel-operation',
                'kwargs': {
                    'execution_id': execution_id
                }
            }
        }
        if target == MGMTWORKER_QUEUE:
            client = get_client()
        else:
            tenant = get_tenant()
            client = get_client(amqp_user=tenant['rabbitmq_username'],
                                amqp_pass=tenant['rabbitmq_password'],
                                amqp_vhost=tenant['rabbitmq_vhost'])

        handler = SendHandler(exchange=target, routing_key='service')
        client.add_handler(handler)
        with client:
            handler.publish(message)
Exemplo n.º 9
0
def start(cloudify_agent, **_):
    """
    Only called in "init_script"/"plugin" mode, where the agent is started
    externally (e.g. userdata script), and all we have to do is wait for it
    """
    update_agent_record(cloudify_agent, AgentState.STARTING)
    tenant = cloudify_utils.get_tenant()
    client = get_client(amqp_user=tenant['rabbitmq_username'],
                        amqp_pass=tenant['rabbitmq_password'],
                        amqp_vhost=tenant['rabbitmq_vhost'])
    agent_alive = utils.is_agent_alive(cloudify_agent['queue'], client)

    if not agent_alive:
        if ctx.operation.retry_number > 3:
            ctx.logger.warning('Waiting too long for Agent to start')
            update_agent_record(cloudify_agent, AgentState.NONRESPONSIVE)
        return ctx.operation.retry(message='Waiting for Agent to start...')

    ctx.logger.info('Agent has started')
    update_agent_record(cloudify_agent, AgentState.STARTED)
    if not cloudify_agent.is_provided:
        script.cleanup_scripts()
Exemplo n.º 10
0
def _get_amqp_client(agent):
    delete_cert_path = False
    if agent.get('broker_config'):
        broker_config = agent['broker_config']
        ssl_cert_path = _get_ssl_cert_path(broker_config)
        # Using a temp path, so we need to delete it
        delete_cert_path = True
    else:
        broker_config = _get_broker_config(agent)
        ssl_cert_path = get_local_rest_certificate()

    tenant = get_tenant()
    try:
        yield amqp_client.get_client(
            amqp_host=broker_config.get('broker_ip'),
            amqp_user=tenant.get('rabbitmq_username'),
            amqp_port=broker_config.get('broker_port'),
            amqp_pass=tenant.get('rabbitmq_password'),
            amqp_vhost=tenant.get('rabbitmq_vhost'),
            ssl_enabled=broker_config.get('broker_ssl_enabled'),
            ssl_cert_path=ssl_cert_path)
    finally:
        if delete_cert_path and ssl_cert_path:
            os.remove(ssl_cert_path)
Exemplo n.º 11
0
    def _create_agent_env(self):
        # Try to get broker credentials from the tenant. If they aren't set
        # get them from the broker_config module
        tenant = get_tenant()
        tenant_name = tenant.get('name', defaults.DEFAULT_TENANT_NAME)
        broker_user = tenant.get('rabbitmq_username',
                                 broker_config.broker_username)
        broker_pass = tenant.get('rabbitmq_password',
                                 broker_config.broker_password)
        broker_vhost = tenant.get('rabbitmq_vhost', broker_config.broker_vhost)

        execution_env = {
            # mandatory values calculated before the agent
            # is actually created
            env.CLOUDIFY_DAEMON_QUEUE:
            self.cloudify_agent['queue'],
            env.CLOUDIFY_DAEMON_NAME:
            self.cloudify_agent['name'],
            env.CLOUDIFY_REST_HOST:
            self.cloudify_agent['rest_host'],
            env.CLOUDIFY_BROKER_IP:
            self.cloudify_agent['broker_ip'],

            # Optional broker values
            env.CLOUDIFY_BROKER_USER:
            broker_user,
            env.CLOUDIFY_BROKER_PASS:
            broker_pass,
            env.CLOUDIFY_BROKER_VHOST:
            broker_vhost,
            env.CLOUDIFY_BROKER_SSL_ENABLED:
            broker_config.broker_ssl_enabled,
            env.CLOUDIFY_BROKER_SSL_CERT_PATH:
            self.cloudify_agent['broker_ssl_cert_path'],
            env.CLOUDIFY_HEARTBEAT:
            self.cloudify_agent.get('heartbeat'),

            # these are variables that have default values that will be set
            # by the agent on the remote host if not set here
            env.CLOUDIFY_DAEMON_USER:
            self.cloudify_agent.get('user'),
            env.CLOUDIFY_REST_PORT:
            self.cloudify_agent.get('rest_port'),
            env.CLOUDIFY_REST_TOKEN:
            get_rest_token(),
            env.CLOUDIFY_REST_TENANT:
            tenant_name,
            env.CLOUDIFY_DAEMON_MAX_WORKERS:
            self.cloudify_agent.get('max_workers'),
            env.CLOUDIFY_DAEMON_MIN_WORKERS:
            self.cloudify_agent.get('min_workers'),
            env.CLOUDIFY_DAEMON_PROCESS_MANAGEMENT:
            self.cloudify_agent['process_management']['name'],
            env.CLOUDIFY_DAEMON_WORKDIR:
            self.cloudify_agent['workdir'],
            env.CLOUDIFY_DAEMON_EXTRA_ENV:
            self.create_custom_env_file_on_target(
                self.cloudify_agent.get('env', {})),
            env.CLOUDIFY_BYPASS_MAINTENANCE_MODE:
            get_is_bypass_maintenance(),
            env.CLOUDIFY_LOCAL_REST_CERT_PATH:
            self.cloudify_agent['agent_rest_cert_path'],
            env.CLOUDIFY_CLUSTER_NODES:
            base64.b64encode(json.dumps(self.cloudify_agent.get('cluster',
                                                                []))),
            env.CLOUDIFY_NETWORK_NAME:
            self.cloudify_agent.get('network')
        }

        execution_env = utils.purge_none_values(execution_env)
        execution_env = utils.stringify_values(execution_env)

        self.logger.debug('Cloudify Agent will be created using the following '
                          'environment: {0}'.format(execution_env))

        return execution_env
Exemplo n.º 12
0
    def _create_agent_env(self):
        tenant = get_tenant()
        tenant_name = tenant.get('name', defaults.DEFAULT_TENANT_NAME)
        tenant_user = tenant.get('rabbitmq_username',
                                 broker_config.broker_username)
        tenant_pass = tenant.get('rabbitmq_password',
                                 broker_config.broker_password)
        broker_vhost = tenant.get('rabbitmq_vhost',
                                  broker_config.broker_vhost)
        # Get the agent's broker credentials
        broker_user = self.cloudify_agent.get('broker_user', tenant_user)
        broker_pass = self.cloudify_agent.get('broker_pass', tenant_pass)

        manager_ip = self.cloudify_agent.get_manager_ip()
        network = self.cloudify_agent.get('network')
        execution_env = {
            # mandatory values calculated before the agent
            # is actually created
            env.CLOUDIFY_DAEMON_QUEUE: self.cloudify_agent['queue'],
            env.CLOUDIFY_DAEMON_NAME: self.cloudify_agent['name'],
            env.CLOUDIFY_REST_HOST: manager_ip,
            env.CLOUDIFY_BROKER_IP: ','.join(
                broker.networks[network] for broker in
                ctx.get_brokers(network=network)
            ),

            # Optional broker values
            env.CLOUDIFY_BROKER_USER: broker_user,
            env.CLOUDIFY_BROKER_PASS: broker_pass,
            env.CLOUDIFY_BROKER_VHOST: broker_vhost,
            env.CLOUDIFY_BROKER_SSL_ENABLED: broker_config.broker_ssl_enabled,
            env.CLOUDIFY_BROKER_SSL_CERT_PATH: (
                self.cloudify_agent['broker_ssl_cert_path']
            ),
            env.CLOUDIFY_HEARTBEAT: (
                self.cloudify_agent.get('heartbeat')
            ),

            # these are variables that have default values that will be set
            # by the agent on the remote host if not set here
            env.CLOUDIFY_DAEMON_USER: self.cloudify_agent.get('user'),
            env.CLOUDIFY_REST_PORT: self.cloudify_agent.get('rest_port'),
            env.CLOUDIFY_REST_TOKEN: get_rest_token(),
            env.CLOUDIFY_REST_TENANT: tenant_name,
            env.CLOUDIFY_DAEMON_MAX_WORKERS: self.cloudify_agent.get(
                'max_workers'),
            env.CLOUDIFY_DAEMON_MIN_WORKERS: self.cloudify_agent.get(
                'min_workers'),
            env.CLOUDIFY_DAEMON_PROCESS_MANAGEMENT:
            self.cloudify_agent['process_management']['name'],
            env.CLOUDIFY_DAEMON_WORKDIR: self.cloudify_agent['workdir'],
            env.CLOUDIFY_DAEMON_EXTRA_ENV:
            self.create_custom_env_file_on_target(
                self.cloudify_agent.get('env', {})),
            env.CLOUDIFY_BYPASS_MAINTENANCE_MODE: get_is_bypass_maintenance(),
            env.CLOUDIFY_LOCAL_REST_CERT_PATH: (
                self.cloudify_agent['agent_rest_cert_path']
            ),
            env.CLOUDIFY_CLUSTER_NODES: base64.b64encode(json.dumps(
                self.cloudify_agent.get('cluster', []))),
            env.CLOUDIFY_NETWORK_NAME: network,
            ENV_CFY_EXEC_TEMPDIR: self.cloudify_agent.get(
                'executable_temp_path'),
            ENV_AGENT_LOG_LEVEL: self.cloudify_agent.get('log_level'),
            ENV_AGENT_LOG_MAX_BYTES: self.cloudify_agent.get('log_max_bytes'),
            ENV_AGENT_LOG_MAX_HISTORY: self.cloudify_agent.get(
                'log_max_history')
        }

        execution_env = utils.purge_none_values(execution_env)
        execution_env = utils.stringify_values(execution_env)

        self.logger.debug('Cloudify Agent will be created using the following '
                          'environment: {0}'.format(execution_env))

        return execution_env
Exemplo n.º 13
0
    def _create_agent_env(self):
        tenant = get_tenant()
        tenant_name = tenant.get('name', defaults.DEFAULT_TENANT_NAME)
        tenant_user = tenant.get('rabbitmq_username',
                                 broker_config.broker_username)
        tenant_pass = tenant.get('rabbitmq_password',
                                 broker_config.broker_password)
        broker_vhost = tenant.get('rabbitmq_vhost', broker_config.broker_vhost)
        # Get the agent's broker credentials
        broker_user = self.cloudify_agent.get('broker_user', tenant_user)
        broker_pass = self.cloudify_agent.get('broker_pass', tenant_pass)

        network = self.cloudify_agent.get('network')
        execution_env = {
            # mandatory values calculated before the agent
            # is actually created
            env.CLOUDIFY_DAEMON_QUEUE:
            self.cloudify_agent['queue'],
            env.CLOUDIFY_DAEMON_NAME:
            self.cloudify_agent['name'],
            env.CLOUDIFY_REST_HOST:
            ','.join(self.cloudify_agent['rest_host']),
            env.CLOUDIFY_BROKER_IP:
            ','.join(self.cloudify_agent['broker_ip']),

            # Optional broker values
            env.CLOUDIFY_BROKER_USER:
            broker_user,
            env.CLOUDIFY_BROKER_PASS:
            broker_pass,
            env.CLOUDIFY_BROKER_VHOST:
            broker_vhost,
            env.CLOUDIFY_BROKER_SSL_ENABLED:
            broker_config.broker_ssl_enabled,
            env.CLOUDIFY_BROKER_SSL_CERT_PATH:
            (self.cloudify_agent['broker_ssl_cert_path']),
            env.CLOUDIFY_HEARTBEAT: (self.cloudify_agent.get('heartbeat')),

            # these are variables that have default values that will be set
            # by the agent on the remote host if not set here
            env.CLOUDIFY_DAEMON_USER:
            self.cloudify_agent.get('user'),
            env.CLOUDIFY_REST_PORT:
            self.cloudify_agent.get('rest_port'),
            env.CLOUDIFY_REST_TOKEN:
            get_rest_token(),
            env.CLOUDIFY_REST_TENANT:
            tenant_name,
            env.CLOUDIFY_DAEMON_MAX_WORKERS:
            self.cloudify_agent.get('max_workers'),
            env.CLOUDIFY_DAEMON_MIN_WORKERS:
            self.cloudify_agent.get('min_workers'),
            env.CLOUDIFY_DAEMON_PROCESS_MANAGEMENT:
            self.cloudify_agent['process_management']['name'],
            env.CLOUDIFY_DAEMON_WORKDIR:
            self.cloudify_agent['workdir'],
            env.CLOUDIFY_DAEMON_EXTRA_ENV:
            self.create_custom_env_file_on_target(
                self.cloudify_agent.get('env', {})),
            env.CLOUDIFY_BYPASS_MAINTENANCE_MODE:
            get_is_bypass_maintenance(),
            env.CLOUDIFY_LOCAL_REST_CERT_PATH:
            (self.cloudify_agent['agent_rest_cert_path']),
            env.CLOUDIFY_NETWORK_NAME:
            network,
            ENV_CFY_EXEC_TEMPDIR:
            self.cloudify_agent.get('executable_temp_path'),
            ENV_AGENT_LOG_LEVEL:
            self.cloudify_agent.get('log_level'),
            ENV_AGENT_LOG_MAX_BYTES:
            self.cloudify_agent.get('log_max_bytes'),
            ENV_AGENT_LOG_MAX_HISTORY:
            self.cloudify_agent.get('log_max_history')
        }

        execution_env = utils.purge_none_values(execution_env)
        execution_env = utils.stringify_values(execution_env)

        self.logger.debug('Cloudify Agent will be created using the following '
                          'environment: {0}'.format(execution_env))

        return execution_env