All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cognitect.aws.region.clj Maven / Gradle / Ivy

There is a newer version: 0.8.692
Show newest version
;; Copyright (c) Cognitect, Inc.
;; All rights reserved.

(ns cognitect.aws.region
  "Region providers. Primarily for internal use, and subject to change."
  (:require [clojure.string :as str]
            [clojure.java.io :as io]
            [clojure.tools.logging :as log]
            [clojure.core.async :as a]
            [cognitect.aws.util :as u]
            [cognitect.aws.config :as config]
            [cognitect.aws.ec2-metadata-utils :as ec2])
  (:import (java.io File)))

(defn ^:skip-wiki valid-region
  "For internal use. Don't call directly.

  Return the credential region if valid, otherwise nil."
  [region]
  ;; TODO: (dchelimsky 2018-07-27) maybe validate this against known regions?
  (when-not (str/blank? region) region))

(defprotocol RegionProvider
  (fetch [_] "Returns the region found by this provider, or nil."))

(defn chain-region-provider
  "Chain together multiple region providers.

  `fetch` calls each provider in order until one returns a non-nil result,
  or returns nil.

  Alpha. Subject to change."
  [providers]
  (reify RegionProvider
    (fetch [_]
      (or (valid-region (some fetch providers))
          (throw (ex-info "No region found by any region provider."
                          {:providers (map class providers)}))))))

(defn environment-region-provider
  "Returns the region from the AWS_REGION env var, or nil if not present.

  Alpha. Subject to change."
  []
  (reify RegionProvider
    (fetch [_] (valid-region (u/getenv "AWS_REGION")))))

(defn system-property-region-provider
  "Returns the region from the aws.region system property, or nil if not present.

  Alpha. Subject to change."
  []
  (reify RegionProvider
    (fetch [_] (valid-region (u/getProperty "aws.region")))))

(defn profile-region-provider
  "Returns the region from an AWS configuration profile.

  Arguments:

    f             File    The profile configuration file. (default: ~/.aws/config)
    profile-name  string  The name of the profile in the file. (default: default)

  Parsed properties:

    region        required

  Alpha. Subject to change."
  ([]
   (profile-region-provider (or (u/getenv "AWS_PROFILE")
                                (u/getProperty "aws.profile")
                                "default")))
  ([profile-name]
   (profile-region-provider profile-name (or (io/file (u/getenv "AWS_CONFIG_FILE"))
                                             (io/file (u/getProperty "user.home") ".aws" "config"))))
  ([profile-name ^File f]
   (reify RegionProvider
     (fetch [_]
       (when (.exists f)
        (try
          (let [profile (get (config/parse f) profile-name)]
            (valid-region (get profile "region")))
          (catch Throwable t
            (log/error t "Unable to fetch region from the AWS config file " (str f)))))))))

(defn instance-region-provider
  "Returns the region from the ec2 instance's metadata service,
  or nil if the service can not be found.

  Alpha. Subject to change."
  [http-client]
  (let [cached-region (atom nil)]
    (reify RegionProvider
      (fetch [_]
        (or @cached-region
            (reset! cached-region (valid-region (ec2/get-ec2-instance-region http-client))))))))

(defn default-region-provider
  "Returns a chain-region-provider with, in order:

    environment-region-provider
    system-property-region-provider
    profile-region-provider
    instance-region-provider

  Alpha. Subject to change."
  [http-client]
  (chain-region-provider
   [(environment-region-provider)
    (system-property-region-provider)
    (profile-region-provider)
    (instance-region-provider http-client)]))

(defn fetch-async
  "Returns a channel that will produce the result of calling fetch on
  the provider.

  Alpha. Subject to change."
  [provider]
  (u/fetch-async fetch provider "region"))




© 2015 - 2024 Weber Informatics LLC | Privacy Policy