-
Notifications
You must be signed in to change notification settings - Fork 101
/
Copy pathregion.clj
121 lines (96 loc) · 3.72 KB
/
region.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
;; 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]
[cognitect.aws.util :as u]
[cognitect.aws.config :as config]
[cognitect.aws.ec2-metadata-utils :as ec2])
(:import (java.io File)))
(set! *warn-on-reflection* true)
(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"))