Skip to content
Permalink
Browse files

allows service description builder to contribute to component->previo…

…us-descriptor-fns (#954)
  • Loading branch information...
shamsimam authored and nsinkov committed Sep 11, 2019
1 parent 30c46f0 commit 3745ff02a97e4924f9d86d0a75ba53b270c87e8e
@@ -224,8 +224,7 @@

(defn- compute-token-source-previous-descriptor
"Computes the previous descriptor using token sources."
[kv-store service-id-prefix username metric-group-mappings token-defaults service-description-builder
assoc-run-as-user-approved? {:keys [sources] :as descriptor}]
[token-defaults build-service-description-and-id {:keys [component->previous-descriptor-fns sources] :as descriptor}]
(when-let [token-sequence (-> sources :token-sequence seq)]
(let [{:keys [token->token-data]} sources
previous-token (->> token->token-data
@@ -235,28 +234,25 @@
(when (seq previous-token-data)
(let [new-sources (->> (assoc token->token-data previous-token previous-token-data)
(sd/compute-service-description-template-from-tokens token-defaults token-sequence)
(merge sources))]
(-> (select-keys descriptor [:component->previous-descriptor-fns :passthrough-headers :waiter-headers])
(assoc :sources new-sources)
(sd/merge-service-description-and-id
kv-store service-id-prefix username metric-group-mappings service-description-builder
assoc-run-as-user-approved?)
(sd/merge-suspended kv-store)))))))
(merge sources))
token-previous-descriptor-fns (get component->previous-descriptor-fns :token)]
(-> (select-keys descriptor [:passthrough-headers :waiter-headers])
(assoc :component->previous-descriptor-fns {:token token-previous-descriptor-fns}
:sources new-sources)
(build-service-description-and-id)))))))

(defn attach-token-fallback-source
"Attaches the helper functions map to retrieve previous descriptor using tokens into the
[:component->previous-descriptor-fns :token] key in the provided descriptor.
The map contains the following keys: :retrieve-last-update-time and :retrieve-previous-descriptor"
[descriptor kv-store service-id-prefix username metric-group-mappings token-defaults service-description-builder
assoc-run-as-user-approved?]
[descriptor token-defaults build-service-description-and-id]
(cond-> descriptor
(-> descriptor :sources :token-sequence seq)
(assoc-in [:component->previous-descriptor-fns :token]
{:retrieve-last-update-time sd/retrieve-most-recently-modified-token-update-time
:retrieve-previous-descriptor (fn retrieve-most-recent-token-update-descriptor [descriptor]
(compute-token-source-previous-descriptor
kv-store service-id-prefix username metric-group-mappings token-defaults
service-description-builder assoc-run-as-user-approved? descriptor))})))
token-defaults build-service-description-and-id descriptor))})))

(defn compute-descriptor
"Creates the service descriptor from the request.
@@ -265,14 +261,14 @@
[service-description-defaults token-defaults service-id-prefix kv-store waiter-hostnames request metric-group-mappings
service-description-builder assoc-run-as-user-approved?]
(let [current-request-user (get request :authorization/user)
build-service-description-and-id-helper (sd/make-build-service-description-and-id-helper
kv-store service-id-prefix current-request-user metric-group-mappings
service-description-builder assoc-run-as-user-approved?)
descriptor
(-> (headers/split-headers (:headers request))
(sd/merge-service-description-sources kv-store waiter-hostnames service-description-defaults token-defaults)
(sd/merge-service-description-and-id kv-store service-id-prefix current-request-user metric-group-mappings
service-description-builder assoc-run-as-user-approved?)
(sd/merge-suspended kv-store)
(attach-token-fallback-source kv-store service-id-prefix current-request-user metric-group-mappings
token-defaults service-description-builder assoc-run-as-user-approved?))]
(sd/merge-service-description-sources kv-store waiter-hostnames service-description-defaults token-defaults)
(attach-token-fallback-source token-defaults build-service-description-and-id-helper)
(build-service-description-and-id-helper))]
(when-let [throwable (sd/validate-service-description kv-store service-description-builder descriptor)]
(throw throwable))
descriptor))
@@ -549,7 +549,8 @@
ServiceDescriptionBuilder

