Exemplo n.º 1
0
    def do_provision(self, token, instance_id):
        pbclient = PBClient(token,
                            self.config['INTERNAL_API_BASE_URL'],
                            ssl_verify=False)

        log_uploader = self.create_prov_log_uploader(token,
                                                     instance_id,
                                                     log_type='provisioning')

        self.logger.info('faking provisioning')
        log_uploader.info('dummy provisioning for 5 seconds\n')
        time.sleep(5)
        log_uploader.info('dummy provisioning completed\n')

        public_ip = '%s.%s.%s.%s' % (randint(1, 254), randint(
            1, 254), randint(1, 254), randint(1, 254))
        instance_data = {
            'endpoints': [
                {
                    'name': 'SSH',
                    'access': 'ssh cloud-user@%s' % public_ip
                },
                {
                    'name': 'Some Web Interface',
                    'access': 'http://%s/service-x' % public_ip
                },
            ]
        }
        pbclient.do_instance_patch(instance_id, {
            'public_ip': public_ip,
            'instance_data': json.dumps(instance_data)
        })
Exemplo n.º 2
0
    def do_update_connectivity(self, token, instance_id):
        oss = self.get_oss()
        pbclient = PBClient(token,
                            self.config['INTERNAL_API_BASE_URL'],
                            ssl_verify=False)
        instance = pbclient.get_instance_description(instance_id)
        instance_data = instance['instance_data']
        security_group_id = instance_data['security_group_id']

        blueprint_config = pbclient.get_blueprint_description(
            instance['blueprint_id'])
        config = blueprint_config['config']

        # Delete all existing rules and add the rules using the input port string
        oss.clear_security_group_rules(security_group_id)

        ports_str = config['exposed_ports']
        if not ports_str:
            ports_str = '22'  # If the input port string is empty then use 22 as the default port
        ports_list = parse_ports_string(ports_str)

        for ports in ports_list:
            from_port = ports[0]
            to_port = ports[1]

            oss.create_security_group_rule(security_group_id,
                                           from_port=from_port,
                                           to_port=to_port,
                                           cidr="%s/32" %
                                           instance['client_ip'],
                                           ip_protocol='tcp',
                                           group_id=None)
Exemplo n.º 3
0
def get_provisioning_type(token, instance_id):
    """ gets the name of the plugin (driver) that an instance uses.
    """
    pbclient = PBClient(token, local_config['INTERNAL_API_BASE_URL'], ssl_verify=False)

    blueprint = pbclient.get_instance_parent_data(instance_id)
    plugin_id = blueprint['plugin']
    return pbclient.get_plugin_data(plugin_id)['name']
Exemplo n.º 4
0
 def get_pb_client(token, api_base_url, ssl_verify):
     """
     Get a custom client for interacting with external REST APIs
     Parameters:
     token - the authentication token required by the api
     api_base_url - the base url for the api
     ssl_verify . flag to check SSL certificates on the api requests
     """
     return PBClient(token, api_base_url, ssl_verify)
Exemplo n.º 5
0
def get_config():
    """
    Retrieve dynamic config over ReST API. Config object from Flask is unable to resolve variables from
    database if containers are used. In order to use the ReST API some configuration items
    (Variable.filtered_variables) are required. These are read from Flask config object, as these values
    cannot be modified during the runtime.
    """
    token = get_token()
    pbclient = PBClient(token,
                        local_config['INTERNAL_API_BASE_URL'],
                        ssl_verify=False)

    return dict([(x['key'], x['value'])
                 for x in pbclient.do_get('variables').json()])
Exemplo n.º 6
0
    def update(self, token, instance_id):
        """ an update call  updates the status of an instance.

        If an instance is queued it will be provisioned, if should be deleted,
        it is.
        """
        self.logger.debug("update('%s')" % instance_id)

        pbclient = PBClient(token, self.config['INTERNAL_API_BASE_URL'], ssl_verify=False)
        instance = pbclient.get_instance(instance_id)
        if not instance['to_be_deleted'] and instance['state'] in [Instance.STATE_QUEUEING]:
            self.provision(token, instance_id)
        elif instance['to_be_deleted'] and instance['state'] not in [Instance.STATE_DELETED]:
            self.deprovision(token, instance_id)
        else:
            self.logger.debug("update('%s') - nothing to do for %s" % (instance_id, instance))
