#!/usr/bin/env python
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Ambari Agent

"""

__all__ = ["curl_krb_request"]
import hashlib
import logging
import os

import time

from get_kinit_path import get_kinit_path
from get_klist_path import get_klist_path
from resource_management.core import global_lock
from resource_management.core import shell
from resource_management.core.exceptions import Fail
from resource_management.libraries.functions.get_user_call_output import get_user_call_output

HASH_ALGORITHM = hashlib.sha224
CONNECTION_TIMEOUT_DEFAULT = 10
MAX_TIMEOUT_DEFAULT = CONNECTION_TIMEOUT_DEFAULT + 2

logger = logging.getLogger()

# a dictionary of the last time that a kinit was performed for a specific cache
# dicionaries are inherently thread-safe in Python via the Global Interpreer Lock
# https://docs.python.org/2/glossary.html#term-global-interpreter-lock
_KINIT_CACHE_TIMES = {}

# the default time in between forced kinit calls (4 hours)
DEFAULT_KERBEROS_KINIT_TIMER_MS = 14400000

# a parameter which can be used to pass around the above timout value
KERBEROS_KINIT_TIMER_PARAMETER = "kerberos.kinit.timer"

def curl_krb_request(tmp_dir, keytab, principal, url, cache_file_prefix,
    krb_exec_search_paths, return_only_http_code, caller_label, user,
    connection_timeout = CONNECTION_TIMEOUT_DEFAULT,
    ca_certs = None,
    kinit_timer_ms=DEFAULT_KERBEROS_KINIT_TIMER_MS, method = '',body='',header=''):
  """
  Makes a curl request using the kerberos credentials stored in a calculated cache file. The
  cache file is created by combining the supplied principal, keytab, user, and request name into
  a unique hash.

  This function will use the klist command to determine if the cache is expired and will perform
  a kinit if necessary. Additionally, it has an internal timer to force a kinit after a
  configurable amount of time. This is to prevent boundary issues where requests hit the edge
  of a ticket's lifetime.

  :param tmp_dir: the directory to use for storing the local kerberos cache for this request.
  :param keytab: the location of the keytab to use when performing a kinit
  :param principal: the principal to use when performing a kinit
  :param url: the URL to request
  :param cache_file_prefix: an identifier used to build the unique cache name for this request.