예제 #1
0
def ParseDuration(string, calendar=False):
    """Parses a duration string and returns a Duration object.

  Durations using only hours, miniutes, seconds and microseconds are exact.
  calendar=True allows the constructor to use duration units larger than hours.
  These durations will be inexact across daylight savings time and leap year
  boundaries, but will be "calendar" correct. For example:

    2015-02-14 + P1Y   => 2016-02-14
    2015-02-14 + P365D => 2016-02-14
    2016-02-14 + P1Y   => 2017-02-14
    2016-02-14 + P366D => 2017-02-14

    2016-03-13T01:00:00 + P1D   => 2016-03-14T01:00:00
    2016-03-13T01:00:00 + PT23H => 2016-03-14T01:00:00
    2016-03-13T01:00:00 + PT24H => 2016-03-14T03:00:00

  Args:
    string: The ISO 8601 duration/period string to parse.
    calendar: Use duration units larger than hours if True.

  Raises:
    DurationSyntaxError: Invalid duration syntax.
    DurationValueError: A Duration numeric constant exceeded its range.

  Returns:
    An iso_duration.Duration object for the given ISO 8601 duration/period
    string.
  """
    try:
        return iso_duration.Duration(calendar=calendar).Parse(string)
    except (AttributeError, OverflowError) as e:
        raise DurationValueError(six.text_type(e))
    except ValueError as e:
        raise DurationSyntaxError(six.text_type(e))
예제 #2
0
def process_retention_period(retention_period_string):
    """Converts retention_period string to Apitools object."""
    if retention_period_string == user_request_args_factory.CLEAR:
        return None

    messages = apis.GetMessagesModule('storage', 'v1')
    return messages.Bucket.RetentionPolicyValue(retentionPeriod=int(
        iso_duration.Duration().Parse(retention_period_string).total_seconds))
예제 #3
0
def GetDurationFromTimeDelta(delta, calendar=False):
    """Returns a Duration object converted from a datetime.timedelta object.

  Args:
    delta: The datetime.timedelta object to convert.
    calendar: Use duration units larger than hours if True.

  Returns:
    The iso_duration.Duration object converted from a datetime.timedelta object.
  """
    return iso_duration.Duration(delta=delta, calendar=calendar)
예제 #4
0
def RecentlyModified(update_time):
    """Checks if the trigger with the given update_time was recently modified.

  Args:
    update_time: str, the time when the trigger was last modified.

  Returns:
    True if the trigger was recently modified and might not be ready for use.
  """
    update_dt = times.ParseDateTime(update_time)
    max_duration = iso_duration.Duration(minutes=MAX_READY_LATENCY_MINUTES)
    ready_dt = times.GetDateTimePlusDuration(update_dt, max_duration)
    return times.Now() < ready_dt
예제 #5
0
def _ParseSegmentTimestamp(timestamp_string):
    """Parse duration formatted segment timestamp into a Duration object.

  Assumes string with no duration unit specified (e.g. 's' or 'm' etc.) is
  an int representing microseconds.

  Args:
    timestamp_string: str, string to convert

  Raises:
    ValueError: timestamp_string is not a properly formatted duration, not a
    int or int value is <0

  Returns:
    Duration object represented by timestamp_string
  """
    # Assume timestamp_string passed as int number of microseconds if no unit
    # e.g. 4566, 100, etc.
    try:
        microseconds = int(timestamp_string)
    except ValueError:
        try:
            duration = times.ParseDuration(timestamp_string)
            if duration.total_seconds < 0:
                raise times.DurationValueError()
            return duration
        except (times.DurationSyntaxError, times.DurationValueError):
            raise ValueError(
                'Could not parse timestamp string [{}]. Timestamp must '
                'be a properly formatted duration string with time '
                'amount and units (e.g. 1m3.456s, 2m, 14.4353s)'.format(
                    timestamp_string))
    else:
        log.warning(
            "Time unit missing ('s', 'm','h') for segment timestamp [{}], "
            "parsed as microseconds.".format(timestamp_string))

    if microseconds < 0:
        raise ValueError(
            'Could not parse duration string [{}]. Timestamp must be'
            'greater than >= 0)'.format(timestamp_string))

    return iso_duration.Duration(microseconds=microseconds)
예제 #6
0
def TriggerActiveTime(event_type, update_time):
  """Computes the time by which the trigger will become active.

  Args:
    event_type: str, the trigger's event type.
    update_time: str, the time when the trigger was last modified.

  Returns:
    The active time as a string, or None if the trigger is already active.
  """
  if not types.IsAuditLogType(event_type):
    # The delay only applies to Audit Log triggers.
    return None
  update_dt = times.ParseDateTime(update_time)
  delay = iso_duration.Duration(minutes=MAX_ACTIVE_DELAY_MINUTES)
  active_dt = times.GetDateTimePlusDuration(update_dt, delay)
  if times.Now() >= active_dt:
    return None
  return times.FormatDateTime(active_dt, fmt='%H:%M:%S', tzinfo=times.LOCAL)