Exemplo n.º 7
0
    def deprovision(self, token, instance_id):
        self.logger.debug('starting deprovisioning')
        pbclient = PBClient(token, self.config['INTERNAL_API_BASE_URL'], ssl_verify=False)

        try:
            pbclient.do_instance_patch(instance_id, {'state': Instance.STATE_DELETING})
            self.logger.debug('calling subclass do_deprovision')
            self.do_deprovision(token, instance_id)

            self.logger.debug('finishing deprovisioning')
            pbclient.do_instance_patch(instance_id, {'deprovisioned_at': datetime.datetime.utcnow()})
            pbclient.do_instance_patch(instance_id, {'state': Instance.STATE_DELETED})
        except Exception as e:
            self.logger.exception('do_deprovision raised %s' % e)
            pbclient.do_instance_patch(instance_id, {'state': Instance.STATE_FAILED})
            raise e
Exemplo n.º 8
0
def periodic_update():
    """ Runs periodic updates.

    In particular sets old instances up for deprovisioning after they are past
    their maximum_lifetime and sets instances up for up updates.

    Both deletion and update events are not guaranteed to take place
    immediately. If there are more than 10 instances a random sample of 10
    updates and deletions will take place to ensure task is safe to run and
    won't slow down other tasks.
    """
    token = get_token()
    pbclient = PBClient(token,
                        local_config['INTERNAL_API_BASE_URL'],
                        ssl_verify=False)
    instances = pbclient.get_instances()

    deprovision_list = []
    update_list = []
    for instance in instances:
        logger.debug('checking instance for actions %s' % instance['name'])
        deprovision_required = False
        if instance.get('state') in [Instance.STATE_RUNNING]:
            if not instance.get('lifetime_left') and instance.get(
                    'maximum_lifetime'):
                deprovision_required = True

            if deprovision_required:
                deprovision_list.append(instance)

        elif instance.get('state') not in [Instance.STATE_FAILED]:
            update_list.append(instance)

    # ToDo: refactor magic number to variable
    if len(deprovision_list) > 10:
        deprovision_list = random.sample(deprovision_list, 10)
    for instance in deprovision_list:
        logger.info(
            'deprovisioning triggered for %s (reason: maximum lifetime exceeded)'
            % instance.get('id'))
        pbclient.do_instance_patch(instance['id'], {'to_be_deleted': True})
        run_update.delay(instance.get('id'))

    if len(update_list) > 10:
        update_list = random.sample(update_list, 10)
    for instance in update_list:
        run_update.delay(instance.get('id'))
Exemplo n.º 9
0
    def provision(self, token, instance_id):
        self.logger.debug('starting provisioning')
        pbclient = PBClient(token, self.config['INTERNAL_API_BASE_URL'], ssl_verify=False)

        try:
            pbclient.do_instance_patch(instance_id, {'state': Instance.STATE_PROVISIONING})
            self.logger.debug('calling subclass do_provision')

            new_state = self.do_provision(token, instance_id)
            if not new_state:
                new_state = Instance.STATE_RUNNING

            pbclient.do_instance_patch(instance_id, {'state': new_state})
        except Exception as e:
            self.logger.exception('do_provision raised %s' % e)
            pbclient.do_instance_patch(instance_id, {'state': Instance.STATE_FAILED})
            raise e