(build [_ user-service-description
{:keys [assoc-run-as-user-approved? defaults kv-store metric-group-mappings service-id-prefix username]}]
{:keys [assoc-run-as-user-approved? component->previous-descriptor-fns defaults kv-store
metric-group-mappings service-id-prefix username]}]
(let [core-service-description (if (get user-service-description "run-as-user")
user-service-description
(let [candidate-service-description (assoc-run-as-requester-fields user-service-description username)
@@ -562,7 +563,8 @@
service-id (service-description->service-id service-id-prefix core-service-description)
service-description (default-and-override core-service-description metric-group-mappings
kv-store defaults service-id)]
{:core-service-description core-service-description
{:component->previous-descriptor-fns component->previous-descriptor-fns
:core-service-description core-service-description
:service-description service-description
:service-id service-id}))

@@ -893,8 +895,8 @@
If after the merge a run-as-user is not available, then `username` becomes the run-as-user.
If after the merge a permitted-user is not available, then `username` becomes the permitted-user."
[{:keys [defaults headers service-description-template source-tokens token-authentication-disabled token-preauthorized]}
waiter-headers passthrough-headers kv-store service-id-prefix username metric-group-mappings
service-description-builder assoc-run-as-user-approved?]
waiter-headers passthrough-headers component->previous-descriptor-fns kv-store service-id-prefix username
metric-group-mappings assoc-run-as-user-approved? service-description-builder]
(let [headers-without-params (dissoc headers "param")
header-params (get headers "param")
; any change with the on-the-fly must change the run-as-user if it doesn't already exist
@@ -944,17 +946,19 @@
(throw (ex-info "Cannot use run-as-requester with a specific namespace"
{:namespace raw-namespace :run-as-user raw-run-as-user :status 400 :log-level :warn})))
(sling/try+
(let [{:keys [core-service-description service-description service-id]}
(let [{:keys [component->previous-descriptor-fns core-service-description service-description service-id]}
(build service-description-builder user-service-description
{:assoc-run-as-user-approved? assoc-run-as-user-approved?
:component->previous-descriptor-fns component->previous-descriptor-fns
:defaults defaults
:kv-store kv-store
:metric-group-mappings metric-group-mappings
:service-id-prefix service-id-prefix
:username username})
service-preauthorized (and token-preauthorized (empty? service-description-based-on-headers))
service-authentication-disabled (and token-authentication-disabled (empty? service-description-based-on-headers))]
{:core-service-description core-service-description
{:component->previous-descriptor-fns component->previous-descriptor-fns
:core-service-description core-service-description
:on-the-fly? on-the-fly?
:service-authentication-disabled service-authentication-disabled
:service-description service-description
@@ -988,12 +992,23 @@

(defn merge-service-description-and-id
"Populates the descriptor with the service-description and service-id."
[{:keys [passthrough-headers sources waiter-headers] :as descriptor} kv-store service-id-prefix username
metric-group-mappings service-description-builder assoc-run-as-user-approved?]
(->> (compute-service-description sources waiter-headers passthrough-headers kv-store service-id-prefix username
metric-group-mappings service-description-builder assoc-run-as-user-approved?)
[{:keys [component->previous-descriptor-fns passthrough-headers sources waiter-headers] :as descriptor}
kv-store service-id-prefix username metric-group-mappings service-description-builder assoc-run-as-user-approved?]
(->> (compute-service-description
sources waiter-headers passthrough-headers component->previous-descriptor-fns kv-store service-id-prefix
username metric-group-mappings assoc-run-as-user-approved? service-description-builder)
(merge descriptor)))

(defn make-build-service-description-and-id-helper
"Factory function to return the function used to complete creating a descriptor using the builder."
[kv-store service-id-prefix current-request-user metric-group-mappings service-description-builder
assoc-run-as-user-approved?]
(fn build-service-description-and-id-helper [descriptor]
(-> descriptor
(merge-service-description-and-id kv-store service-id-prefix current-request-user metric-group-mappings
service-description-builder assoc-run-as-user-approved?)
(merge-suspended kv-store))))

(defn retrieve-most-recently-modified-token
"Computes the most recently modified token from the token->token-data map."
[token->token-data]
@@ -469,7 +469,10 @@
metric-group-mappings []
constraints {"cpus" {:max 100} "mem" {:max 1024}}
builder (sd/create-default-service-description-builder {:constraints constraints})
assoc-run-as-user-approved? (constantly false)]
assoc-run-as-user-approved? (constantly false)
build-service-description-and-id-helper (sd/make-build-service-description-and-id-helper
kv-store service-id-prefix username metric-group-mappings builder
assoc-run-as-user-approved?)]

(deftest test-descriptor->previous-descriptor-no-token
(let [sources {:defaults {"permitted-user" "*"}
@@ -503,8 +506,7 @@
(-> {:passthrough-headers passthrough-headers
:sources sources
:waiter-headers waiter-headers}
(attach-token-fallback-source kv-store service-id-prefix username metric-group-mappings
token-defaults builder assoc-run-as-user-approved?)))))))
(attach-token-fallback-source token-defaults build-service-description-and-id-helper)))))))

(deftest test-descriptor->previous-descriptor-multiple-sources
(let [service-description-1 {"cmd" "ls1" "cpus" 1 "mem" 32 "run-as-user" "ru" "version" "foo"}
@@ -640,8 +642,7 @@
current-descriptor (-> {:passthrough-headers passthrough-headers
:sources sources
:waiter-headers waiter-headers}
(attach-token-fallback-source kv-store service-id-prefix username metric-group-mappings
token-defaults builder assoc-run-as-user-approved?))
(attach-token-fallback-source token-defaults build-service-description-and-id-helper))
previous-descriptor (descriptor->previous-descriptor kv-store builder current-descriptor)]
(is (= {:component->previous-descriptor-fns (:component->previous-descriptor-fns current-descriptor)
:core-service-description service-description-1
@@ -680,8 +681,7 @@
current-descriptor (-> {:passthrough-headers passthrough-headers
:sources sources
:waiter-headers waiter-headers}
(attach-token-fallback-source kv-store service-id-prefix username metric-group-mappings
token-defaults builder assoc-run-as-user-approved?))
(attach-token-fallback-source token-defaults build-service-description-and-id-helper))
previous-descriptor (descriptor->previous-descriptor kv-store builder current-descriptor)]
(is (= {:component->previous-descriptor-fns (:component->previous-descriptor-fns current-descriptor)
:core-service-description service-description-1
@@ -720,8 +720,7 @@
current-descriptor (-> {:passthrough-headers passthrough-headers
:sources sources
:waiter-headers waiter-headers}
(attach-token-fallback-source kv-store service-id-prefix username metric-group-mappings
token-defaults builder assoc-run-as-user-approved?))
(attach-token-fallback-source token-defaults build-service-description-and-id-helper))
previous-descriptor (descriptor->previous-descriptor kv-store builder current-descriptor)]
(let [expected-core-service-description (assoc service-description-1 "cpus" 20 "permitted-user" username "run-as-user" username)]
(is (= {:component->previous-descriptor-fns (:component->previous-descriptor-fns current-descriptor)
@@ -758,8 +757,7 @@
current-descriptor (-> {:passthrough-headers passthrough-headers
:sources sources
:waiter-headers waiter-headers}
(attach-token-fallback-source kv-store service-id-prefix username metric-group-mappings
token-defaults builder assoc-run-as-user-approved?))]
(attach-token-fallback-source token-defaults build-service-description-and-id-helper))]
(is (nil? (descriptor->previous-descriptor kv-store builder current-descriptor)))))

(deftest test-descriptor->previous-descriptor-multiple-tokens-with-previous
@@ -787,8 +785,7 @@
current-descriptor (-> {:passthrough-headers passthrough-headers
:sources sources
:waiter-headers waiter-headers}
(attach-token-fallback-source kv-store service-id-prefix username metric-group-mappings
token-defaults builder assoc-run-as-user-approved?))
(attach-token-fallback-source token-defaults build-service-description-and-id-helper))
previous-descriptor (descriptor->previous-descriptor kv-store builder current-descriptor)]
(let [expected-core-service-description (-> (merge service-description-1 service-description-2p)
(select-keys sd/service-parameter-keys))]
@@ -780,14 +780,21 @@
(is (= expected actual))))))))

