def _cluster_to_basic_summary(cluster, now=None):
    if now is None:
        now = datetime.utcnow()

    bcs = {}  # basic cluster summary to fill in

    bcs['id'] = getattr(cluster, 'id', None)
    bcs['name'] = getattr(cluster, 'name', None)

    status = getattr(cluster, 'status', None)
    timeline = getattr(status, 'timeline', None)

    bcs['created'] = _to_datetime(getattr(
        timeline, 'creationdatetime', None))
    bcs['ready'] = _to_datetime(getattr(timeline, 'readydatetime', None))
    bcs['end'] = _to_datetime(getattr(timeline, 'enddatetime', None))

    if bcs['created']:
        bcs['ran'] = (bcs['end'] or now) - bcs['created']
    else:
        bcs['ran'] = timedelta(0)

    bcs['state'] = getattr(status, 'state', None)

    bcs['num_steps'] = len(getattr(cluster, 'steps', ()))

    bcs['pool'] = None
    bootstrap_actions = getattr(cluster, 'bootstrapactions', None)
    if bootstrap_actions:
        args = [arg.value for arg in bootstrap_actions[-1].args]
        if len(args) == 2 and args[0].startswith('pool-'):
            bcs['pool'] = args[1]

    m = _JOB_KEY_RE.match(bcs['name'] or '')
    if m:
        bcs['label'], bcs['owner'] = m.group(1), m.group(2)
    else:
        bcs['label'], bcs['owner'] = None, None

    bcs['nih'] = float(getattr(cluster, 'normalizedinstancehours', '0'))

    return bcs
Extract fields such as creation time, owner, etc. from the cluster,
dataset/ETHPy150Open Yelp/mrjob/mrjob/tools/emr/audit_usage.py/_cluster_to_basic_summary