예제 #1
0
    def __init__(self):
        etcd_authority = os.getenv(ETCD_AUTHORITY_ENV, ETCD_AUTHORITY_DEFAULT)
        if not validate_hostname_port(etcd_authority):
            raise DataStoreError("Invalid %s. It must take the form "
                                 "<address>:<port>. Value provided is '%s'" %
                                 (ETCD_AUTHORITY_ENV, etcd_authority))

        (host, port) = etcd_authority.split(":", 1)
        etcd_scheme = os.getenv(ETCD_SCHEME_ENV, ETCD_SCHEME_DEFAULT)
        etcd_key = os.getenv(ETCD_KEY_FILE_ENV, '')
        etcd_cert = os.getenv(ETCD_CERT_FILE_ENV, '')
        etcd_ca = os.getenv(ETCD_CA_CERT_FILE_ENV, '')
        key_pair = (etcd_cert, etcd_key) if (etcd_cert and etcd_key) else None

        if etcd_scheme == "https":
            # key and certificate must be both specified or both not specified
            if bool(etcd_key) != bool(etcd_cert):
                raise DataStoreError("Invalid %s, %s combination. Key and "
                                     "certificate must both be specified or "
                                     "both be blank. Values provided: %s=%s, "
                                     "%s=%s" % (ETCD_KEY_FILE_ENV,
                                                ETCD_CERT_FILE_ENV,
                                                ETCD_KEY_FILE_ENV, etcd_key,
                                                ETCD_CERT_FILE_ENV, etcd_cert))
            # Make sure etcd key and certificate are readable
            if etcd_key and etcd_cert and not (os.path.isfile(etcd_key) and
                                               os.access(etcd_key, os.R_OK) and
                                               os.path.isfile(etcd_cert) and
                                               os.access(etcd_cert, os.R_OK)):
                raise DataStoreError("Cannot read %s and/or %s. Both must "
                                     "be readable file paths. Values "
                                     "provided: %s=%s, %s=%s" %
                                     (ETCD_KEY_FILE_ENV,
                                      ETCD_CERT_FILE_ENV,
                                      ETCD_KEY_FILE_ENV, etcd_key,
                                      ETCD_CERT_FILE_ENV, etcd_cert))
            # Certificate Authority cert must be provided, check it's readable
            if not etcd_ca or not (os.path.isfile(etcd_ca) and
                                   os.access(etcd_ca, os.R_OK)):
                raise DataStoreError("Invalid %s. Certificate Authority "
                                     "cert is required and must be a "
                                     "readable file path. Value provided: "
                                     "%s" % (ETCD_CA_CERT_FILE_ENV, etcd_ca))
        elif etcd_scheme != "http":
            raise DataStoreError("Invalid %s. Value must be one of: \"\", "
                                 "\"http\", \"https\". Value provided: %s" %
                                 (ETCD_SCHEME_ENV, etcd_scheme))

        # Set CA value to None if it is a None-value string
        etcd_ca = None if not etcd_ca else etcd_ca
        self.etcd_client = etcd.Client(host=host,
                                       port=int(port),
                                       protocol=etcd_scheme,
                                       cert=key_pair,
                                       ca_cert=etcd_ca)
예제 #2
0
 def wrapped(*args, **kwargs):
     try:
         return fn(*args, **kwargs)
     except EtcdException as e:
         # Don't leak out etcd exceptions.
         raise DataStoreError("%s: Error accessing etcd (%s).  Is etcd "
                              "running?" % (fn.__name__, e.message))