(defn- compute-service-description-helper
([sources & {:keys [assoc-run-as-user-approved? kv-store waiter-headers]}]
([sources & {:keys [assoc-run-as-user-approved? component->previous-descriptor-fns kv-store waiter-headers]}]
(with-redefs [metric-group-filter (fn [sd _] sd)
service-description-schema {s/Str s/Any}]
(let [assoc-run-as-user-approved? (or assoc-run-as-user-approved? (constantly false))
component->previous-descriptor-fns (or component->previous-descriptor-fns {})
kv-store (or kv-store (kv/->LocalKeyValueStore (atom {})))
waiter-headers (or waiter-headers {})]
(compute-service-description sources waiter-headers {} kv-store "test-service-" "current-request-user"
[] (create-default-service-description-builder {}) assoc-run-as-user-approved?)))))
waiter-headers (or waiter-headers {})
passthrough-headers {}
metric-group-mappings []
service-id-prefix "test-service-"
current-user "current-request-user"
service-description-builder (create-default-service-description-builder {})]
(compute-service-description
sources waiter-headers passthrough-headers component->previous-descriptor-fns kv-store service-id-prefix
current-user metric-group-mappings assoc-run-as-user-approved? service-description-builder)))))

(defn- service-description
([sources & {:keys [assoc-run-as-user-approved? kv-store waiter-headers]}]
@@ -1375,15 +1382,16 @@
test-user "test-header-user"
waiter-headers {}
passthrough-headers {}
component->previous-descriptor-fns {}
metric-group-mappings []
assoc-run-as-user-approved? (constantly false)
service-description-builder (create-default-service-description-builder {})
run-compute-service-description
(fn run-compute-service-description [descriptor]
(let [result-descriptor
(compute-service-description
descriptor waiter-headers passthrough-headers kv-store service-id-prefix test-user
metric-group-mappings service-description-builder assoc-run-as-user-approved?)
descriptor waiter-headers passthrough-headers component->previous-descriptor-fns kv-store service-id-prefix
test-user metric-group-mappings assoc-run-as-user-approved? service-description-builder)
result-errors (validate-service-description kv-store service-description-builder result-descriptor)]
(when result-errors
(throw result-errors))

0 comments on commit 3745ff0

Please sign in to comment.
You can’t perform that action at this time.