예제 #7
0
def _WhitelistClientIP(instance_ref, sql_client, sql_messages, resources,
                       minutes=5):
  """Add CLIENT_IP to the authorized networks list.

  Makes an API call to add CLIENT_IP to the authorized networks list.
  The server knows to interpret the string CLIENT_IP as the address with which
  the client reaches the server. This IP will be whitelisted for 1 minute.

  Args:
    instance_ref: resources.Resource, The instance we're connecting to.
    sql_client: apitools.BaseApiClient, A working client for the sql version
        to be used.
    sql_messages: module, The module that defines the messages for the sql
        version to be used.
    resources: resources.Registry, The registry that can create resource refs
        for the sql version to be used.
    minutes: How long the client IP will be whitelisted for, in minutes.

  Returns:
    string, The name of the authorized network rule. Callers can use this name
    to find out the IP the client reached the server with.
  Raises:
    HttpException: An http error response was received while executing api
        request.
    ToolException: Server did not complete the whitelisting operation in time.
  """
  time_of_connection = network.GetCurrentTime()

  acl_name = 'sql connect at time {0}'.format(time_of_connection)
  user_acl = sql_messages.AclEntry(
      name=acl_name,
      expirationTime=iso_duration.Duration(
          minutes=minutes).GetRelativeDateTime(time_of_connection),
      value='CLIENT_IP')

  try:
    original = sql_client.instances.Get(
        sql_messages.SqlInstancesGetRequest(
            project=instance_ref.project,
            instance=instance_ref.instance))
  except apitools_exceptions.HttpError as error:
    raise exceptions.HttpException(error)

  original.settings.ipConfiguration.authorizedNetworks.append(user_acl)
  try:
    patch_request = sql_messages.SqlInstancesPatchRequest(
        databaseInstance=original,
        project=instance_ref.project,
        instance=instance_ref.instance)
    result = sql_client.instances.Patch(patch_request)
  except apitools_exceptions.HttpError as error:
    raise exceptions.HttpException(error)

  operation_ref = resources.Create(
      'sql.operations',
      operation=result.name,
      project=instance_ref.project)
  message = ('Whitelisting your IP for incoming connection for '
             '{0} {1}'.format(minutes, text.Pluralize(minutes, 'minute')))

  operations.OperationsV1Beta4.WaitForOperation(
      sql_client, operation_ref, message)

  return acl_name
예제 #8
0
def _AllowlistClientIP(instance_ref,
                       sql_client,
                       sql_messages,
                       resources,
                       minutes=5):
    """Add CLIENT_IP to the authorized networks list.

  Makes an API call to add CLIENT_IP to the authorized networks list.
  The server knows to interpret the string CLIENT_IP as the address with which
  the client reaches the server. This IP will be allowlisted for 1 minute.

  Args:
    instance_ref: resources.Resource, The instance we're connecting to.
    sql_client: apitools.BaseApiClient, A working client for the sql version to
      be used.
    sql_messages: module, The module that defines the messages for the sql
      version to be used.
    resources: resources.Registry, The registry that can create resource refs
      for the sql version to be used.
    minutes: How long the client IP will be allowlisted for, in minutes.

  Returns:
    string, The name of the authorized network rule. Callers can use this name
    to find out the IP the client reached the server with.
  Raises:
    HttpException: An http error response was received while executing api
        request.
    ResourceNotFoundError: The SQL instance was not found.
  """
    time_of_connection = network.GetCurrentTime()

    acl_name = 'sql connect at time {0}'.format(time_of_connection)
    user_acl = sql_messages.AclEntry(
        kind='sql#aclEntry',
        name=acl_name,
        expirationTime=iso_duration.Duration(
            minutes=minutes).GetRelativeDateTime(time_of_connection)
        # TODO(b/122989827): Remove this once the datetime parsing is fixed.
        # Setting the microseconds component to 10 milliseconds. This complies
        # with backend formatting restrictions, since backend requires a microsecs
        # component and anything less than 1 milli will get truncated.
        .replace(microsecond=10000).isoformat(),
        value='CLIENT_IP')

    try:
        original = sql_client.instances.Get(
            sql_messages.SqlInstancesGetRequest(
                project=instance_ref.project, instance=instance_ref.instance))
    except apitools_exceptions.HttpError as error:
        if error.status_code == six.moves.http_client.FORBIDDEN:
            raise exceptions.ResourceNotFoundError(
                'There was no instance found at {} or you are not authorized to '
                'connect to it.'.format(instance_ref.RelativeName()))
        raise calliope_exceptions.HttpException(error)

    # TODO(b/122989827): Remove this once the datetime parsing is fixed.
    original.serverCaCert = None

    original.settings.ipConfiguration.authorizedNetworks.append(user_acl)
    try:
        patch_request = sql_messages.SqlInstancesPatchRequest(
            databaseInstance=original,
            project=instance_ref.project,
            instance=instance_ref.instance)
        result = sql_client.instances.Patch(patch_request)
    except apitools_exceptions.HttpError as error:
        raise calliope_exceptions.HttpException(error)

    operation_ref = resources.Create('sql.operations',
                                     operation=result.name,
                                     project=instance_ref.project)
    message = ('Allowlisting your IP for incoming connection for '
               '{0} {1}'.format(minutes, text.Pluralize(minutes, 'minute')))

    operations.OperationsV1Beta4.WaitForOperation(sql_client, operation_ref,
                                                  message)

    return acl_name