Exemplo n.º 10
0
    def do_deprovision(self, token, instance_id):
        pbclient = PBClient(token, self.config['INTERNAL_API_BASE_URL'], ssl_verify=False)

        instance = pbclient.get_instance_description(instance_id)
        cluster_name = instance['name']

        instance_dir = '%s/%s' % (self.config['INSTANCE_DATA_DIR'], cluster_name)

        log_uploader = self.create_prov_log_uploader(token, instance_id, log_type='deprovisioning')

        self.logger.info('faking deprovisioning\n')
        log_uploader.info('dummy deprovisioning for 5 seconds\n')
        time.sleep(5)
        log_uploader.info('dummy deprovisioning completed\n')

        # use instance id as a part of the name to make tombstones always unique
        if os.path.isdir(instance_dir):
            os.rename(instance_dir, '%s.deleted.%s' % (instance_dir, instance_id))
Exemplo n.º 11
0
    def do_deprovision(self, token, instance_id):
        log_uploader = self.create_prov_log_uploader(token,
                                                     instance_id,
                                                     log_type='deprovisioning')
        log_uploader.info("Deprovisioning instance %s\n" % instance_id)
        pbclient = PBClient(token,
                            self.config['INTERNAL_API_BASE_URL'],
                            ssl_verify=False)
        oss = self.get_oss()
        instance = pbclient.get_instance_description(instance_id)
        instance_data = instance['instance_data']
        if 'server_id' not in instance_data:
            log_uploader.info("Skipping, no server id in instance data")
            return

        server_id = instance_data['server_id']

        log_uploader.info("Destroying server instance . . ")
        oss.deprovision_instance(server_id)
        log_uploader.info("Deprovisioning ready\n")
Exemplo n.º 12
0
    def do_provision(self, token, instance_id):
        self.logger.debug("do_provision %s" % instance_id)

        pbclient = PBClient(token,
                            self.config['INTERNAL_API_BASE_URL'],
                            ssl_verify=False)
        instance = pbclient.get_instance_description(instance_id)

        instance_name = instance['name']
        instance_user = instance['user_id']

        # fetch config
        blueprint_config = pbclient.get_blueprint_description(
            instance['blueprint_id'])
        config = blueprint_config['config']

        log_uploader = self.create_prov_log_uploader(token,
                                                     instance_id,
                                                     log_type='provisioning')
        log_uploader.info("Provisioning OpenStack instance (%s)\n" %
                          instance_id)

        ports_str = config['exposed_ports']
        if ports_str:
            try:
                parse_ports_string(ports_str)
            except:
                error = 'Incorrect exposed ports definition in blueprint'
                error_body = {
                    'state': Instance.STATE_FAILED,
                    'error_msg': error
                }
                pbclient.do_instance_patch(instance_id, error_body)
                self.logger.debug(error)
                raise RuntimeError(error)

        # fetch user public key
        key_data = pbclient.get_user_key_data(instance_user).json()
        if not key_data:
            error = 'user\'s public key is missing'
            error_body = {'state': Instance.STATE_FAILED, 'error_msg': error}
            pbclient.do_instance_patch(instance_id, error_body)
            self.logger.debug(error)
            raise RuntimeError(error)

        oss = self.get_oss()

        result = oss.provision_instance(instance_name,
                                        config['image'],
                                        config['flavor'],
                                        public_key=key_data[0]['public_key'],
                                        userdata=config.get('userdata'))

        if 'error' in result:
            log_uploader.warn('Provisioning failed %s' % result['error'])
            return

        ip = result['address_data']['public_ip']
        instance_data = {
            'server_id': result['server_id'],
            'floating_ip': ip,
            'allocated_from_pool':
            result['address_data']['allocated_from_pool'],
            'security_group_id': result['security_group'],
            'endpoints': [
                {
                    'name': 'SSH',
                    'access': 'ssh cloud-user@%s' % ip
                },
            ]
        }
        log_uploader.info("Publishing server data\n")
        pbclient.do_instance_patch(instance_id, {
            'instance_data': json.dumps(instance_data),
            'public_ip': ip
        })
        log_uploader.info("Provisioning complete\n")
Exemplo n.º 13
0
 def get_pb_client(token, api_base_url, ssl_verify):
     return PBClient(token, api_base_url, ssl_verify)