From 38fb15a3a29242052c3e770f033ab01b74752939 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Wed, 12 Jul 2017 17:47:04 +0200 Subject: [PATCH 01/46] wip --- .../ssclj/resources/run_parameter.clj | 0 .../ssclj/resources/spec/run_parameter.cljc | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj create mode 100644 ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj new file mode 100644 index 000000000..e69de29bb diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc new file mode 100644 index 000000000..48589f625 --- /dev/null +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc @@ -0,0 +1,18 @@ +(ns com.sixsq.slipstream.ssclj.resources.spec.service-attribute-namespace + (:require + [clojure.spec.alpha :as s] + [clojure.spec.gen.alpha :as gen] + [clojure.string :as str] + [com.sixsq.slipstream.ssclj.util.spec :as su] + [com.sixsq.slipstream.ssclj.resources.spec.common :as c])) + +(def prefix-regex #"^[a-z]([a-z0-9-]*[a-z0-9])?$") +(def char-prefix (gen/fmap char (s/gen (set (concat (range 97 123) (range 48 58) [45]))))) +(def gen-prefix (gen/fmap str/join (gen/vector char-prefix))) +(s/def :cimi.service-attribute-namespace/prefix (s/with-gen (s/and string? #(re-matches prefix-regex %)) + (constantly gen-prefix))) + +(s/def :cimi/service-attribute-namespace + (su/only-keys-maps c/common-attrs + {:req-un [:cimi.service-attribute-namespace/prefix + :cimi.core/uri]})) From 5c349ea60cc84cc770697d2505a5e4232d1160a9 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Wed, 12 Jul 2017 17:49:06 +0200 Subject: [PATCH 02/46] wip --- ssclj/jar/build.boot | 1 + 1 file changed, 1 insertion(+) diff --git a/ssclj/jar/build.boot b/ssclj/jar/build.boot index f870acfe1..cf0f716d5 100644 --- a/ssclj/jar/build.boot +++ b/ssclj/jar/build.boot @@ -45,6 +45,7 @@ [ring/ring-core] [ring/ring-json] [superstring] + [ring-sse/ring-sse] [com.sixsq.slipstream/utils] [com.sixsq.slipstream/auth] From 90be0aa8656004623654b27cda5eef9f1d1e2c57 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Wed, 12 Jul 2017 17:53:56 +0200 Subject: [PATCH 03/46] wip --- .../ssclj/resources/run_parameter.clj | 104 ++++++++++++++++++ .../ssclj/resources/spec/run_parameter.cljc | 15 +-- 2 files changed, 109 insertions(+), 10 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj index e69de29bb..dd1918560 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj @@ -0,0 +1,104 @@ +(ns com.sixsq.slipstream.ssclj.resources.run-parameter + (:require + [clojure.spec.alpha :as s] + [com.sixsq.slipstream.ssclj.resources.spec.run-parameter] + [com.sixsq.slipstream.ssclj.resources.common.std-crud :as std-crud] + [com.sixsq.slipstream.ssclj.resources.common.schema :as c] + [com.sixsq.slipstream.ssclj.resources.common.crud :as crud] + [com.sixsq.slipstream.ssclj.resources.common.utils :as u] + [com.sixsq.slipstream.auth.acl :as a] + [superstring.core :as str] + [ring.util.response :as r] + [com.sixsq.slipstream.util.response :as sr] + [ring.sse :as sse] + )) + +(def ^:const resource-name "RunParameter") + +(def ^:const resource-tag (keyword (str (str/camel-case resource-name) "s"))) + +(def ^:const resource-url (u/de-camelcase resource-name)) + +(def ^:const collection-name "RunParameterCollection") + +(def ^:const resource-uri (str c/slipstream-schema-uri resource-name)) + +(def ^:const collection-uri (str c/slipstream-schema-uri collection-name)) + +(def collection-acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal "USER" + :type "ROLE" + :right "MODIFY"}]}) +;; +;; multimethods for validation and operations +;; + +(def validate-fn (u/create-spec-validation-fn :cimi/run-parameter)) +(defmethod crud/validate resource-uri + [resource] + (validate-fn resource)) + +(defmethod crud/add-acl resource-uri + [resource request] + (a/add-acl resource request)) +;; +;; CRUD operations +;; + +(def add-impl (std-crud/add-fn resource-name collection-acl resource-uri)) + +(defmethod crud/add resource-name + [request] + (add-impl request)) + +;(def handler +; (sse/event-channel-handler +; (fn [request response raise event-ch] +; (async/go +; (dotimes [i 20] +; (let [event {:id (java.util.UUID/randomUUID) +; :name "foo" +; :data (json/generate-string {:foo "bar"})}] +; (async/>! event-ch event) +; (async/ (str (u/de-camelcase resource-name) "/" uuid) +; (db/retrieve request) +; (a/can-view? request) +; (crud/set-operations request) +; (r/json-response)) +; (catch ExceptionInfo ei +; (ex-data ei))))) + +(def retrieve-impl (std-crud/retrieve-fn resource-name)) + +(defmethod crud/retrieve resource-name + [request] + ;(handler request (partial retrieve-fn resource-name) (fn[e] (log/error e))) + (std-crud/retrieve-fn resource-name) + ) + +(def edit-impl (std-crud/edit-fn resource-name)) + +(defmethod crud/edit resource-name + [request] + (edit-impl request)) + +(def delete-impl (std-crud/delete-fn resource-name)) + +(defmethod crud/delete resource-name + [request] + (delete-impl request)) + +(def query-impl (std-crud/query-fn resource-name collection-acl collection-uri resource-tag)) + +(defmethod crud/query resource-name + [request] + (query-impl request)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc index 48589f625..9f0c60025 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc @@ -1,4 +1,4 @@ -(ns com.sixsq.slipstream.ssclj.resources.spec.service-attribute-namespace +(ns com.sixsq.slipstream.ssclj.resources.spec.run-parameter (:require [clojure.spec.alpha :as s] [clojure.spec.gen.alpha :as gen] @@ -6,13 +6,8 @@ [com.sixsq.slipstream.ssclj.util.spec :as su] [com.sixsq.slipstream.ssclj.resources.spec.common :as c])) -(def prefix-regex #"^[a-z]([a-z0-9-]*[a-z0-9])?$") -(def char-prefix (gen/fmap char (s/gen (set (concat (range 97 123) (range 48 58) [45]))))) -(def gen-prefix (gen/fmap str/join (gen/vector char-prefix))) -(s/def :cimi.service-attribute-namespace/prefix (s/with-gen (s/and string? #(re-matches prefix-regex %)) - (constantly gen-prefix))) - -(s/def :cimi/service-attribute-namespace +(s/def :cimi/run-parameter (su/only-keys-maps c/common-attrs - {:req-un [:cimi.service-attribute-namespace/prefix - :cimi.core/uri]})) + {:req-un [:cimi.common/acl + :cimi.run-parameter/name + :cimi.run-parameter/run-id]})) From 30e8445a6da9721671f29b07e2f052dc598c685c Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Thu, 13 Jul 2017 16:57:24 +0200 Subject: [PATCH 04/46] working sse prototype --- ssclj/jar/build.boot | 2 +- .../ssclj/resources/run_parameter.clj | 59 ++++---- .../com/sixsq/slipstream/ssclj/util/sse.clj | 139 ++++++++++++++++++ 3 files changed, 170 insertions(+), 30 deletions(-) create mode 100644 ssclj/jar/src/com/sixsq/slipstream/ssclj/util/sse.clj diff --git a/ssclj/jar/build.boot b/ssclj/jar/build.boot index cf0f716d5..f98f82724 100644 --- a/ssclj/jar/build.boot +++ b/ssclj/jar/build.boot @@ -36,6 +36,7 @@ [metrics-clojure-jvm] [metrics-clojure-graphite] [me.raynes/fs] + [org.clojure/core.async :exclusions []] [org.clojure/data.json] [org.clojure/java.classpath] [org.clojure/tools.cli] @@ -45,7 +46,6 @@ [ring/ring-core] [ring/ring-json] [superstring] - [ring-sse/ring-sse] [com.sixsq.slipstream/utils] [com.sixsq.slipstream/auth] diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj index dd1918560..07379a0d9 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj @@ -10,8 +10,12 @@ [superstring.core :as str] [ring.util.response :as r] [com.sixsq.slipstream.util.response :as sr] - [ring.sse :as sse] - )) + [com.sixsq.slipstream.db.impl :as db] + [clojure.tools.logging :as log] + [com.sixsq.slipstream.ssclj.util.sse :as sse] + [clojure.core.async :as async] + ) + (:import (clojure.lang ExceptionInfo))) (def ^:const resource-name "RunParameter") @@ -52,38 +56,35 @@ [request] (add-impl request)) -;(def handler -; (sse/event-channel-handler -; (fn [request response raise event-ch] -; (async/go -; (dotimes [i 20] -; (let [event {:id (java.util.UUID/randomUUID) -; :name "foo" -; :data (json/generate-string {:foo "bar"})}] -; (async/>! event-ch event) -; (async/ (str (u/de-camelcase resource-name) "/" uuid) -; (db/retrieve request) -; (a/can-view? request) -; (crud/set-operations request) -; (r/json-response)) -; (catch ExceptionInfo ei -; (ex-data ei))))) +(def handler + (sse/event-channel-handler + (fn [request response raise event-ch] + (async/go + (dotimes [i 20] + (let [event {:id (java.util.UUID/randomUUID) + :name "foo" + :data "bar"}] + (async/>! event-ch event) + (async/ (str (u/de-camelcase resource-name) "/" uuid) + (db/retrieve request) + (a/can-view? request) + (crud/set-operations request)) + (catch ExceptionInfo ei + (ex-data ei))))) (def retrieve-impl (std-crud/retrieve-fn resource-name)) (defmethod crud/retrieve resource-name [request] - ;(handler request (partial retrieve-fn resource-name) (fn[e] (log/error e))) - (std-crud/retrieve-fn resource-name) - ) + (handler request)) (def edit-impl (std-crud/edit-fn resource-name)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/sse.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/sse.clj new file mode 100644 index 000000000..098ab2d87 --- /dev/null +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/sse.clj @@ -0,0 +1,139 @@ +(ns com.sixsq.slipstream.ssclj.util.sse + (:require [clojure.core.async :as async] + [clojure.java.io :as io] + [clojure.string :as string] + [ring.core.protocols :as ring] + [ring.util.response :as ring-response] + [manifold.stream :as s] + [manifold.deferred :as d]) + ) + +(def CRLF "\r\n") +(def EVENT_FIELD "event: ") +(def DATA_FIELD "data: ") +(def ID_FIELD "id: ") + +(defn mk-data + ([name data] + (mk-data name data nil)) + ([name data id] + (let [sb (StringBuilder.)] + (when name + (.append sb EVENT_FIELD) + (.append sb name) + (.append sb CRLF)) + + (doseq [part (string/split data #"\r?\n")] + (.append sb DATA_FIELD) + (.append sb part) + (.append sb CRLF)) + + (when (not-empty id) + (.append sb ID_FIELD) + (.append sb id) + (.append sb CRLF)) + + (.append sb CRLF) + (str sb)))) + +(defn send-event + [channel name data id put-fn raise] + (try + (put-fn channel (mk-data name data id)) + (catch Throwable t + (async/close! channel) + (raise t) + nil))) + +(defn- start-dispatch-loop + "Kicks off the loop that transfers data provided by the application + on `event-channel` to the HTTP infrastructure via + `response-channel`." + [{:keys [event-channel response-channel heartbeat-delay on-client-disconnect raise] :as opts}] + (async/go + (loop [] + (let [hb-timeout (async/timeout (* 1000 heartbeat-delay)) + [event port] (async/alts! [event-channel hb-timeout])] + (cond + (= port hb-timeout) + (when (async/>! response-channel CRLF) + (recur)) + + (and (some? event) (= port event-channel)) + (let [{event-name :name + event-data :data + event-id :id} + (if (map? event) + (reduce (fn [agg [k v]] (assoc agg k (str v))) {} event) + {:data (str event)})] + (when (send-event response-channel event-name event-data event-id async/put! raise) + (recur)))))) + (async/close! event-channel) + (async/close! response-channel) + (when on-client-disconnect (on-client-disconnect)) + :done)) + +(defn- start-stream + "Starts an SSE event stream and initiates a heartbeat to keep the + connection alive. `stream-ready-fn` will be called with a core.async + channel and the initial response map. The application can then put + maps with keys :id, :name, and :data on that channel to cause SSE + events to be sent to the client. Either the client or the + application may close the channel to terminate and clean up the + event stream; the client closes it by closing the connection. The + SSE's core.async buffer can either be a fixed buffer (n) or a + 0-arity function that returns a buffer." + [{:keys [stream-ready-fn request respond raise heartbeat-delay bufferfn-or-n on-client-disconnect]}] + (let [heartbeat-delay (or heartbeat-delay 10) + bufferfn-or-n (or bufferfn-or-n 10) + response-channel (async/chan (if (fn? bufferfn-or-n) (bufferfn-or-n) bufferfn-or-n)) + response (-> (ring-response/response (s/->source response-channel)) + (ring-response/content-type "text/event-stream") ;; TODO: content negotiation? "text/event-stream+json"? + (ring-response/charset "UTF-8") + (ring-response/header "Connection" "close") + (ring-response/header "Cache-Control" "no-cache")) + ;; TODO: re-create CORS support as per original: (update-in [:headers] merge (:cors-headers context)) + event-channel (async/chan (if (fn? bufferfn-or-n) (bufferfn-or-n) bufferfn-or-n))] + (respond response) + (async/thread + (stream-ready-fn request response raise event-channel) + :done) + (start-dispatch-loop (merge {:event-channel event-channel + :response-channel response-channel + :heartbeat-delay heartbeat-delay + :raise raise} + (when on-client-disconnect + {:on-client-disconnect #(on-client-disconnect response)}))))) + +(defn ring->aleph [handler] + (fn [request] + (let [response (d/deferred)] + (handler request #(d/success! response %) #(d/error! response %)) + response))) + +(defn event-channel-handler + "Returns a Ring async handler which will start a Server Sent Event + stream with the requesting client. `stream-ready-fn` will be called + in a future, and will be passed the original request, the initial + response, the raise fn, and the event channel. + + Options: + + :buffer - either an integer buffer size, or a 0-arity function that + returns a buffer. + :heartbeat-delay - An integer number of seconds between heartbeat + messages + :on-client-disconnect - A function of one argument (the initial response) + which will be called when the client permanently disconnects." + ([stream-ready-fn] + (event-channel-handler stream-ready-fn {})) + ([stream-ready-fn {:keys [buffer heartbeat-delay on-client-disconnect]}] + (ring->aleph + (fn [request respond raise] + (start-stream {:stream-ready-fn stream-ready-fn + :request request + :respond respond + :raise raise + :heartbeat-delay heartbeat-delay + :bufferfn-or-n buffer + :on-client-disconnect on-client-disconnect}))))) From ae095222f68712190b6b3f8e396769cbac8274b8 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Fri, 14 Jul 2017 17:53:52 +0200 Subject: [PATCH 05/46] sse and zookeeper working --- .../sixsq/slipstream/ssclj/resources/run.clj | 122 ++++++++++++++++++ .../ssclj/resources/run_parameter.clj | 33 +++-- .../slipstream/ssclj/util/zookeeper_utils.clj | 17 +++ 3 files changed, 164 insertions(+), 8 deletions(-) create mode 100644 ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj create mode 100644 ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper_utils.clj diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj new file mode 100644 index 000000000..ecebe2a6e --- /dev/null +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj @@ -0,0 +1,122 @@ +(ns com.sixsq.slipstream.ssclj.resources.run + (:require + [clojure.spec.alpha :as s] + [com.sixsq.slipstream.ssclj.resources.spec.run] + [com.sixsq.slipstream.ssclj.resources.common.std-crud :as std-crud] + [com.sixsq.slipstream.ssclj.resources.common.schema :as c] + [com.sixsq.slipstream.ssclj.resources.common.crud :as crud] + [com.sixsq.slipstream.ssclj.resources.common.utils :as u] + [com.sixsq.slipstream.auth.acl :as a] + [superstring.core :as str] + [ring.util.response :as r] + [com.sixsq.slipstream.util.response :as sr] + [com.sixsq.slipstream.db.impl :as db] + [clojure.tools.logging :as log] + [com.sixsq.slipstream.ssclj.util.sse :as sse] + [clojure.core.async :as async] + [zookeeper :as zk] + ) + (:import (clojure.lang ExceptionInfo))) + +(def ^:const resource-name "Run") + +(def ^:const resource-tag (keyword (str (str/camel-case resource-name) "s"))) + +(def ^:const resource-url (u/de-camelcase resource-name)) + +(def ^:const collection-name "RunCollection") + +(def ^:const resource-uri (str c/slipstream-schema-uri resource-name)) + +(def ^:const collection-uri (str c/slipstream-schema-uri collection-name)) + +(def collection-acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal "USER" + :type "ROLE" + :right "MODIFY"}]}) +(def port 2181) + +(defn connect + ([] (connect port)) + ([port] + (zk/connect (str "127.0.0.1:" port)))) + +(def client (connect)) +;; +;; multimethods for validation and operations +;; + +(def validate-fn (u/create-spec-validation-fn :cimi/run-parameter)) +(defmethod crud/validate resource-uri + [resource] + (validate-fn resource)) + +(defmethod crud/add-acl resource-uri + [resource request] + (a/add-acl resource request)) +;; +;; CRUD operations +;; + +(def add-impl (std-crud/add-fn resource-name collection-acl resource-uri)) + +(defmethod crud/add resource-name + [request] + (add-impl request)) + +(def node "/hello") + +(defn get-data + "Get data, as string, from the znode" + [client path] + (String. (:data (zk/data client path)))) + +(defn watch-fn [event-ch {:keys [event-type path :as zk-event]}] + (when (= event-type :NodeDataChanged) + (let [event {:id (java.util.UUID/randomUUID) + :name "foo" + :data (get-data client path)}] + (async/>!! event-ch event))) + (zk/data client node :watcher (partial watch-fn event-ch))) + +(def handler + (sse/event-channel-handler + (fn [request response raise event-ch] + (zk/data client node :watcher (partial watch-fn event-ch))) + {:on-client-disconnect #(log/debug "sse/on-client-disconnect: " %)})) + +(defn retrieve-fn + [resource-name] + (fn [{{uuid :uuid} :params :as request}] + (try + (-> (str (u/de-camelcase resource-name) "/" uuid) + (db/retrieve request) + (a/can-view? request) + (crud/set-operations request)) + (catch ExceptionInfo ei + (ex-data ei))))) + +(def retrieve-impl (std-crud/retrieve-fn resource-name)) + +(defmethod crud/retrieve resource-name + [request] + (handler request)) + +(def edit-impl (std-crud/edit-fn resource-name)) + +(defmethod crud/edit resource-name + [request] + (edit-impl request)) + +(def delete-impl (std-crud/delete-fn resource-name)) + +(defmethod crud/delete resource-name + [request] + (delete-impl request)) + +(def query-impl (std-crud/query-fn resource-name collection-acl collection-uri resource-tag)) + +(defmethod crud/query resource-name + [request] + (query-impl request)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj index 07379a0d9..55bb412e0 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj @@ -14,6 +14,7 @@ [clojure.tools.logging :as log] [com.sixsq.slipstream.ssclj.util.sse :as sse] [clojure.core.async :as async] + [zookeeper :as zk] ) (:import (clojure.lang ExceptionInfo))) @@ -34,6 +35,14 @@ :rules [{:principal "USER" :type "ROLE" :right "MODIFY"}]}) +(def port 2181) + +(defn connect + ([] (connect port)) + ([port] + (zk/connect (str "127.0.0.1:" port)))) + +(def client (connect)) ;; ;; multimethods for validation and operations ;; @@ -56,17 +65,25 @@ [request] (add-impl request)) +(def node "/hello") + +(defn get-data + "Get data, as string, from the znode" + [client path] + (String. (:data (zk/data client path)))) + +(defn watch-fn [event-ch {:keys [event-type path :as zk-event]}] + (when (= event-type :NodeDataChanged) + (let [event {:id (java.util.UUID/randomUUID) + :name "foo" + :data (get-data client path)}] + (async/>!! event-ch event))) + (zk/data client node :watcher (partial watch-fn event-ch))) + (def handler (sse/event-channel-handler (fn [request response raise event-ch] - (async/go - (dotimes [i 20] - (let [event {:id (java.util.UUID/randomUUID) - :name "foo" - :data "bar"}] - (async/>! event-ch event) - (async/ Date: Tue, 18 Jul 2017 18:27:52 +0200 Subject: [PATCH 06/46] run with action prototype working and some unit test --- .../com/sixsq/slipstream/ssclj/app/server.clj | 5 +- .../ssclj/resources/common/utils.clj | 4 +- .../sixsq/slipstream/ssclj/resources/run.clj | 85 +++++++++---------- .../slipstream/ssclj/resources/spec/run.cljc | 32 +++++++ .../slipstream/ssclj/util/zookeeper_utils.clj | 7 +- .../ssclj/resources/spec/run_test.cljc | 43 ++++++++++ 6 files changed, 128 insertions(+), 48 deletions(-) create mode 100644 ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc create mode 100644 ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/run_test.cljc diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/app/server.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/app/server.clj index 2af533778..e72d3b3f1 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/app/server.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/app/server.clj @@ -24,7 +24,8 @@ [com.sixsq.slipstream.ssclj.app.graphite :as graphite] [com.sixsq.slipstream.db.impl :as db] [com.sixsq.slipstream.db.es.es-binding :as esb] - [com.sixsq.slipstream.ssclj.resources.common.dynamic-load :as resources])) + [com.sixsq.slipstream.ssclj.resources.common.dynamic-load :as resources] + [com.sixsq.slipstream.ssclj.util.zookeeper-utils :as zku])) (defn- set-persistence-impl [] @@ -72,6 +73,8 @@ (esb/set-client! (esb/create-client)) + (zku/set-client! (zku/create-client)) + (set-persistence-impl) (resources/initialize) (let [handler (create-ring-handler)] diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/common/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/common/utils.clj index c5a5a1fe5..2212c7b80 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/common/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/common/utils.clj @@ -62,12 +62,14 @@ [m] (dissoc m :id :created :updated :resourceURI :operations)) +(defn time-now [] (time-fmt/unparse (:date-time time-fmt/formatters) (time/now))) + (defn update-timestamps "Sets the updated attribute and optionally the created attribute in the request. The created attribute is only set if the existing value is missing or evaluates to false." [data] - (let [updated (time-fmt/unparse (:date-time time-fmt/formatters) (time/now)) + (let [updated (time-now) created (or (:created data) updated)] (assoc data :created created :updated updated))) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj index ecebe2a6e..27324ccee 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj @@ -12,10 +12,8 @@ [com.sixsq.slipstream.util.response :as sr] [com.sixsq.slipstream.db.impl :as db] [clojure.tools.logging :as log] - [com.sixsq.slipstream.ssclj.util.sse :as sse] [clojure.core.async :as async] - [zookeeper :as zk] - ) + [clj-time.core :as time]) (:import (clojure.lang ExceptionInfo))) (def ^:const resource-name "Run") @@ -35,19 +33,12 @@ :rules [{:principal "USER" :type "ROLE" :right "MODIFY"}]}) -(def port 2181) -(defn connect - ([] (connect port)) - ([port] - (zk/connect (str "127.0.0.1:" port)))) - -(def client (connect)) ;; ;; multimethods for validation and operations ;; -(def validate-fn (u/create-spec-validation-fn :cimi/run-parameter)) +(def validate-fn (u/create-spec-validation-fn :cimi/run)) (defmethod crud/validate resource-uri [resource] (validate-fn resource)) @@ -65,43 +56,11 @@ [request] (add-impl request)) -(def node "/hello") - -(defn get-data - "Get data, as string, from the znode" - [client path] - (String. (:data (zk/data client path)))) - -(defn watch-fn [event-ch {:keys [event-type path :as zk-event]}] - (when (= event-type :NodeDataChanged) - (let [event {:id (java.util.UUID/randomUUID) - :name "foo" - :data (get-data client path)}] - (async/>!! event-ch event))) - (zk/data client node :watcher (partial watch-fn event-ch))) - -(def handler - (sse/event-channel-handler - (fn [request response raise event-ch] - (zk/data client node :watcher (partial watch-fn event-ch))) - {:on-client-disconnect #(log/debug "sse/on-client-disconnect: " %)})) - -(defn retrieve-fn - [resource-name] - (fn [{{uuid :uuid} :params :as request}] - (try - (-> (str (u/de-camelcase resource-name) "/" uuid) - (db/retrieve request) - (a/can-view? request) - (crud/set-operations request)) - (catch ExceptionInfo ei - (ex-data ei))))) - (def retrieve-impl (std-crud/retrieve-fn resource-name)) (defmethod crud/retrieve resource-name [request] - (handler request)) + (retrieve-impl request)) (def edit-impl (std-crud/edit-fn resource-name)) @@ -120,3 +79,41 @@ (defmethod crud/query resource-name [request] (query-impl request)) + +;; +;; override the operations method to add describe action +;; + +(defmethod crud/set-operations resource-uri + [{:keys [id resourceURI] :as resource} request] + (let [href (str id "/start")] + (try + (a/can-modify? resource request) + (let [ops (if (.endsWith resourceURI "Collection") + [{:rel (:add c/action-uri) :href id}] + [{:rel (:edit c/action-uri) :href id} + {:rel (:delete c/action-uri) :href id} + {:rel (:start c/action-uri) :href href}])] + (assoc resource :operations ops)) + (catch Exception e + (if (.endsWith resourceURI "Collection") + (dissoc resource :operations) + (assoc resource :operations [{:rel (:start c/action-uri) :href href}])))))) + +;; +;; actions +;; + +(defmethod crud/do-action [resource-url "start"] + [{{uuid :uuid} :params :as request}] + (try + (let [current (-> (str (u/de-camelcase resource-name) "/" uuid) + (db/retrieve request) + (a/can-modify? request)) + updated-run (assoc current :start-time (u/time-now))] + (-> updated-run + (u/update-timestamps) + (crud/validate) + (db/edit request))) + (catch ExceptionInfo ei + (ex-data ei)))) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc new file mode 100644 index 000000000..dc5780de4 --- /dev/null +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc @@ -0,0 +1,32 @@ +(ns com.sixsq.slipstream.ssclj.resources.spec.run + (:require + [clojure.spec.alpha :as s] + [clojure.spec.gen.alpha :as gen] + [clojure.string :as str] + [com.sixsq.slipstream.ssclj.util.spec :as su] + [com.sixsq.slipstream.ssclj.resources.spec.common :as c])) + +(s/def :cimi.run/module-resource-uri :cimi.core/uri) +(s/def :cimi.run/type #{"Run" "Orchestration" "Machine"}) +(s/def :cimi.run/category #{"Image" "Deployment"}) +(s/def :cimi.run/start-time :cimi.core/timestamp) +(s/def :cimi.run/end-time :cimi.core/timestamp) +(s/def :cimi.run/last-state-change-time :cimi.core/timestamp) +(s/def :cimi.run/mutable boolean?) +(s/def :cimi.run/state #{"init" "provisioning" "executing" "sending report" "finalyzing" "terminated" "canceled" "done"}) +(s/def :cimi.run/parameters (su/constrained-map keyword? string?)) +(s/def :cimi.run/user-choices (su/constrained-map keyword? string?)) + +(s/def :cimi/run + (su/only-keys-maps c/common-attrs + {:req-un [:cimi.common/id + :cimi.run/module-resource-uri + :cimi.run/type + :cimi.run/category + :cimi.run/mutable + :cimi.run/parameters + :cimi.run/user-choices] + :opt-un [:cimi.run/start-time + :cimi.run/end-time + :cimi.run/last-state-change-time + :cimi.run/state]})) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper_utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper_utils.clj index a2d0f0683..650f55720 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper_utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper_utils.clj @@ -1,5 +1,8 @@ (ns com.sixsq.slipstream.ssclj.util.zookeeper-utils - (:require [zookeeper :as zk])) + (:require + [environ.core :as env] + [clojure.tools.logging :as log] + [zookeeper :as zk])) (def ^:dynamic *client*) @@ -7,7 +10,7 @@ [client] (alter-var-root #'*client* (constantly client))) -(defn create-zk-client +(defn create-client "Creates a client connecting to an instance of Zookeeper Parameters (host and port) are taken from environment variables." [] diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/run_test.cljc b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/run_test.cljc new file mode 100644 index 000000000..bd737f6e3 --- /dev/null +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/run_test.cljc @@ -0,0 +1,43 @@ +(ns com.sixsq.slipstream.ssclj.resources.spec.run-test + (:require + [clojure.test :refer :all] + [clojure.spec.alpha :as s] + [com.sixsq.slipstream.ssclj.resources.run :as r])) + +(def valid-acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:type "ROLE", + :principal "ADMIN", + :right "ALL"}]}) + +(deftest check-RunInfo + (let [timestamp "1964-08-25T10:00:00.0Z" + run {:id (str r/resource-url "/run-uuid") + :created timestamp + :updated timestamp + :resourceURI r/resource-uri + :acl valid-acl + :module-resource-uri "module/examples/tutorials/service-testing/system/1940" + :category "Deployment" + :type "Orchestration" + :mutable false + :parameters {:a "b"} + :user-choices {}}] + + (is (= true (s/valid? :cimi/run run))) + + (are [expect-fn arg] (expect-fn (s/valid? :cimi/run arg)) + true? run + false? (dissoc run :created) + false? (dissoc run :updated) + false? (dissoc run :acl) + false? (dissoc run :module-resource-uri) + false? (dissoc run :category) + false? (dissoc run :type) + false? (update run :category (constantly "bonjour")) + false? (dissoc run :mutable) + false? (assoc run :other "abc") + true? (assoc run :user-choices {:a "a" :b "b"}) + false? (assoc run :user-choices {:a []}) + false? (dissoc run :parameters) + true? (assoc run :start-time timestamp)))) From 6cb9db04afc7af53113a9b54b21e3c2cb4f317d9 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Wed, 19 Jul 2017 18:31:50 +0200 Subject: [PATCH 07/46] wip --- .../com/sixsq/slipstream/ssclj/app/server.clj | 2 +- .../sixsq/slipstream/ssclj/resources/run.clj | 68 ++++++++++++++++-- .../ssclj/resources/run_parameter.clj | 32 ++++++--- .../ssclj/resources/spec/common.cljc | 2 + .../slipstream/ssclj/resources/spec/run.cljc | 69 ++++++++++++++----- .../ssclj/resources/spec/run_parameter.cljc | 14 +++- .../ssclj/resources/zk/run/state_machine.clj | 31 +++++++++ .../ssclj/resources/zk/run/utils.clj | 38 ++++++++++ .../{zookeeper_utils.clj => zookeeper.clj} | 11 ++- .../ssclj/resources/spec/common_test.cljc | 11 +++ .../ssclj/resources/spec/run_test.cljc | 21 +++--- 11 files changed, 256 insertions(+), 43 deletions(-) create mode 100644 ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/state_machine.clj create mode 100644 ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj rename ssclj/jar/src/com/sixsq/slipstream/ssclj/util/{zookeeper_utils.clj => zookeeper.clj} (69%) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/app/server.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/app/server.clj index e72d3b3f1..d9a3dee07 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/app/server.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/app/server.clj @@ -25,7 +25,7 @@ [com.sixsq.slipstream.db.impl :as db] [com.sixsq.slipstream.db.es.es-binding :as esb] [com.sixsq.slipstream.ssclj.resources.common.dynamic-load :as resources] - [com.sixsq.slipstream.ssclj.util.zookeeper-utils :as zku])) + [com.sixsq.slipstream.ssclj.util.zookeeper :as zku])) (defn- set-persistence-impl [] diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj index 27324ccee..50e57221a 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj @@ -1,11 +1,15 @@ (ns com.sixsq.slipstream.ssclj.resources.run (:require + [clojure.stacktrace :as st] [clojure.spec.alpha :as s] [com.sixsq.slipstream.ssclj.resources.spec.run] [com.sixsq.slipstream.ssclj.resources.common.std-crud :as std-crud] [com.sixsq.slipstream.ssclj.resources.common.schema :as c] [com.sixsq.slipstream.ssclj.resources.common.crud :as crud] [com.sixsq.slipstream.ssclj.resources.common.utils :as u] + [com.sixsq.slipstream.ssclj.resources.zk.run.utils :as zru] + [com.sixsq.slipstream.ssclj.resources.run-parameter :as rp] + [com.sixsq.slipstream.ssclj.resources.run.state-machine :as rsm] [com.sixsq.slipstream.auth.acl :as a] [superstring.core :as str] [ring.util.response :as r] @@ -50,7 +54,49 @@ ;; CRUD operations ;; -(def add-impl (std-crud/add-fn resource-name collection-acl resource-uri)) + +(defmethod crud/new-identifier resource-name + [json _] + #_json ;TODO uncomment + (assoc json :id (u/random-uuid)) ;TODO REMOVE + ) ; keep id of java run + +(defn create-parameter [run-parameter] + (try + (let [ + request {:params {:resource-name rp/resource-url} + :body run-parameter} + {:keys [status]} (crud/add request)] + (case status + 201 (log/info "created run-parameter:" run-parameter) + (log/info "unexpected status code when creating run-parameter:" status))) + (catch Exception e + (log/warn "error when creating session-template/internal resource: " (str e) "\n" + (with-out-str (st/print-cause-trace e))))) + ) + +(defn create-parameters [{nodes :nodes run-id :id state :state}] + (create-parameter {:run-id run-id :name "state" :value state}) + (doseq [n nodes] + () + (let [node-name (name (key n)) + multiplicity (get-in (val n) [:parameters :multiplicity :default-value])] + (doseq [i (range 1 (inc multiplicity))] + (create-parameter {:run-id run-id :node-name node-name :node-index i :name "vmstate" :value "init"}) + )))) + +(defn add-impl [{body :body :as request}] + (a/can-modify? {:acl collection-acl} request) + (let [new-run (-> body + u/strip-service-attrs + (crud/new-identifier resource-name) + (assoc :resourceURI resource-uri) + u/update-timestamps + (crud/add-acl request) + (assoc :state rsm/initial-state))] + (db/add resource-name (crud/validate new-run) {}) + (create-parameters new-run) + )) (defmethod crud/add resource-name [request] @@ -104,16 +150,24 @@ ;; actions ;; +(defn add-start-time [run] + (let [now (u/time-now)] + (assoc run :start-time now))) + (defmethod crud/do-action [resource-url "start"] [{{uuid :uuid} :params :as request}] (try (let [current (-> (str (u/de-camelcase resource-name) "/" uuid) (db/retrieve request) (a/can-modify? request)) - updated-run (assoc current :start-time (u/time-now))] - (-> updated-run - (u/update-timestamps) - (crud/validate) - (db/edit request))) + response (-> current + (add-start-time) + (u/update-timestamps) + (crud/validate) + (db/edit request))] + ;(zru/create-zk-run current) + response + ) (catch ExceptionInfo ei - (ex-data ei)))) \ No newline at end of file + (ex-data ei))) + ) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj index 55bb412e0..be493f834 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj @@ -15,6 +15,7 @@ [com.sixsq.slipstream.ssclj.util.sse :as sse] [clojure.core.async :as async] [zookeeper :as zk] + [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] ) (:import (clojure.lang ExceptionInfo))) @@ -35,14 +36,7 @@ :rules [{:principal "USER" :type "ROLE" :right "MODIFY"}]}) -(def port 2181) -(defn connect - ([] (connect port)) - ([port] - (zk/connect (str "127.0.0.1:" port)))) - -(def client (connect)) ;; ;; multimethods for validation and operations ;; @@ -55,11 +49,33 @@ (defmethod crud/add-acl resource-uri [resource request] (a/add-acl resource request)) + ;; ;; CRUD operations ;; -(def add-impl (std-crud/add-fn resource-name collection-acl resource-uri)) +(defn add-impl [{:keys [body] :as request}] + (a/can-modify? {:acl collection-acl} request) + (let [rp (-> body + u/strip-service-attrs + (crud/new-identifier resource-name) + (assoc :resourceURI resource-uri) + u/update-timestamps + (crud/add-acl request) + crud/validate) + run-id (:run-id body) + node-name (:node-name body) + node-index (:node-index body) + name (:name body) + value (:value body) + node-path (cond + (and run-id node-name node-index) (str "/runs/" run-id "/" node-name "/" node-index "/" name) + (and run-id node-name) (str "/runs/" run-id "/" node-name "/" name) + (and run-id) (str "/runs/" run-id "/" name)) + ] + (uzk/create-all node-path :persistent? true) + (uzk/set-data node-path value) + )) (defmethod crud/add resource-name [request] diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/common.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/common.cljc index a7c7d0542..5c42c1279 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/common.cljc +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/common.cljc @@ -50,6 +50,8 @@ (s/def :cimi.core/resource-type :cimi.core/kebab-identifier) +(s/def :cimi.core/zero-or-pos-int #(and (int? %) (> % -1))) + ;; ;; A resource href is the concatenation of a resource type and resource identifier separated ;; with a slash. The later part is optional for singleton resources like the cloud-entry-point. diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc index dc5780de4..0c0c25945 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc @@ -14,19 +14,56 @@ (s/def :cimi.run/last-state-change-time :cimi.core/timestamp) (s/def :cimi.run/mutable boolean?) (s/def :cimi.run/state #{"init" "provisioning" "executing" "sending report" "finalyzing" "terminated" "canceled" "done"}) -(s/def :cimi.run/parameters (su/constrained-map keyword? string?)) -(s/def :cimi.run/user-choices (su/constrained-map keyword? string?)) - -(s/def :cimi/run - (su/only-keys-maps c/common-attrs - {:req-un [:cimi.common/id - :cimi.run/module-resource-uri - :cimi.run/type - :cimi.run/category - :cimi.run/mutable - :cimi.run/parameters - :cimi.run/user-choices] - :opt-un [:cimi.run/start-time - :cimi.run/end-time - :cimi.run/last-state-change-time - :cimi.run/state]})) + +(s/def :cimi.run.parameter/description string?) +(s/def :cimi.run.parameter/default-value string?) +(s/def :cimi.run.parameter/user-choice-value string?) + +(s/def :cimi.run/parameter (su/only-keys-maps {:opt-un [:cimi.run.parameter/description + :cimi.run.parameter/default-value + :cimi.run.parameter/user-choice-value]})) + +(s/def :cimi.run.node/cpu.nb :cimi.run/parameter) +(s/def :cimi.run.node/ram.GB :cimi.run/parameter) +(s/def :cimi.run.node/disk.GB :cimi.run/parameter) +(s/def :cimi.run.node/multiplicity :cimi.run/parameter) +(s/def :cimi.run.node/max-provisioning-failures :cimi.run/parameter) +(s/def :cimi.run.node/cloudservice :cimi.run/parameter) + +(s/def :cimi.run/parameters + (su/only-keys-maps + {:req-un [:cimi.run.node/cloudservice] + :opt-un [:cimi.run.node/multiplicity + :cimi.run.node/max-provisioning-failures + :cimi.run.node/cpu.nb + :cimi.run.node/ram.GB + :cimi.run.node/disk.GB]})) + +(s/def :cimi.run.runtime-parameter/mapped-to :cimi.core/nonblank-string) + +(s/def :cimi.run.node/runtime-parameter (su/only-keys-maps + {:opt-un [:cimi.run.parameter/description + :cimi.run.parameter/default-value + :cimi.run.parameter/user-choice-value + :cimi.run.runtime-parameter/mapped-to]})) + +(s/def :cimi.run/runtime-parameters + (su/constrained-map keyword? :cimi.run.node/runtime-parameter)) + +(s/def :cimi.run/node (su/only-keys-maps {:req-un [:cimi.run/parameters] + :opt-un [:cimi.run/runtime-parameters]})) + +(s/def :cimi.run/nodes (su/constrained-map keyword? :cimi.run/node)) + +(def run-attrs {:req-un [#_:cimi.common/id ;TODO uncomment + :cimi.run/module-resource-uri + :cimi.run/type + :cimi.run/category + :cimi.run/mutable + :cimi.run/nodes] + :opt-un [:cimi.run/start-time + :cimi.run/end-time + :cimi.run/last-state-change-time + :cimi.run/state]}) + +(s/def :cimi/run (su/only-keys-maps c/common-attrs run-attrs)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc index 9f0c60025..30020c315 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc @@ -6,8 +6,18 @@ [com.sixsq.slipstream.ssclj.util.spec :as su] [com.sixsq.slipstream.ssclj.resources.spec.common :as c])) +(s/def :cimi.run-parameter/run-id :cimi.core/nonblank-string) +(s/def :cimi.run-parameter/name :cimi.core/nonblank-string) +(s/def :cimi.run-parameter/value string?) +(s/def :cimi.run-parameter/node-name :cimi.core/nonblank-string) +(s/def :cimi.run-parameter/node-index pos-int?) +(s/def :cimi.run-parameter/description string?) + (s/def :cimi/run-parameter (su/only-keys-maps c/common-attrs - {:req-un [:cimi.common/acl + {:req-un [:cimi.run-parameter/run-id :cimi.run-parameter/name - :cimi.run-parameter/run-id]})) + :cimi.run-parameter/value] + :opt-un [:cimi.run-parameter/node-name + :cimi.run-parameter/node-index + :cimi.run-parameter/description]})) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/state_machine.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/state_machine.clj new file mode 100644 index 000000000..5c331877c --- /dev/null +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/state_machine.clj @@ -0,0 +1,31 @@ +(ns com.sixsq.slipstream.ssclj.resources.run.state-machine + "This namespace uses ZooKeeper to create a distributed system to host the state of a run. Each VM is represented + by an index node under its corresponding node. As each VM reports its current state completed, the corresponding + index znode (i.e. ZooKeeper node) is removed from the structure. When no node remains, it means all VMs have + reported, which means the state machine can move to its next state. + + This design includes the following important goals: + 1. state completion should be idem potent. This is important such that if the client has a doubt about the + completness of its call to report completion, it can be performed again, without risk in changing the the state + machine (e.g. reporting as completed the next state in the run) + 2. no pulling is required to get the next state transition, since the system includes a notification mechanism. + 3. the system is fast, with no loops nor expensive state investigation. It is even constant wrt the size of the run + 4. works in a share nothing pattern, meaning that this namespace can be distributed over the network. For this, the + new buddy-circle namespace is used to ensure automatic recovery of partial transition, is case of failure. This + means this namespace can be packaged as a micro-service, and deployed/removed as required, with no special + coordination required. + + The topology of the run is persisted as an edn structure inside the ./topology znode. This can be changed as nodes + come and go, for scalable deployments." + (:require [zookeeper :as zk])) + +;; State machine states +(def initial-state "init") +(def valid-transitions + {initial-state ["provisioning"] + "provisioning" ["executing"] + "executing" ["sending report"] + "sending report" ["ready"] + "ready" ["provisioning" ] + "finalyzing" ["terminated"] + "terminated" []}) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj new file mode 100644 index 000000000..0aefac78d --- /dev/null +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj @@ -0,0 +1,38 @@ +(ns com.sixsq.slipstream.ssclj.resources.zk.run.utils + (:require [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] + [zookeeper :as zk])) + + +(def runs-path "/runs") + +(defn run-id-path [run-id] + (str runs-path "/" run-id)) + +(defn nodes-path [run-id] + (str (run-id-path run-id) "/nodes")) + +(defn node-path + [run-id node-name] + (str (nodes-path run-id) "/" node-name)) + +(defn indexed-node-path [run-id node-name node-index] + (str (node-path run-id node-name) "/" node-index)) + +(defn create-run [run-id] + (uzk/create (run-id-path run-id) :persistent? true)) + +#_(defn create-zk-run [{run-id :id nodes :nodes :as run}] + (doseq [n nodes] + (zk/create-all uzk/*client* (node-path run-id (key n)) :persistent? true) + (let [{:keys [params multiplicity mapping]} (val n)] + (doseq [i (range 1 (inc multiplicity))] + (zk/create-all client (rzu/params-znode-path run-id (key n) i) :persistent? true) + (doseq [p params] + (if-let [default (-> p val :default)] + (zk/create client (rzu/param-znode-path run-id (key n) i (key p)) + :data (zdata/to-bytes default) + :persistent? true) + (zk/create client (rzu/param-znode-path run-id (key n) i (key p)) + :persistent? true)))))) + (rsm/create client run-id module params) + ) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper_utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj similarity index 69% rename from ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper_utils.clj rename to ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj index 650f55720..e67fd8627 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper_utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj @@ -1,4 +1,4 @@ -(ns com.sixsq.slipstream.ssclj.util.zookeeper-utils +(ns com.sixsq.slipstream.ssclj.util.zookeeper (:require [environ.core :as env] [clojure.tools.logging :as log] @@ -18,3 +18,12 @@ (log/info "creating zookeeper client:" zk-endpoints) (zk/connect zk-endpoints))) + +(def create-all (partial zk/create-all *client*)) + +(def create (partial zk/create *client*)) + +(def set-data (partial zk/set-data *client*)) + +(def get-data (partial zk/data *client*)) + diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/common_test.cljc b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/common_test.cljc index da8e2a9da..5e756f4be 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/common_test.cljc +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/common_test.cljc @@ -156,3 +156,14 @@ true? (dissoc maximal :description) true? (dissoc maximal :properties) false? (assoc maximal :bad "BAD")))) + +(deftest check-zero-or-pos-int + (are [expect-fn arg] (expect-fn (s/valid? :cimi.core/zero-or-pos-int arg)) + true? 0 + true? 1 + true? 1000 + false? -1 + false? -1000 + false? 1.2 + false? "" + false? {})) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/run_test.cljc b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/run_test.cljc index bd737f6e3..4a307e84b 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/run_test.cljc +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/run_test.cljc @@ -21,13 +21,20 @@ :category "Deployment" :type "Orchestration" :mutable false - :parameters {:a "b"} - :user-choices {}}] - - (is (= true (s/valid? :cimi/run run))) + :nodes {:node1 {:parameters {:cloudservice {:description "p1 description" + :default-value "abc" + :user-choice-value "ABC"} + :multiplicity {:default-value "1"}} + :runtime-parameters {:p1 {:description "p1 description" + :default-value "abc" + :user-choice-value "ABC" + :mapped-to "a"}}} + :node2 {:parameters {:cloudservice {:description "param1 description" + :default-value "abc"}}}}}] (are [expect-fn arg] (expect-fn (s/valid? :cimi/run arg)) true? run + ;false? (dissoc run :id) ;TODO uncomment false? (dissoc run :created) false? (dissoc run :updated) false? (dissoc run :acl) @@ -37,7 +44,5 @@ false? (update run :category (constantly "bonjour")) false? (dissoc run :mutable) false? (assoc run :other "abc") - true? (assoc run :user-choices {:a "a" :b "b"}) - false? (assoc run :user-choices {:a []}) - false? (dissoc run :parameters) - true? (assoc run :start-time timestamp)))) + false? (dissoc run :nodes) + true? (assoc run :start-time timestamp)))) From 8f0ed09599ed91712129c3937413db6f8bd1315f Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Thu, 20 Jul 2017 14:44:05 +0200 Subject: [PATCH 08/46] wip run parameters working with zookeeper for creation --- .../sixsq/slipstream/ssclj/resources/run.clj | 31 ++++++------ .../ssclj/resources/run_parameter.clj | 48 ++++++++++--------- .../slipstream/ssclj/resources/spec/run.cljc | 4 +- .../ssclj/resources/zk/run/state_machine.clj | 2 +- .../sixsq/slipstream/ssclj/util/zookeeper.clj | 22 +++++++-- 5 files changed, 63 insertions(+), 44 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj index 50e57221a..524bdc665 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj @@ -9,7 +9,7 @@ [com.sixsq.slipstream.ssclj.resources.common.utils :as u] [com.sixsq.slipstream.ssclj.resources.zk.run.utils :as zru] [com.sixsq.slipstream.ssclj.resources.run-parameter :as rp] - [com.sixsq.slipstream.ssclj.resources.run.state-machine :as rsm] + [com.sixsq.slipstream.ssclj.resources.zk.run.state-machine :as rsm] [com.sixsq.slipstream.auth.acl :as a] [superstring.core :as str] [ring.util.response :as r] @@ -61,31 +61,32 @@ (assoc json :id (u/random-uuid)) ;TODO REMOVE ) ; keep id of java run -(defn create-parameter [run-parameter] +(defn create-parameter [identity run-parameter] (try (let [ request {:params {:resource-name rp/resource-url} + :identity identity :body run-parameter} - {:keys [status]} (crud/add request)] + {:keys [status body]} (crud/add request)] (case status - 201 (log/info "created run-parameter:" run-parameter) - (log/info "unexpected status code when creating run-parameter:" status))) + 201 (log/info "created run-parameter: " body) + (log/info "unexpected status code when creating run-parameter resource:" status))) (catch Exception e - (log/warn "error when creating session-template/internal resource: " (str e) "\n" + (log/warn "error when creating run-parameter resource: " (str e) "\n" (with-out-str (st/print-cause-trace e))))) ) -(defn create-parameters [{nodes :nodes run-id :id state :state}] - (create-parameter {:run-id run-id :name "state" :value state}) +(defn create-parameters [identity {nodes :nodes run-id :id state :state}] + (create-parameter identity {:run-id run-id :name "state" :value state}) (doseq [n nodes] () (let [node-name (name (key n)) - multiplicity (get-in (val n) [:parameters :multiplicity :default-value])] + multiplicity (read-string (get-in (val n) [:parameters :multiplicity :default-value]))] (doseq [i (range 1 (inc multiplicity))] - (create-parameter {:run-id run-id :node-name node-name :node-index i :name "vmstate" :value "init"}) + (create-parameter identity {:run-id run-id :node-name node-name :node-index i :name "vmstate" :value "init"}) )))) -(defn add-impl [{body :body :as request}] +(defn add-impl [{body :body identity :identity :as request}] (a/can-modify? {:acl collection-acl} request) (let [new-run (-> body u/strip-service-attrs @@ -93,10 +94,10 @@ (assoc :resourceURI resource-uri) u/update-timestamps (crud/add-acl request) - (assoc :state rsm/initial-state))] - (db/add resource-name (crud/validate new-run) {}) - (create-parameters new-run) - )) + (assoc :state rsm/initial-state)) + response (db/add resource-name (crud/validate new-run) {})] + (create-parameters identity new-run) + response)) (defmethod crud/add resource-name [request] diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj index be493f834..830439d67 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj @@ -63,6 +63,7 @@ u/update-timestamps (crud/add-acl request) crud/validate) + response (db/add resource-name rp {}) run-id (:run-id body) node-name (:node-name body) node-index (:node-index body) @@ -75,32 +76,33 @@ ] (uzk/create-all node-path :persistent? true) (uzk/set-data node-path value) + response )) (defmethod crud/add resource-name [request] (add-impl request)) - -(def node "/hello") - -(defn get-data - "Get data, as string, from the znode" - [client path] - (String. (:data (zk/data client path)))) - -(defn watch-fn [event-ch {:keys [event-type path :as zk-event]}] - (when (= event-type :NodeDataChanged) - (let [event {:id (java.util.UUID/randomUUID) - :name "foo" - :data (get-data client path)}] - (async/>!! event-ch event))) - (zk/data client node :watcher (partial watch-fn event-ch))) - -(def handler - (sse/event-channel-handler - (fn [request response raise event-ch] - (zk/data client node :watcher (partial watch-fn event-ch))) - {:on-client-disconnect #(log/debug "sse/on-client-disconnect: " %)})) +; +;(def node "/hello") +; +;(defn get-data +; "Get data, as string, from the znode" +; [client path] +; (String. (:data (zk/data client path)))) +; +;(defn watch-fn [event-ch {:keys [event-type path :as zk-event]}] +; (when (= event-type :NodeDataChanged) +; (let [event {:id (java.util.UUID/randomUUID) +; :name "foo" +; :data (get-data client path)}] +; (async/>!! event-ch event))) +; (zk/data client node :watcher (partial watch-fn event-ch))) +; +;(def handler +; (sse/event-channel-handler +; (fn [request response raise event-ch] +; (zk/data client node :watcher (partial watch-fn event-ch))) +; {:on-client-disconnect #(log/debug "sse/on-client-disconnect: " %)})) (defn retrieve-fn [resource-name] @@ -117,7 +119,9 @@ (defmethod crud/retrieve resource-name [request] - (handler request)) + #_(handler request) + (retrieve-impl request) + ) (def edit-impl (std-crud/edit-fn resource-name)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc index 0c0c25945..1bca0b1db 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc @@ -6,6 +6,7 @@ [com.sixsq.slipstream.ssclj.util.spec :as su] [com.sixsq.slipstream.ssclj.resources.spec.common :as c])) +(s/def :cimi.run/id :cimi.core/nonblank-string) ;TODO enhance (s/def :cimi.run/module-resource-uri :cimi.core/uri) (s/def :cimi.run/type #{"Run" "Orchestration" "Machine"}) (s/def :cimi.run/category #{"Image" "Deployment"}) @@ -61,7 +62,8 @@ :cimi.run/category :cimi.run/mutable :cimi.run/nodes] - :opt-un [:cimi.run/start-time + :opt-un [:cimi.run/id + :cimi.run/start-time :cimi.run/end-time :cimi.run/last-state-change-time :cimi.run/state]}) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/state_machine.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/state_machine.clj index 5c331877c..b5086203a 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/state_machine.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/state_machine.clj @@ -1,4 +1,4 @@ -(ns com.sixsq.slipstream.ssclj.resources.run.state-machine +(ns com.sixsq.slipstream.ssclj.resources.zk.run.state-machine "This namespace uses ZooKeeper to create a distributed system to host the state of a run. Each VM is represented by an index node under its corresponding node. As each VM reports its current state completed, the corresponding index znode (i.e. ZooKeeper node) is removed from the structure. When no node remains, it means all VMs have diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj index e67fd8627..86e310823 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj @@ -17,13 +17,25 @@ (let [zk-endpoints (or (env/env :zk-endpoints) "localhost:2181")] (log/info "creating zookeeper client:" zk-endpoints) - (zk/connect zk-endpoints))) + (zk/connect zk-endpoints :timeout-msec 60000))) -(def create-all (partial zk/create-all *client*)) +(defn create-all [path & options] + (apply zk/create-all *client* path options)) -(def create (partial zk/create *client*)) +(defn create [path & options] + (apply zk/create *client* path options)) -(def set-data (partial zk/set-data *client*)) +(defn get-data [path & options] + (let [result (apply zk/data *client* path options) + data (:data result) + value (when (-> data nil? not) (String. data))] + (assoc result :data value))) -(def get-data (partial zk/data *client*)) +(defn get-version + [path] + (-> (get-data path) :stat :version)) +(defn set-data [path value & options] + (let [version (get-version path) + data (.getBytes (str value) "UTF-8")] + (apply zk/set-data *client* path data version options))) From 28ae980365eb1fd47fadeaae586c1fb29ef6d603 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Thu, 20 Jul 2017 18:00:23 +0200 Subject: [PATCH 09/46] wip run parameter retrieve value from zookeeper --- .../ssclj/resources/run_parameter.clj | 59 ++++++++++--------- .../ssclj/resources/spec/run_parameter.cljc | 6 +- .../ssclj/resources/zk/run/utils.clj | 39 ++++++++---- 3 files changed, 59 insertions(+), 45 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj index 830439d67..485c205d1 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj @@ -8,14 +8,14 @@ [com.sixsq.slipstream.ssclj.resources.common.utils :as u] [com.sixsq.slipstream.auth.acl :as a] [superstring.core :as str] - [ring.util.response :as r] - [com.sixsq.slipstream.util.response :as sr] + [com.sixsq.slipstream.util.response :as r] [com.sixsq.slipstream.db.impl :as db] [clojure.tools.logging :as log] [com.sixsq.slipstream.ssclj.util.sse :as sse] [clojure.core.async :as async] [zookeeper :as zk] [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] + [com.sixsq.slipstream.ssclj.resources.zk.run.utils :as zkru] ) (:import (clojure.lang ExceptionInfo))) @@ -56,24 +56,21 @@ (defn add-impl [{:keys [body] :as request}] (a/can-modify? {:acl collection-acl} request) - (let [rp (-> body - u/strip-service-attrs - (crud/new-identifier resource-name) - (assoc :resourceURI resource-uri) - u/update-timestamps - (crud/add-acl request) - crud/validate) - response (db/add resource-name rp {}) + (let [run-parameter (-> body + u/strip-service-attrs + (dissoc :value) + (crud/new-identifier resource-name) + (assoc :resourceURI resource-uri) + u/update-timestamps + (crud/add-acl request) + crud/validate) + response (db/add resource-name run-parameter {}) run-id (:run-id body) node-name (:node-name body) node-index (:node-index body) name (:name body) value (:value body) - node-path (cond - (and run-id node-name node-index) (str "/runs/" run-id "/" node-name "/" node-index "/" name) - (and run-id node-name) (str "/runs/" run-id "/" node-name "/" name) - (and run-id) (str "/runs/" run-id "/" name)) - ] + node-path (zkru/parameter-znode-path run-id node-name node-index name)] (uzk/create-all node-path :persistent? true) (uzk/set-data node-path value) response @@ -104,24 +101,28 @@ ; (zk/data client node :watcher (partial watch-fn event-ch))) ; {:on-client-disconnect #(log/debug "sse/on-client-disconnect: " %)})) -(defn retrieve-fn - [resource-name] - (fn [{{uuid :uuid} :params :as request}] - (try - (-> (str (u/de-camelcase resource-name) "/" uuid) - (db/retrieve request) - (a/can-view? request) - (crud/set-operations request)) - (catch ExceptionInfo ei - (ex-data ei))))) - -(def retrieve-impl (std-crud/retrieve-fn resource-name)) +(defn retrieve-impl + [{{uuid :uuid} :params :as request}] + (try + (let [run-parameter (-> (str (u/de-camelcase resource-name) "/" uuid) + (db/retrieve request) + (a/can-view? request) + (crud/set-operations request)) + run-id (:run-id run-parameter) + node-name (:node-name run-parameter) + node-index (:node-index run-parameter) + name (:name run-parameter) + value (:data (uzk/get-data (zkru/parameter-znode-path run-id node-name node-index name))) ;TODO what if data not found + response (assoc run-parameter :value value) + ] + (r/json-response response)) + (catch ExceptionInfo ei + (ex-data ei)))) (defmethod crud/retrieve resource-name [request] #_(handler request) - (retrieve-impl request) - ) + (retrieve-impl request)) (def edit-impl (std-crud/edit-fn resource-name)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc index 30020c315..328f8181a 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc @@ -16,8 +16,8 @@ (s/def :cimi/run-parameter (su/only-keys-maps c/common-attrs {:req-un [:cimi.run-parameter/run-id - :cimi.run-parameter/name - :cimi.run-parameter/value] + :cimi.run-parameter/name] :opt-un [:cimi.run-parameter/node-name :cimi.run-parameter/node-index - :cimi.run-parameter/description]})) \ No newline at end of file + :cimi.run-parameter/description + :cimi.run-parameter/value]})) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj index 0aefac78d..b46e08ee8 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj @@ -1,25 +1,38 @@ (ns com.sixsq.slipstream.ssclj.resources.zk.run.utils (:require [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] - [zookeeper :as zk])) + [zookeeper :as zk] + [clojure.string :as string])) +(def znode-separator "/") -(def runs-path "/runs") +(def runs-path (str znode-separator "runs")) -(defn run-id-path [run-id] - (str runs-path "/" run-id)) +(def nodes-txt "nodes") -(defn nodes-path [run-id] - (str (run-id-path run-id) "/nodes")) +(defn parameter-znode-path [run-id node-name node-index name] + (cond + (and run-id node-name node-index) (string/join znode-separator [runs-path run-id nodes-txt node-name node-index name]) + (and run-id node-name) (string/join znode-separator [runs-path run-id nodes-txt node-name name]) + run-id (string/join znode-separator [runs-path run-id name]))) -(defn node-path - [run-id node-name] - (str (nodes-path run-id) "/" node-name)) +;(defn run-id-path [run-id]) + +; (str runs-path "/" run-id)) +; +;(defn nodes-path [run-id] +; (str (run-id-path run-id) "/nodes")) +; +;(defn node-path +; [run-id node-name] +; (str (nodes-path run-id) "/" node-name)) +; +;(defn indexed-node-path [run-id node-name node-index] +; (str (node-path run-id node-name) "/" node-index)) +; +;(defn create-run [run-id] +; (uzk/create (run-id-path run-id) :persistent? true)) -(defn indexed-node-path [run-id node-name node-index] - (str (node-path run-id node-name) "/" node-index)) -(defn create-run [run-id] - (uzk/create (run-id-path run-id) :persistent? true)) #_(defn create-zk-run [{run-id :id nodes :nodes :as run}] (doseq [n nodes] From 5a447b07456005cf0ed1f3ea3c58d56b7e799e76 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Fri, 21 Jul 2017 14:46:46 +0200 Subject: [PATCH 10/46] wip issue with sse --- .../ssclj/resources/run_parameter.clj | 63 +++++++++---------- .../ssclj/resources/zk/run/utils.clj | 4 ++ .../sixsq/slipstream/ssclj/util/zookeeper.clj | 10 ++- 3 files changed, 41 insertions(+), 36 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj index 485c205d1..cb60e368a 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj @@ -79,50 +79,43 @@ (defmethod crud/add resource-name [request] (add-impl request)) -; -;(def node "/hello") -; -;(defn get-data -; "Get data, as string, from the znode" -; [client path] -; (String. (:data (zk/data client path)))) -; -;(defn watch-fn [event-ch {:keys [event-type path :as zk-event]}] -; (when (= event-type :NodeDataChanged) -; (let [event {:id (java.util.UUID/randomUUID) -; :name "foo" -; :data (get-data client path)}] -; (async/>!! event-ch event))) -; (zk/data client node :watcher (partial watch-fn event-ch))) -; -;(def handler -; (sse/event-channel-handler -; (fn [request response raise event-ch] -; (zk/data client node :watcher (partial watch-fn event-ch))) -; {:on-client-disconnect #(log/debug "sse/on-client-disconnect: " %)})) - -(defn retrieve-impl - [{{uuid :uuid} :params :as request}] + +(defn watch-fn [event-ch id name {:keys [event-type path :as zk-event]}] + (when (= event-type :NodeDataChanged) + (let [event {:id id + :name name + :data (uzk/get-data path :watcher (partial watch-fn event-ch id name))}] + (async/>!! event-ch event)))) + + +(defn retrieve-run-parameter [{{uuid :uuid} :params :as request}] (try (let [run-parameter (-> (str (u/de-camelcase resource-name) "/" uuid) (db/retrieve request) (a/can-view? request) (crud/set-operations request)) - run-id (:run-id run-parameter) - node-name (:node-name run-parameter) - node-index (:node-index run-parameter) - name (:name run-parameter) - value (:data (uzk/get-data (zkru/parameter-znode-path run-id node-name node-index name))) ;TODO what if data not found - response (assoc run-parameter :value value) - ] - (r/json-response response)) + value (uzk/get-data (zkru/run-parameter-znode-path run-parameter))];TODO what if data not found + (assoc run-parameter :value value)) (catch ExceptionInfo ei (ex-data ei)))) +(def retrieve-sse-impl + (sse/event-channel-handler + (fn [request response raise event-ch] + (let [{id :id name :name :as run-parameter} (retrieve-run-parameter request) + node-path (zkru/run-parameter-znode-path run-parameter)] + (uzk/get-data node-path :watcher (partial watch-fn event-ch id name)) + )) + {:on-client-disconnect #(log/debug "sse/on-client-disconnect: " %)})) + +(defn retrieve-json-impl [request] + (r/json-response (retrieve-run-parameter request))) + (defmethod crud/retrieve resource-name - [request] - #_(handler request) - (retrieve-impl request)) + [{{accept :accept} :headers :as request}] + (case accept + "text/event-stream" (retrieve-sse-impl request) + (retrieve-json-impl request))) (def edit-impl (std-crud/edit-fn resource-name)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj index b46e08ee8..8e3e345e1 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj @@ -15,6 +15,10 @@ (and run-id node-name) (string/join znode-separator [runs-path run-id nodes-txt node-name name]) run-id (string/join znode-separator [runs-path run-id name]))) +(defn run-parameter-znode-path + [{run-id :run-id node-name :node-name node-index :node-index name :name :as run-parameter}] + (parameter-znode-path run-id node-name node-index name)) + ;(defn run-id-path [run-id]) ; (str runs-path "/" run-id)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj index 86e310823..8e6253add 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj @@ -25,12 +25,20 @@ (defn create [path & options] (apply zk/create *client* path options)) -(defn get-data [path & options] +(defn get-znode [path & options] (let [result (apply zk/data *client* path options) data (:data result) value (when (-> data nil? not) (String. data))] (assoc result :data value))) +(defn get-data [path & options] + (-> (apply get-znode path options) + :data)) + +(defn get-stat [path & options] + (-> (apply get-znode path options) + :stat)) + (defn get-version [path] (-> (get-data path) :stat :version)) From 56d2acb8d3f901a6a359a05f6568e84ea35658e2 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Sat, 22 Jul 2017 12:31:49 +0200 Subject: [PATCH 11/46] fix issue with nginx buffering and accept header logic implemented --- .../ssclj/resources/run_parameter.clj | 14 ++++++++------ .../com/sixsq/slipstream/ssclj/util/sse.clj | 19 ++++++++++--------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj index cb60e368a..bd32c5eb3 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj @@ -94,7 +94,7 @@ (db/retrieve request) (a/can-view? request) (crud/set-operations request)) - value (uzk/get-data (zkru/run-parameter-znode-path run-parameter))];TODO what if data not found + value (uzk/get-data (zkru/run-parameter-znode-path run-parameter))] ;TODO what if data not found (assoc run-parameter :value value)) (catch ExceptionInfo ei (ex-data ei)))) @@ -103,9 +103,11 @@ (sse/event-channel-handler (fn [request response raise event-ch] (let [{id :id name :name :as run-parameter} (retrieve-run-parameter request) - node-path (zkru/run-parameter-znode-path run-parameter)] - (uzk/get-data node-path :watcher (partial watch-fn event-ch id name)) - )) + node-path (zkru/run-parameter-znode-path run-parameter) + event {:id id + :name name + :data (uzk/get-data node-path :watcher (partial watch-fn event-ch id name))}] + (async/>!! event-ch event))) {:on-client-disconnect #(log/debug "sse/on-client-disconnect: " %)})) (defn retrieve-json-impl [request] @@ -114,8 +116,8 @@ (defmethod crud/retrieve resource-name [{{accept :accept} :headers :as request}] (case accept - "text/event-stream" (retrieve-sse-impl request) - (retrieve-json-impl request))) + "text/event-stream" retrieve-sse-impl + retrieve-json-impl)) (def edit-impl (std-crud/edit-fn resource-name)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/sse.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/sse.clj index 098ab2d87..c65eb2114 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/sse.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/sse.clj @@ -52,7 +52,7 @@ [{:keys [event-channel response-channel heartbeat-delay on-client-disconnect raise] :as opts}] (async/go (loop [] - (let [hb-timeout (async/timeout (* 1000 heartbeat-delay)) + (let [hb-timeout (async/timeout (* 1000 heartbeat-delay)) [event port] (async/alts! [event-channel hb-timeout])] (cond (= port hb-timeout) @@ -84,16 +84,17 @@ SSE's core.async buffer can either be a fixed buffer (n) or a 0-arity function that returns a buffer." [{:keys [stream-ready-fn request respond raise heartbeat-delay bufferfn-or-n on-client-disconnect]}] - (let [heartbeat-delay (or heartbeat-delay 10) - bufferfn-or-n (or bufferfn-or-n 10) + (let [heartbeat-delay (or heartbeat-delay 10) + bufferfn-or-n (or bufferfn-or-n 10) response-channel (async/chan (if (fn? bufferfn-or-n) (bufferfn-or-n) bufferfn-or-n)) - response (-> (ring-response/response (s/->source response-channel)) - (ring-response/content-type "text/event-stream") ;; TODO: content negotiation? "text/event-stream+json"? - (ring-response/charset "UTF-8") - (ring-response/header "Connection" "close") - (ring-response/header "Cache-Control" "no-cache")) + response (-> (ring-response/response (s/->source response-channel)) + (ring-response/content-type "text/event-stream") ;; TODO: content negotiation? "text/event-stream+json"? + (ring-response/charset "UTF-8") + (ring-response/header "Connection" "close") + (ring-response/header "Cache-Control" "no-cache") + (ring-response/header "X-Accel-Buffering" "no")) ; X-Accel-Buffering needed to disable nginx buffering ;; TODO: re-create CORS support as per original: (update-in [:headers] merge (:cors-headers context)) - event-channel (async/chan (if (fn? bufferfn-or-n) (bufferfn-or-n) bufferfn-or-n))] + event-channel (async/chan (if (fn? bufferfn-or-n) (bufferfn-or-n) bufferfn-or-n))] (respond response) (async/thread (stream-ready-fn request response raise event-channel) From e6c52800142ae3bbb85957ff5c6e69725464888c Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Sun, 23 Jul 2017 17:16:10 +0200 Subject: [PATCH 12/46] run param edit set value in zk and fix issue with get-version from zookeeper --- .../ssclj/resources/run_parameter.clj | 19 ++++++++++++++++++- .../sixsq/slipstream/ssclj/util/zookeeper.clj | 2 +- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj index bd32c5eb3..96af86f3a 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj @@ -119,7 +119,24 @@ "text/event-stream" retrieve-sse-impl retrieve-json-impl)) -(def edit-impl (std-crud/edit-fn resource-name)) +(defn edit-impl + [{{uuid :uuid} :params body :body :as request}] + (try + (let [current (-> (str (u/de-camelcase resource-name) "/" uuid) + (db/retrieve request) + (a/can-modify? request)) + merged (merge current body) + value (:value merged)] + (-> merged + (u/update-timestamps) + (crud/validate) + (dissoc :value) + (db/edit request)) + (when value + (uzk/set-data (zkru/run-parameter-znode-path merged) value)) ;TODO what if znode not found + ) + (catch ExceptionInfo ei + (ex-data ei)))) (defmethod crud/edit resource-name [request] diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj index 8e6253add..24485ca5b 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj @@ -41,7 +41,7 @@ (defn get-version [path] - (-> (get-data path) :stat :version)) + (-> (get-znode path) :stat :version)) (defn set-data [path value & options] (let [version (get-version path) From 622f1471ec4be21685bfabfb296f09ef9519d598 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Mon, 24 Jul 2017 09:17:37 +0200 Subject: [PATCH 13/46] implement query for run param with sse and json --- .../ssclj/resources/run_parameter.clj | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj index 96af86f3a..5247db9c1 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj @@ -99,15 +99,21 @@ (catch ExceptionInfo ei (ex-data ei)))) +(defn send-param-value-and-set-watcher [event-ch {id :id name :name :as run-parameter}] + (try ; if znode not found do nothing for the moment + (let [node-path (zkru/run-parameter-znode-path run-parameter) + event {:id id + :name name + :data (uzk/get-data node-path :watcher (partial watch-fn event-ch id name))}] + (async/>!! event-ch event)) + (catch Exception e + ))) + (def retrieve-sse-impl (sse/event-channel-handler (fn [request response raise event-ch] - (let [{id :id name :name :as run-parameter} (retrieve-run-parameter request) - node-path (zkru/run-parameter-znode-path run-parameter) - event {:id id - :name name - :data (uzk/get-data node-path :watcher (partial watch-fn event-ch id name))}] - (async/>!! event-ch event))) + (let [{id :id name :name :as run-parameter} (retrieve-run-parameter request)] + (send-param-value-and-set-watcher event-ch run-parameter))) {:on-client-disconnect #(log/debug "sse/on-client-disconnect: " %)})) (defn retrieve-json-impl [request] @@ -148,8 +154,19 @@ [request] (delete-impl request)) -(def query-impl (std-crud/query-fn resource-name collection-acl collection-uri resource-tag)) +(def query-sse-impl + (sse/event-channel-handler + (fn [request response raise event-ch] + (a/can-view? {:acl collection-acl} request) + (let [options (select-keys request [:identity :query-params :cimi-params :user-name :user-roles]) + [count-before-pagination entries] (db/query resource-name options)] + (doall (map (partial send-param-value-and-set-watcher event-ch) entries)))) + {:on-client-disconnect #(log/debug "sse/on-client-disconnect: " %)})) + +(def query-json-impl (std-crud/query-fn resource-name collection-acl collection-uri resource-tag)) (defmethod crud/query resource-name - [request] - (query-impl request)) + [{{accept :accept} :headers :as request}] + (case accept + "text/event-stream" query-sse-impl + query-json-impl)) From cbf8d6d918b9c16b0e9c92b8f6d99529aac72d96 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Mon, 24 Jul 2017 18:14:43 +0200 Subject: [PATCH 14/46] add unit tests and dependencies --- ssclj/jar/build.boot | 2 ++ .../ssclj/resources/run_parameter.clj | 1 + .../sixsq/slipstream/ssclj/util/sse_test.clj | 26 +++++++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 ssclj/jar/test/com/sixsq/slipstream/ssclj/util/sse_test.clj diff --git a/ssclj/jar/build.boot b/ssclj/jar/build.boot index d3bee8590..22358fa42 100644 --- a/ssclj/jar/build.boot +++ b/ssclj/jar/build.boot @@ -24,6 +24,7 @@ '[[org.clojure/clojure] [aleph] + [manifold] [cheshire] ;; newer version needed for ring-json [compojure] [clj-stacktrace] @@ -46,6 +47,7 @@ [ring/ring-core] [ring/ring-json] [superstring] + [zookeeper-clj] [com.sixsq.slipstream/utils] [com.sixsq.slipstream/auth] diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj index 5247db9c1..4c6705afc 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj @@ -107,6 +107,7 @@ :data (uzk/get-data node-path :watcher (partial watch-fn event-ch id name))}] (async/>!! event-ch event)) (catch Exception e + (log/warn (ex-data e)) ))) (def retrieve-sse-impl diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/util/sse_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/util/sse_test.clj new file mode 100644 index 000000000..94c14396b --- /dev/null +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/util/sse_test.clj @@ -0,0 +1,26 @@ +(ns com.sixsq.slipstream.ssclj.util.sse-test + (:require [clojure.test :refer [deftest is]] + [ring.mock.request :as mock] + [com.sixsq.slipstream.ssclj.util.sse :as sse])) + +(deftest sse-start-stream + (let [request (-> (mock/request :get "/events")) + handler (sse/event-channel-handler (fn [request response raise ch] ch)) + response @(handler request) + {body :body + {content-type "Content-Type" + connection "Connection" + cache-control "Cache-Control" + X-Accel-Buffering "X-Accel-Buffering" + allow-origin "Access-Control-Allow-Origin"} :headers + status :status} response] + (is body "Response has a body") + (is (instance? manifold.stream.async.CoreAsyncSource body) "Response body is a channel.") + (is (= 200 status) "A successful status code is sent to the client.") + (is (= "text/event-stream; charset=UTF-8" content-type) + "The mime type and character encoding are set with the servlet setContentType method.") + (is (= "close" connection) "The client is instructed to close the connection.") + (is (= "no-cache" cache-control) "The client is instructed not to cache the event stream.") + (is (= "close" connection) "The client is instructed to close the connection.") + (is (= "no" X-Accel-Buffering) "The server is instructed to allow unbuffered response."))) + From aa6e37e78aaffc29215e9bec85b27769056f1d3b Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Tue, 25 Jul 2017 16:16:36 +0200 Subject: [PATCH 15/46] simple lifecycle test for run with embded zookeeper server working --- ssclj/jar/build.boot | 1 + .../sixsq/slipstream/ssclj/resources/run.clj | 2 +- .../sixsq/slipstream/ssclj/util/zookeeper.clj | 3 + .../ssclj/resources/lifecycle_test_utils.clj | 15 +++- .../ssclj/resources/run_lifecycle_test.clj | 75 +++++++++++++++++++ 5 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj diff --git a/ssclj/jar/build.boot b/ssclj/jar/build.boot index 22358fa42..31f4f3f52 100644 --- a/ssclj/jar/build.boot +++ b/ssclj/jar/build.boot @@ -66,6 +66,7 @@ [honeysql] [org.clojure/test.check] [org.slf4j/slf4j-log4j12 :scope "test"] + [org.apache.curator/curator-test :scope "test"] ;; boot tasks [boot-environ] diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj index 524bdc665..93e88276d 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj @@ -81,7 +81,7 @@ (doseq [n nodes] () (let [node-name (name (key n)) - multiplicity (read-string (get-in (val n) [:parameters :multiplicity :default-value]))] + multiplicity (read-string (get-in (val n) [:parameters :multiplicity :default-value] "1"))] (doseq [i (range 1 (inc multiplicity))] (create-parameter identity {:run-id run-id :node-name node-name :node-index i :name "vmstate" :value "init"}) )))) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj index 24485ca5b..858d4186a 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj @@ -19,6 +19,9 @@ (log/info "creating zookeeper client:" zk-endpoints) (zk/connect zk-endpoints :timeout-msec 60000))) +(defn close-client [] + (zk/close *client*)) + (defn create-all [path & options] (apply zk/create-all *client* path options)) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj index c9db5cff5..55bce6483 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj @@ -19,7 +19,10 @@ [com.sixsq.slipstream.ssclj.middleware.exception-handler :refer [wrap-exceptions]] [com.sixsq.slipstream.ssclj.middleware.authn-info-header :refer [wrap-authn-info-header]] [com.sixsq.slipstream.db.es.es-binding :as esb] - [com.sixsq.slipstream.db.es.es-util :as esu])) + [com.sixsq.slipstream.db.es.es-util :as esu] + [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] + [zookeeper :as zk]) + (:import [org.apache.curator.test TestingServer])) (defn serialize-cookie-value "replaces the map cookie value with a serialized string" @@ -205,3 +208,13 @@ [f] (with-test-client (f))) + +(defn setup-embedded-zk [f] + (let [port 21810 + server (TestingServer. port)] + (uzk/set-client! (zk/connect (str "127.0.0.1:" port))) + (f) + (try + (uzk/close-client) ; in case server already closed ignore exceptions + (catch Exception e)) + (.close server))) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj new file mode 100644 index 000000000..3b7f8db22 --- /dev/null +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj @@ -0,0 +1,75 @@ +(ns com.sixsq.slipstream.ssclj.resources.run-lifecycle-test + (:require + [clojure.test :refer :all] + [clojure.data.json :as json] + [peridot.core :refer :all] + [ring.util.codec :as rc] + [com.sixsq.slipstream.ssclj.resources.run :refer :all] + [com.sixsq.slipstream.ssclj.resources.run-parameter :as rp] + [com.sixsq.slipstream.ssclj.resources.lifecycle-test-utils :as t] + [com.sixsq.slipstream.ssclj.middleware.authn-info-header :refer [authn-info-header]] + [com.sixsq.slipstream.ssclj.app.routes :as routes] + [com.sixsq.slipstream.ssclj.app.params :as p] + [com.sixsq.slipstream.ssclj.resources.common.utils :as u] + [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] + [com.sixsq.slipstream.ssclj.resources.zk.run.utils :as ru])) + +(use-fixtures :each t/with-test-client-fixture) + +(use-fixtures :once t/setup-embedded-zk) + +(def base-uri (str p/service-context resource-url)) + +(defn ring-app [] + (t/make-ring-app (t/concat-routes routes/final-routes))) + +(def valid-entry + {:id (str resource-url "/run-uuid") + :resourceURI resource-uri + :module-resource-uri "module/examples/tutorials/service-testing/system/1940" + :category "Deployment" + :type "Orchestration" + :mutable false + :nodes {:node1 {:parameters {:cloudservice {:description "p1 description" ;TODO only node name and multiplicity are being used for now from all these parameters + :default-value "abc" + :user-choice-value "ABC"} + :multiplicity {:default-value "1"}} + :runtime-parameters {:p1 {:description "p1 description" + :default-value "abc" + :user-choice-value "ABC" + :mapped-to "a"}}} + :node2 {:parameters {:cloudservice {:description "param1 description" + :default-value "abc"}}}}}) + +(deftest lifecycle + + (let [session-admin-json (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "super ADMIN USER ANON")) + session-admin-form (-> (session (ring-app)) + (content-type "application/x-www-form-urlencoded") + (header authn-info-header "super ADMIN USER ANON")) + session-user (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "jane USER ANON")) + session-anon (-> (session (ring-app)) + (content-type "application/json"))] + + ;; adding, retrieving and deleting entry as user should succeed + (let [uri (-> session-user + (request base-uri + :request-method :post + :body (json/write-str valid-entry)) + (t/body->edn) + (t/is-status 201) + (t/location)) + abs-uri (str p/service-context resource-url "/" (u/de-camelcase uri))] + + (-> session-user + (request abs-uri) + (t/body->edn) + (t/is-status 200)) + + (are [expected value] (= expected value) + "init" (uzk/get-data (str ru/runs-path "/" uri "/state")) + "init" (uzk/get-data (str ru/runs-path "/" uri "/" ru/nodes-txt "/node2/1/" "vmstate")))))) From cbfbc7e987a5d3aac627faa45f4f161c47b54d58 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Tue, 25 Jul 2017 19:09:12 +0200 Subject: [PATCH 16/46] minor enhancement and more unit test for start run action --- .../sixsq/slipstream/ssclj/resources/run.clj | 29 +++++------ .../ssclj/resources/zk/run/utils.clj | 11 ++--- .../sixsq/slipstream/ssclj/util/zookeeper.clj | 3 ++ .../ssclj/resources/run_lifecycle_test.clj | 48 ++++++++++++------- 4 files changed, 52 insertions(+), 39 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj index 93e88276d..f0cf3c349 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj @@ -57,9 +57,9 @@ (defmethod crud/new-identifier resource-name [json _] - #_json ;TODO uncomment - (assoc json :id (u/random-uuid)) ;TODO REMOVE - ) ; keep id of java run + #_json ;TODO uncomment because the run-id should be consistent with SlipStream java server + (assoc json :id (str resource-url "/" (u/random-uuid))) ;TODO REMOVE this line + ) (defn create-parameter [identity run-parameter] (try @@ -86,7 +86,7 @@ (create-parameter identity {:run-id run-id :node-name node-name :node-index i :name "vmstate" :value "init"}) )))) -(defn add-impl [{body :body identity :identity :as request}] +(defn add-impl [{body :body :as request}] (a/can-modify? {:acl collection-acl} request) (let [new-run (-> body u/strip-service-attrs @@ -96,7 +96,6 @@ (crud/add-acl request) (assoc :state rsm/initial-state)) response (db/add resource-name (crud/validate new-run) {})] - (create-parameters identity new-run) response)) (defmethod crud/add resource-name @@ -156,19 +155,17 @@ (assoc run :start-time now))) (defmethod crud/do-action [resource-url "start"] - [{{uuid :uuid} :params :as request}] + [{{uuid :uuid} :params identity :identity :as request}] (try (let [current (-> (str (u/de-camelcase resource-name) "/" uuid) (db/retrieve request) (a/can-modify? request)) - response (-> current - (add-start-time) - (u/update-timestamps) - (crud/validate) - (db/edit request))] - ;(zru/create-zk-run current) - response - ) + run (-> current + (add-start-time) + (u/update-timestamps) + (crud/validate) + (db/edit request))] + (create-parameters identity current) + run) (catch ExceptionInfo ei - (ex-data ei))) - ) \ No newline at end of file + (ex-data ei)))) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj index 8e3e345e1..7404189f7 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj @@ -5,15 +5,14 @@ (def znode-separator "/") -(def runs-path (str znode-separator "runs")) - (def nodes-txt "nodes") (defn parameter-znode-path [run-id node-name node-index name] - (cond - (and run-id node-name node-index) (string/join znode-separator [runs-path run-id nodes-txt node-name node-index name]) - (and run-id node-name) (string/join znode-separator [runs-path run-id nodes-txt node-name name]) - run-id (string/join znode-separator [runs-path run-id name]))) + (->> (cond + (and run-id node-name node-index) (string/join znode-separator [run-id nodes-txt node-name node-index name]) + (and run-id node-name) (string/join znode-separator [run-id nodes-txt node-name name]) + run-id (string/join znode-separator [run-id name])) + (str znode-separator))) (defn run-parameter-znode-path [{run-id :run-id node-name :node-name node-index :node-index name :name :as run-parameter}] diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj index 858d4186a..8b82ba32d 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj @@ -50,3 +50,6 @@ (let [version (get-version path) data (.getBytes (str value) "UTF-8")] (apply zk/set-data *client* path data version options))) + +(defn exists [path & options] + (apply zk/exists *client* path options)) \ No newline at end of file diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj index 3b7f8db22..fe34a9b4a 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj @@ -24,7 +24,7 @@ (t/make-ring-app (t/concat-routes routes/final-routes))) (def valid-entry - {:id (str resource-url "/run-uuid") + {:id (str resource-url "run/dfd34916-6ede-47f7-aaeb-a30ddecbba5b") :resourceURI resource-uri :module-resource-uri "module/examples/tutorials/service-testing/system/1940" :category "Deployment" @@ -41,7 +41,7 @@ :node2 {:parameters {:cloudservice {:description "param1 description" :default-value "abc"}}}}}) -(deftest lifecycle +(deftest create-run (let [session-admin-json (-> (session (ring-app)) (content-type "application/json") @@ -56,20 +56,34 @@ (content-type "application/json"))] ;; adding, retrieving and deleting entry as user should succeed - (let [uri (-> session-user - (request base-uri - :request-method :post - :body (json/write-str valid-entry)) - (t/body->edn) - (t/is-status 201) - (t/location)) - abs-uri (str p/service-context resource-url "/" (u/de-camelcase uri))] + (let [run-id (-> session-user + (request base-uri + :request-method :post + :body (json/write-str valid-entry)) + (t/body->edn) + (t/is-status 201) + (t/location)) + abs-uri (str p/service-context (u/de-camelcase run-id)) + created-run (-> session-user + (request abs-uri) + (t/body->edn) + (t/is-status 200))] - (-> session-user - (request abs-uri) - (t/body->edn) - (t/is-status 200)) - (are [expected value] (= expected value) - "init" (uzk/get-data (str ru/runs-path "/" uri "/state")) - "init" (uzk/get-data (str ru/runs-path "/" uri "/" ru/nodes-txt "/node2/1/" "vmstate")))))) + (is (not (uzk/exists (str ru/znode-separator run-id)))) + + (let [start-uri (str p/service-context (t/get-op created-run "http://schemas.dmtf.org/cimi/2/action/start")) + started-run (-> session-user + (request start-uri) + (t/body->edn) + (t/is-status 200))] + + (is (not (get-in created-run [:body :start-time]))) + (is (get-in started-run [:response :body :start-time])) + + (are [expected value] (= expected value) + "init" (uzk/get-data (str ru/znode-separator run-id "/state")) + "init" (uzk/get-data + (str ru/znode-separator run-id "/" ru/nodes-txt "/node2/1/" "vmstate"))) + )))) + From 22a4ed893f5b526f93236f24b616b83616c29eb1 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Thu, 27 Jul 2017 19:11:06 +0200 Subject: [PATCH 17/46] run parameter life cycle tests and run id should be passed at creation time --- .../sixsq/slipstream/ssclj/resources/run.clj | 6 +- .../ssclj/resources/run_parameter.clj | 73 +++++++++-------- .../slipstream/ssclj/resources/spec/run.cljc | 2 +- .../ssclj/resources/zk/run/state_machine.clj | 1 + .../com/sixsq/slipstream/ssclj/util/sse.clj | 13 ++- .../ssclj/resources/run_lifecycle_test.clj | 3 +- .../run_parameter_lifecycle_test.clj | 81 +++++++++++++++++++ 7 files changed, 131 insertions(+), 48 deletions(-) create mode 100644 ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj index f0cf3c349..698b8deb9 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj @@ -57,9 +57,7 @@ (defmethod crud/new-identifier resource-name [json _] - #_json ;TODO uncomment because the run-id should be consistent with SlipStream java server - (assoc json :id (str resource-url "/" (u/random-uuid))) ;TODO REMOVE this line - ) + json) (defn create-parameter [identity run-parameter] (try @@ -89,7 +87,7 @@ (defn add-impl [{body :body :as request}] (a/can-modify? {:acl collection-acl} request) (let [new-run (-> body - u/strip-service-attrs + (dissoc :created :updated :resourceURI :operations) (crud/new-identifier resource-name) (assoc :resourceURI resource-uri) u/update-timestamps diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj index 4c6705afc..5105e8d18 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj @@ -11,6 +11,7 @@ [com.sixsq.slipstream.util.response :as r] [com.sixsq.slipstream.db.impl :as db] [clojure.tools.logging :as log] + [com.sixsq.slipstream.ssclj.util.log :as logu] [com.sixsq.slipstream.ssclj.util.sse :as sse] [clojure.core.async :as async] [zookeeper :as zk] @@ -73,20 +74,28 @@ node-path (zkru/parameter-znode-path run-id node-name node-index name)] (uzk/create-all node-path :persistent? true) (uzk/set-data node-path value) - response - )) + response)) (defmethod crud/add resource-name [request] (add-impl request)) -(defn watch-fn [event-ch id name {:keys [event-type path :as zk-event]}] +(defn transiant-watch-fn [event-ch id name {:keys [event-type path :as zk-event]}] (when (= event-type :NodeDataChanged) - (let [event {:id id - :name name - :data (uzk/get-data path :watcher (partial watch-fn event-ch id name))}] - (async/>!! event-ch event)))) + (let [data (uzk/get-data path)] + (sse/send-event id name data event-ch) + (async/close! event-ch)))) +(defn persistent-watch-fn [event-ch id name {:keys [event-type path :as zk-event]}] + (when (= event-type :NodeDataChanged) + (let [data (uzk/get-data path :watcher (partial persistent-watch-fn event-ch id name))] + (sse/send-event id name data event-ch)))) + +(defn send-event-and-set-watcher + [event-ch watch-fn {id :id name :name :as run-parameter}] + (let [node-path (zkru/run-parameter-znode-path run-parameter) + value (uzk/get-data node-path :watcher (partial watch-fn event-ch id name))] + (sse/send-event id name value event-ch))) (defn retrieve-run-parameter [{{uuid :uuid} :params :as request}] (try @@ -99,22 +108,13 @@ (catch ExceptionInfo ei (ex-data ei)))) -(defn send-param-value-and-set-watcher [event-ch {id :id name :name :as run-parameter}] - (try ; if znode not found do nothing for the moment - (let [node-path (zkru/run-parameter-znode-path run-parameter) - event {:id id - :name name - :data (uzk/get-data node-path :watcher (partial watch-fn event-ch id name))}] - (async/>!! event-ch event)) - (catch Exception e - (log/warn (ex-data e)) - ))) - (def retrieve-sse-impl (sse/event-channel-handler (fn [request response raise event-ch] - (let [{id :id name :name :as run-parameter} (retrieve-run-parameter request)] - (send-param-value-and-set-watcher event-ch run-parameter))) + (let [{id :id name :name :as run-parameter} (retrieve-run-parameter request) + node-path (zkru/run-parameter-znode-path run-parameter) + value (uzk/get-data node-path)] + (send-event-and-set-watcher event-ch transiant-watch-fn run-parameter))) {:on-client-disconnect #(log/debug "sse/on-client-disconnect: " %)})) (defn retrieve-json-impl [request] @@ -128,22 +128,21 @@ (defn edit-impl [{{uuid :uuid} :params body :body :as request}] - (try - (let [current (-> (str (u/de-camelcase resource-name) "/" uuid) - (db/retrieve request) - (a/can-modify? request)) - merged (merge current body) - value (:value merged)] - (-> merged - (u/update-timestamps) - (crud/validate) - (dissoc :value) - (db/edit request)) - (when value - (uzk/set-data (zkru/run-parameter-znode-path merged) value)) ;TODO what if znode not found - ) - (catch ExceptionInfo ei - (ex-data ei)))) + (let [current (-> (str (u/de-camelcase resource-name) "/" uuid) + (db/retrieve request) + (a/can-modify? request)) + merged (merge current body) + value (:value merged)] + (-> merged + (u/update-timestamps) + (crud/validate) + (dissoc :value) + (db/edit request)) + (when value + (let [name (:name merged)] + (if (contains? #{"state" "vmstate"} name) + (logu/log-and-throw-400 (str "run parameter " name " cannot be set")) + (uzk/set-data (zkru/run-parameter-znode-path merged) value)))))) ;TODO what if znode not found (defmethod crud/edit resource-name [request] @@ -161,7 +160,7 @@ (a/can-view? {:acl collection-acl} request) (let [options (select-keys request [:identity :query-params :cimi-params :user-name :user-roles]) [count-before-pagination entries] (db/query resource-name options)] - (doall (map (partial send-param-value-and-set-watcher event-ch) entries)))) + (doall (map (partial send-event-and-set-watcher event-ch persistent-watch-fn) entries)))) {:on-client-disconnect #(log/debug "sse/on-client-disconnect: " %)})) (def query-json-impl (std-crud/query-fn resource-name collection-acl collection-uri resource-tag)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc index 1bca0b1db..1ad079440 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc @@ -56,7 +56,7 @@ (s/def :cimi.run/nodes (su/constrained-map keyword? :cimi.run/node)) -(def run-attrs {:req-un [#_:cimi.common/id ;TODO uncomment +(def run-attrs {:req-un [:cimi.common/id :cimi.run/module-resource-uri :cimi.run/type :cimi.run/category diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/state_machine.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/state_machine.clj index b5086203a..59d9666ea 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/state_machine.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/state_machine.clj @@ -21,6 +21,7 @@ ;; State machine states (def initial-state "init") + (def valid-transitions {initial-state ["provisioning"] "provisioning" ["executing"] diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/sse.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/sse.clj index c65eb2114..76fffc8b5 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/sse.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/sse.clj @@ -5,8 +5,7 @@ [ring.core.protocols :as ring] [ring.util.response :as ring-response] [manifold.stream :as s] - [manifold.deferred :as d]) - ) + [manifold.deferred :as d])) (def CRLF "\r\n") (def EVENT_FIELD "event: ") @@ -36,7 +35,13 @@ (.append sb CRLF) (str sb)))) -(defn send-event +(defn send-event [id name data event-ch] + (let [event {:id id + :name name + :data data}] + (async/>!! event-ch event))) + +(defn- send-event-on-response-ch [channel name data id put-fn raise] (try (put-fn channel (mk-data name data id)) @@ -66,7 +71,7 @@ (if (map? event) (reduce (fn [agg [k v]] (assoc agg k (str v))) {} event) {:data (str event)})] - (when (send-event response-channel event-name event-data event-id async/put! raise) + (when (send-event-on-response-ch response-channel event-name event-data event-id async/put! raise) (recur)))))) (async/close! event-channel) (async/close! response-channel) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj index fe34a9b4a..f3be0afa9 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj @@ -24,7 +24,7 @@ (t/make-ring-app (t/concat-routes routes/final-routes))) (def valid-entry - {:id (str resource-url "run/dfd34916-6ede-47f7-aaeb-a30ddecbba5b") + {:id (str resource-url "/dfd34916-6ede-47f7-aaeb-a30ddecbba5b") :resourceURI resource-uri :module-resource-uri "module/examples/tutorials/service-testing/system/1940" :category "Deployment" @@ -69,7 +69,6 @@ (t/body->edn) (t/is-status 200))] - (is (not (uzk/exists (str ru/znode-separator run-id)))) (let [start-uri (str p/service-context (t/get-op created-run "http://schemas.dmtf.org/cimi/2/action/start")) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj new file mode 100644 index 000000000..b4039d113 --- /dev/null +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj @@ -0,0 +1,81 @@ +(ns com.sixsq.slipstream.ssclj.resources.run-parameter-lifecycle-test + (:require + [clojure.test :refer :all] + [clojure.data.json :as json] + [peridot.core :refer :all] + [ring.util.codec :as rc] + [com.sixsq.slipstream.ssclj.resources.run-parameter :refer :all] + [com.sixsq.slipstream.ssclj.resources.lifecycle-test-utils :as t] + [com.sixsq.slipstream.ssclj.middleware.authn-info-header :refer [authn-info-header]] + [com.sixsq.slipstream.ssclj.app.routes :as routes] + [com.sixsq.slipstream.ssclj.app.params :as p] + [com.sixsq.slipstream.ssclj.resources.common.utils :as u] + [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] + [com.sixsq.slipstream.ssclj.resources.zk.run.utils :as ru] + [com.sixsq.slipstream.ssclj.resources.zk.run.utils :as zkru])) + +(use-fixtures :each t/with-test-client-fixture) + +(use-fixtures :once t/setup-embedded-zk) + +(def base-uri (str p/service-context resource-url)) + +(defn ring-app [] + (t/make-ring-app (t/concat-routes routes/final-routes))) + +(def session-user (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "jane USER ANON"))) + +(deftest create-run-parameter-xyz + (let [run-id "run/abc34916-6ede-47f7-aaeb-a30ddecbba5b" + valid-entry {:run-id run-id :node-name "machine" :node-index 1 :name "xyz" :value "XYZ"} + znode-path (zkru/run-parameter-znode-path valid-entry) + run-parameter-id (-> session-user + (request base-uri + :request-method :post + :body (json/write-str valid-entry)) + (t/body->edn) + (t/is-status 201) + (t/location)) + abs-uri (str p/service-context (u/de-camelcase run-parameter-id)) + created-run-parameter (-> session-user + (request abs-uri) + (t/body->edn) + (t/is-status 200))] + + (is (= "XYZ" (uzk/get-data znode-path))) + + (-> session-user + (request abs-uri :request-method :put + :body (json/write-str {:value "newvalue"})) + (t/body->edn) + (t/is-status 200)) + + (is (= "newvalue" (uzk/get-data znode-path)) "run parameter can be updated"))) + +(deftest create-run-parameter-state + (let [run-id "run/def34916-6ede-47f7-aaeb-a30ddecbba5b" + valid-entry {:run-id run-id :name "state" :value "init"} + run-parameter-id (-> session-user + (request base-uri + :request-method :post + :body (json/write-str valid-entry)) + (t/body->edn) + (t/is-status 201) + (t/location)) + abs-uri (str p/service-context (u/de-camelcase run-parameter-id)) + created-run-parameter (-> session-user + (request abs-uri) + (t/body->edn) + (t/is-status 200))] + + (is (= "init" (uzk/get-data (str ru/znode-separator run-id "/state"))) "znode state is created") + + (-> session-user + (request abs-uri :request-method :put + :body (json/write-str {:value "newvalue"})) + (t/body->edn) + (t/is-status 400)) + + (is (= "init" (uzk/get-data (str ru/znode-separator run-id "/state"))) "run parameter state can't be updated"))) From d83a4bf8f66d1fa3f54e75f5c27242f2efa96204 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Thu, 27 Jul 2017 19:15:36 +0200 Subject: [PATCH 18/46] minor, vmstate should be set by the client --- .../sixsq/slipstream/ssclj/resources/run_parameter.clj | 2 +- .../ssclj/resources/run_parameter_lifecycle_test.clj | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj index 5105e8d18..3ee2a0d48 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj @@ -140,7 +140,7 @@ (db/edit request)) (when value (let [name (:name merged)] - (if (contains? #{"state" "vmstate"} name) + (if (contains? #{"state"} name) (logu/log-and-throw-400 (str "run parameter " name " cannot be set")) (uzk/set-data (zkru/run-parameter-znode-path merged) value)))))) ;TODO what if znode not found diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj index b4039d113..cd715a6e0 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj @@ -56,21 +56,22 @@ (deftest create-run-parameter-state (let [run-id "run/def34916-6ede-47f7-aaeb-a30ddecbba5b" - valid-entry {:run-id run-id :name "state" :value "init"} + run-parameter {:run-id run-id :name "state" :value "init"} run-parameter-id (-> session-user (request base-uri :request-method :post - :body (json/write-str valid-entry)) + :body (json/write-str run-parameter)) (t/body->edn) (t/is-status 201) (t/location)) + znode-path (zkru/run-parameter-znode-path run-parameter) abs-uri (str p/service-context (u/de-camelcase run-parameter-id)) created-run-parameter (-> session-user (request abs-uri) (t/body->edn) (t/is-status 200))] - (is (= "init" (uzk/get-data (str ru/znode-separator run-id "/state"))) "znode state is created") + (is (= "init" (uzk/get-data znode-path)) "znode state is created") (-> session-user (request abs-uri :request-method :put @@ -78,4 +79,4 @@ (t/body->edn) (t/is-status 400)) - (is (= "init" (uzk/get-data (str ru/znode-separator run-id "/state"))) "run parameter state can't be updated"))) + (is (= "init" (uzk/get-data znode-path)) "run parameter state can't be updated"))) From 586697931650f63c68a7b6006c6ace74ce40c340 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Fri, 28 Jul 2017 09:36:26 +0200 Subject: [PATCH 19/46] add acl for un parameters --- .../sixsq/slipstream/ssclj/resources/run.clj | 42 ++++++----- .../ssclj/resources/run_parameter.clj | 4 -- .../ssclj/resources/run_lifecycle_test.clj | 7 +- .../run_parameter_lifecycle_test.clj | 69 +++++++++---------- 4 files changed, 63 insertions(+), 59 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj index 698b8deb9..652b6287a 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj @@ -9,6 +9,7 @@ [com.sixsq.slipstream.ssclj.resources.common.utils :as u] [com.sixsq.slipstream.ssclj.resources.zk.run.utils :as zru] [com.sixsq.slipstream.ssclj.resources.run-parameter :as rp] + [com.sixsq.slipstream.ssclj.middleware.authn-info-header :refer [create-identity-map]] [com.sixsq.slipstream.ssclj.resources.zk.run.state-machine :as rsm] [com.sixsq.slipstream.auth.acl :as a] [superstring.core :as str] @@ -59,30 +60,37 @@ [json _] json) -(defn create-parameter [identity run-parameter] +(defn create-parameter [run-parameter] (try - (let [ - request {:params {:resource-name rp/resource-url} - :identity identity + (let [request {:params {:resource-name rp/resource-url} + :identity (create-identity-map ["super" #{"ADMIN"}]) :body run-parameter} - {:keys [status body]} (crud/add request)] + {:keys [status body]} (rp/add-impl request)] (case status 201 (log/info "created run-parameter: " body) (log/info "unexpected status code when creating run-parameter resource:" status))) (catch Exception e (log/warn "error when creating run-parameter resource: " (str e) "\n" - (with-out-str (st/print-cause-trace e))))) - ) - -(defn create-parameters [identity {nodes :nodes run-id :id state :state}] - (create-parameter identity {:run-id run-id :name "state" :value state}) - (doseq [n nodes] - () - (let [node-name (name (key n)) - multiplicity (read-string (get-in (val n) [:parameters :multiplicity :default-value] "1"))] - (doseq [i (range 1 (inc multiplicity))] - (create-parameter identity {:run-id run-id :node-name node-name :node-index i :name "vmstate" :value "init"}) - )))) + (with-out-str (st/print-cause-trace e)))))) + +(defn create-parameters [identity {nodes :nodes run-id :id state :state}] ; run parameter state should not + (let [user (:current identity)] + (create-parameter {:run-id run-id :name "state" :value state :acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal user + :type "USER" + :right "VIEW"}]}}) + (doseq [n nodes] + () + (let [node-name (name (key n)) + multiplicity (read-string (get-in (val n) [:parameters :multiplicity :default-value] "1"))] + (doseq [i (range 1 (inc multiplicity))] + (create-parameter {:run-id run-id :node-name node-name :node-index i + :name "vmstate" :value "init" :acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal user + :type "USER" + :right "MODIFY"}]}})))))) (defn add-impl [{body :body :as request}] (a/can-modify? {:acl collection-acl} request) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj index 3ee2a0d48..1cb5c98ed 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj @@ -76,10 +76,6 @@ (uzk/set-data node-path value) response)) -(defmethod crud/add resource-name - [request] - (add-impl request)) - (defn transiant-watch-fn [event-ch id name {:keys [event-type path :as zk-event]}] (when (= event-type :NodeDataChanged) (let [data (uzk/get-data path)] diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj index f3be0afa9..7b680190a 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj @@ -84,5 +84,10 @@ "init" (uzk/get-data (str ru/znode-separator run-id "/state")) "init" (uzk/get-data (str ru/znode-separator run-id "/" ru/nodes-txt "/node2/1/" "vmstate"))) - )))) + ) + run-parameter-state-id (-> session-user + :request-method :get + + ) + ))) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj index cd715a6e0..289914715 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj @@ -6,7 +6,7 @@ [ring.util.codec :as rc] [com.sixsq.slipstream.ssclj.resources.run-parameter :refer :all] [com.sixsq.slipstream.ssclj.resources.lifecycle-test-utils :as t] - [com.sixsq.slipstream.ssclj.middleware.authn-info-header :refer [authn-info-header]] + [com.sixsq.slipstream.ssclj.middleware.authn-info-header :refer [authn-info-header create-identity-map]] [com.sixsq.slipstream.ssclj.app.routes :as routes] [com.sixsq.slipstream.ssclj.app.params :as p] [com.sixsq.slipstream.ssclj.resources.common.utils :as u] @@ -23,60 +23,55 @@ (defn ring-app [] (t/make-ring-app (t/concat-routes routes/final-routes))) -(def session-user (-> (session (ring-app)) - (content-type "application/json") - (header authn-info-header "jane USER ANON"))) +(def session-user-jane (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "jane USER ANON"))) + +(def session-user-albert (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "albert USER ANON"))) + +(def identity-admin (create-identity-map ["super" #{"ADMIN"}])) + +(def resource-acl-jane {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal "jane" + :type "USER" + :right "MODIFY"}]}) (deftest create-run-parameter-xyz (let [run-id "run/abc34916-6ede-47f7-aaeb-a30ddecbba5b" - valid-entry {:run-id run-id :node-name "machine" :node-index 1 :name "xyz" :value "XYZ"} + valid-entry {:run-id run-id :node-name "machine" :node-index 1 :name "xyz" :value "XYZ" :acl resource-acl-jane} znode-path (zkru/run-parameter-znode-path valid-entry) - run-parameter-id (-> session-user - (request base-uri - :request-method :post - :body (json/write-str valid-entry)) - (t/body->edn) - (t/is-status 201) - (t/location)) + run-parameter-id (-> + (->> {:params {:resource-name resource-url} + :identity identity-admin + :body valid-entry} + (add-impl) + (assoc {} :response)) + (t/is-status 201) + (t/location)) abs-uri (str p/service-context (u/de-camelcase run-parameter-id)) - created-run-parameter (-> session-user + created-run-parameter (-> session-user-jane (request abs-uri) (t/body->edn) (t/is-status 200))] (is (= "XYZ" (uzk/get-data znode-path))) - (-> session-user + (-> session-user-jane (request abs-uri :request-method :put :body (json/write-str {:value "newvalue"})) (t/body->edn) (t/is-status 200)) - (is (= "newvalue" (uzk/get-data znode-path)) "run parameter can be updated"))) - -(deftest create-run-parameter-state - (let [run-id "run/def34916-6ede-47f7-aaeb-a30ddecbba5b" - run-parameter {:run-id run-id :name "state" :value "init"} - run-parameter-id (-> session-user - (request base-uri - :request-method :post - :body (json/write-str run-parameter)) - (t/body->edn) - (t/is-status 201) - (t/location)) - znode-path (zkru/run-parameter-znode-path run-parameter) - abs-uri (str p/service-context (u/de-camelcase run-parameter-id)) - created-run-parameter (-> session-user - (request abs-uri) - (t/body->edn) - (t/is-status 200))] - - (is (= "init" (uzk/get-data znode-path)) "znode state is created") + (is (= "newvalue" (uzk/get-data znode-path)) "run parameter can be updated") - (-> session-user + (-> session-user-albert (request abs-uri :request-method :put :body (json/write-str {:value "newvalue"})) (t/body->edn) - (t/is-status 400)) + (t/is-status 403)) + + (is (not (= "newvalue-albert" (uzk/get-data znode-path))) "run parameter can be updated"))) - (is (= "init" (uzk/get-data znode-path)) "run parameter state can't be updated"))) From 199d0065d32272c8274ab78c569be5e163bfb242 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Fri, 28 Jul 2017 13:08:31 +0200 Subject: [PATCH 20/46] rename run-id to run-href --- .../sixsq/slipstream/ssclj/resources/run.clj | 24 +++++------ .../ssclj/resources/run_parameter.clj | 4 +- .../ssclj/resources/spec/run_parameter.cljc | 4 +- .../ssclj/resources/zk/run/utils.clj | 40 +++++++++---------- .../ssclj/resources/lifecycle_test_utils.clj | 3 +- .../ssclj/resources/run_lifecycle_test.clj | 27 ++++++------- .../run_parameter_lifecycle_test.clj | 5 ++- 7 files changed, 53 insertions(+), 54 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj index 652b6287a..bda9690c2 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj @@ -73,24 +73,24 @@ (log/warn "error when creating run-parameter resource: " (str e) "\n" (with-out-str (st/print-cause-trace e)))))) -(defn create-parameters [identity {nodes :nodes run-id :id state :state}] ; run parameter state should not +(defn create-parameters [identity {nodes :nodes run-href :id state :state}] ; run parameter state should not (let [user (:current identity)] - (create-parameter {:run-id run-id :name "state" :value state :acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:principal user - :type "USER" - :right "VIEW"}]}}) + (create-parameter {:run-href run-href :name "state" :value state :acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal user + :type "USER" + :right "VIEW"}]}}) (doseq [n nodes] () (let [node-name (name (key n)) multiplicity (read-string (get-in (val n) [:parameters :multiplicity :default-value] "1"))] (doseq [i (range 1 (inc multiplicity))] - (create-parameter {:run-id run-id :node-name node-name :node-index i - :name "vmstate" :value "init" :acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:principal user - :type "USER" - :right "MODIFY"}]}})))))) + (create-parameter {:run-href run-href :node-name node-name :node-index i + :name "vmstate" :value "init" :acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal user + :type "USER" + :right "MODIFY"}]}})))))) (defn add-impl [{body :body :as request}] (a/can-modify? {:acl collection-acl} request) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj index 1cb5c98ed..14988b1ef 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj @@ -66,12 +66,12 @@ (crud/add-acl request) crud/validate) response (db/add resource-name run-parameter {}) - run-id (:run-id body) + run-href (:run-href body) node-name (:node-name body) node-index (:node-index body) name (:name body) value (:value body) - node-path (zkru/parameter-znode-path run-id node-name node-index name)] + node-path (zkru/parameter-znode-path run-href node-name node-index name)] (uzk/create-all node-path :persistent? true) (uzk/set-data node-path value) response)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc index 328f8181a..4c7dfd072 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc @@ -6,7 +6,7 @@ [com.sixsq.slipstream.ssclj.util.spec :as su] [com.sixsq.slipstream.ssclj.resources.spec.common :as c])) -(s/def :cimi.run-parameter/run-id :cimi.core/nonblank-string) +(s/def :cimi.run-parameter/run-href :cimi.core/nonblank-string) (s/def :cimi.run-parameter/name :cimi.core/nonblank-string) (s/def :cimi.run-parameter/value string?) (s/def :cimi.run-parameter/node-name :cimi.core/nonblank-string) @@ -15,7 +15,7 @@ (s/def :cimi/run-parameter (su/only-keys-maps c/common-attrs - {:req-un [:cimi.run-parameter/run-id + {:req-un [:cimi.run-parameter/run-href :cimi.run-parameter/name] :opt-un [:cimi.run-parameter/node-name :cimi.run-parameter/node-index diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj index 7404189f7..5a24db79e 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj @@ -7,16 +7,16 @@ (def nodes-txt "nodes") -(defn parameter-znode-path [run-id node-name node-index name] +(defn parameter-znode-path [run-href node-name node-index name] (->> (cond - (and run-id node-name node-index) (string/join znode-separator [run-id nodes-txt node-name node-index name]) - (and run-id node-name) (string/join znode-separator [run-id nodes-txt node-name name]) - run-id (string/join znode-separator [run-id name])) + (and run-href node-name node-index) (string/join znode-separator [run-href nodes-txt node-name node-index name]) + (and run-href node-name) (string/join znode-separator [run-href nodes-txt node-name name]) + run-href (string/join znode-separator [run-href name])) (str znode-separator))) (defn run-parameter-znode-path - [{run-id :run-id node-name :node-name node-index :node-index name :name :as run-parameter}] - (parameter-znode-path run-id node-name node-index name)) + [{run-href :run-href node-name :node-name node-index :node-index name :name :as run-parameter}] + (parameter-znode-path run-href node-name node-index name)) ;(defn run-id-path [run-id]) @@ -38,17 +38,17 @@ #_(defn create-zk-run [{run-id :id nodes :nodes :as run}] - (doseq [n nodes] - (zk/create-all uzk/*client* (node-path run-id (key n)) :persistent? true) - (let [{:keys [params multiplicity mapping]} (val n)] - (doseq [i (range 1 (inc multiplicity))] - (zk/create-all client (rzu/params-znode-path run-id (key n) i) :persistent? true) - (doseq [p params] - (if-let [default (-> p val :default)] - (zk/create client (rzu/param-znode-path run-id (key n) i (key p)) - :data (zdata/to-bytes default) - :persistent? true) - (zk/create client (rzu/param-znode-path run-id (key n) i (key p)) - :persistent? true)))))) - (rsm/create client run-id module params) - ) \ No newline at end of file + (doseq [n nodes] + (zk/create-all uzk/*client* (node-path run-id (key n)) :persistent? true) + (let [{:keys [params multiplicity mapping]} (val n)] + (doseq [i (range 1 (inc multiplicity))] + (zk/create-all client (rzu/params-znode-path run-id (key n) i) :persistent? true) + (doseq [p params] + (if-let [default (-> p val :default)] + (zk/create client (rzu/param-znode-path run-id (key n) i (key p)) + :data (zdata/to-bytes default) + :persistent? true) + (zk/create client (rzu/param-znode-path run-id (key n) i (key p)) + :persistent? true)))))) + (rsm/create client run-id module params) + ) \ No newline at end of file diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj index 55bce6483..2033f01d4 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj @@ -217,4 +217,5 @@ (try (uzk/close-client) ; in case server already closed ignore exceptions (catch Exception e)) - (.close server))) + (.close server) + )) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj index 7b680190a..43ffa9946 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj @@ -56,20 +56,20 @@ (content-type "application/json"))] ;; adding, retrieving and deleting entry as user should succeed - (let [run-id (-> session-user - (request base-uri - :request-method :post - :body (json/write-str valid-entry)) - (t/body->edn) - (t/is-status 201) - (t/location)) - abs-uri (str p/service-context (u/de-camelcase run-id)) + (let [run-href (-> session-user + (request base-uri + :request-method :post + :body (json/write-str valid-entry)) + (t/body->edn) + (t/is-status 201) + (t/location)) + abs-uri (str p/service-context (u/de-camelcase run-href)) created-run (-> session-user (request abs-uri) (t/body->edn) (t/is-status 200))] - (is (not (uzk/exists (str ru/znode-separator run-id)))) + (is (not (uzk/exists (str ru/znode-separator run-href)))) (let [start-uri (str p/service-context (t/get-op created-run "http://schemas.dmtf.org/cimi/2/action/start")) started-run (-> session-user @@ -81,13 +81,10 @@ (is (get-in started-run [:response :body :start-time])) (are [expected value] (= expected value) - "init" (uzk/get-data (str ru/znode-separator run-id "/state")) + "init" (uzk/get-data (str ru/znode-separator run-href "/state")) "init" (uzk/get-data - (str ru/znode-separator run-id "/" ru/nodes-txt "/node2/1/" "vmstate"))) + (str ru/znode-separator run-href "/" ru/nodes-txt "/node2/1/" "vmstate"))) ) - run-parameter-state-id (-> session-user - :request-method :get - - ) ))) + diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj index 289914715..8d33c0225 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj @@ -40,8 +40,9 @@ :right "MODIFY"}]}) (deftest create-run-parameter-xyz - (let [run-id "run/abc34916-6ede-47f7-aaeb-a30ddecbba5b" - valid-entry {:run-id run-id :node-name "machine" :node-index 1 :name "xyz" :value "XYZ" :acl resource-acl-jane} + (let [run-href "run/abc34916-6ede-47f7-aaeb-a30ddecbba5b" + valid-entry {:run-href run-href :node-name "machine" :node-index 1 + :name "xyz" :value "XYZ" :acl resource-acl-jane} znode-path (zkru/run-parameter-znode-path valid-entry) run-parameter-id (-> (->> {:params {:resource-name resource-url} From dbc3d37c31b15f0363e4950d88303f10501f355e Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Fri, 28 Jul 2017 15:24:43 +0200 Subject: [PATCH 21/46] SSE data is now the full json of run parameter and little more other changes --- .../ssclj/resources/run_parameter.clj | 27 ++++++++++--------- .../slipstream/ssclj/resources/spec/run.cljc | 5 ++-- .../ssclj/resources/run_lifecycle_test.clj | 5 +--- .../ssclj/resources/spec/run_test.cljc | 2 +- 4 files changed, 18 insertions(+), 21 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj index 14988b1ef..c8343f8c3 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj @@ -78,20 +78,25 @@ (defn transiant-watch-fn [event-ch id name {:keys [event-type path :as zk-event]}] (when (= event-type :NodeDataChanged) - (let [data (uzk/get-data path)] - (sse/send-event id name data event-ch) + (let [run-parameter (db/retrieve id {}) + value (uzk/get-data path) + run-parameter (assoc run-parameter :value value)] + (sse/send-event id name run-parameter event-ch) (async/close! event-ch)))) (defn persistent-watch-fn [event-ch id name {:keys [event-type path :as zk-event]}] (when (= event-type :NodeDataChanged) - (let [data (uzk/get-data path :watcher (partial persistent-watch-fn event-ch id name))] - (sse/send-event id name data event-ch)))) + (let [run-parameter (db/retrieve id {}) + value (uzk/get-data path :watcher (partial persistent-watch-fn event-ch id name)) + run-parameter (assoc run-parameter :value value)] + (sse/send-event id name run-parameter event-ch)))) (defn send-event-and-set-watcher [event-ch watch-fn {id :id name :name :as run-parameter}] (let [node-path (zkru/run-parameter-znode-path run-parameter) - value (uzk/get-data node-path :watcher (partial watch-fn event-ch id name))] - (sse/send-event id name value event-ch))) + value (uzk/get-data node-path :watcher (partial watch-fn event-ch id name)) + run-parameter (assoc run-parameter :value value)] + (sse/send-event id name run-parameter event-ch))) (defn retrieve-run-parameter [{{uuid :uuid} :params :as request}] (try @@ -108,8 +113,7 @@ (sse/event-channel-handler (fn [request response raise event-ch] (let [{id :id name :name :as run-parameter} (retrieve-run-parameter request) - node-path (zkru/run-parameter-znode-path run-parameter) - value (uzk/get-data node-path)] + node-path (zkru/run-parameter-znode-path run-parameter)] (send-event-and-set-watcher event-ch transiant-watch-fn run-parameter))) {:on-client-disconnect #(log/debug "sse/on-client-disconnect: " %)})) @@ -135,10 +139,7 @@ (dissoc :value) (db/edit request)) (when value - (let [name (:name merged)] - (if (contains? #{"state"} name) - (logu/log-and-throw-400 (str "run parameter " name " cannot be set")) - (uzk/set-data (zkru/run-parameter-znode-path merged) value)))))) ;TODO what if znode not found + (uzk/set-data (zkru/run-parameter-znode-path merged) value)))) ;TODO what if znode not found (defmethod crud/edit resource-name [request] @@ -157,7 +158,7 @@ (let [options (select-keys request [:identity :query-params :cimi-params :user-name :user-roles]) [count-before-pagination entries] (db/query resource-name options)] (doall (map (partial send-event-and-set-watcher event-ch persistent-watch-fn) entries)))) - {:on-client-disconnect #(log/debug "sse/on-client-disconnect: " %)})) + {:on-client-disconnect #(log/debug "sse/on-client-disconnect: " %) :heartbeat-delay 10})) (def query-json-impl (std-crud/query-fn resource-name collection-acl collection-uri resource-tag)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc index 1ad079440..a4cf43c6c 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc @@ -56,14 +56,13 @@ (s/def :cimi.run/nodes (su/constrained-map keyword? :cimi.run/node)) -(def run-attrs {:req-un [:cimi.common/id +(def run-attrs {:req-un [:cimi.run/id :cimi.run/module-resource-uri :cimi.run/type :cimi.run/category :cimi.run/mutable :cimi.run/nodes] - :opt-un [:cimi.run/id - :cimi.run/start-time + :opt-un [:cimi.run/start-time :cimi.run/end-time :cimi.run/last-state-change-time :cimi.run/state]}) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj index 43ffa9946..f791d0b8f 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj @@ -83,8 +83,5 @@ (are [expected value] (= expected value) "init" (uzk/get-data (str ru/znode-separator run-href "/state")) "init" (uzk/get-data - (str ru/znode-separator run-href "/" ru/nodes-txt "/node2/1/" "vmstate"))) - ) - - ))) + (str ru/znode-separator run-href "/" ru/nodes-txt "/node2/1/" "vmstate"))))))) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/run_test.cljc b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/run_test.cljc index 4a307e84b..2f8862849 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/run_test.cljc +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/run_test.cljc @@ -34,7 +34,7 @@ (are [expect-fn arg] (expect-fn (s/valid? :cimi/run arg)) true? run - ;false? (dissoc run :id) ;TODO uncomment + false? (dissoc run :id) false? (dissoc run :created) false? (dissoc run :updated) false? (dissoc run :acl) From 39a5dee2833f02147027f67b388f27a0eb23050c Mon Sep 17 00:00:00 2001 From: Konstantin Skaburskas Date: Mon, 28 Aug 2017 14:22:32 +0200 Subject: [PATCH 22/46] names of es fixtures changed --- .../com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj | 2 +- .../slipstream/ssclj/resources/run_parameter_lifecycle_test.clj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj index f791d0b8f..01c1d5bd2 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj @@ -14,7 +14,7 @@ [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] [com.sixsq.slipstream.ssclj.resources.zk.run.utils :as ru])) -(use-fixtures :each t/with-test-client-fixture) +(use-fixtures :each t/with-test-es-client-fixture) (use-fixtures :once t/setup-embedded-zk) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj index 8d33c0225..7a0088fd1 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj @@ -14,7 +14,7 @@ [com.sixsq.slipstream.ssclj.resources.zk.run.utils :as ru] [com.sixsq.slipstream.ssclj.resources.zk.run.utils :as zkru])) -(use-fixtures :each t/with-test-client-fixture) +(use-fixtures :each t/with-test-es-client-fixture) (use-fixtures :once t/setup-embedded-zk) From 50916db54802b83cc7d0c94e767268d0c14b67f2 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Fri, 1 Sep 2017 13:38:24 +0200 Subject: [PATCH 23/46] add values to run parameter query --- .../ssclj/resources/run_parameter.clj | 47 ++++++++++++------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj index c8343f8c3..918c31f48 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj @@ -55,6 +55,15 @@ ;; CRUD operations ;; +(defn add-value-run-parameter [run-parameter & {:keys [watcher]}] + (try + (let [value (if watcher + (uzk/get-data (zkru/run-parameter-znode-path run-parameter) :watcher watcher) + (uzk/get-data (zkru/run-parameter-znode-path run-parameter)))] + (assoc run-parameter :value value)) + (catch ExceptionInfo ei ;TODO what if data not found + (ex-data ei)))) + (defn add-impl [{:keys [body] :as request}] (a/can-modify? {:acl collection-acl} request) (let [run-parameter (-> body @@ -78,36 +87,29 @@ (defn transiant-watch-fn [event-ch id name {:keys [event-type path :as zk-event]}] (when (= event-type :NodeDataChanged) - (let [run-parameter (db/retrieve id {}) - value (uzk/get-data path) - run-parameter (assoc run-parameter :value value)] + (let [run-parameter (-> (db/retrieve id {}) + (add-value-run-parameter))] (sse/send-event id name run-parameter event-ch) (async/close! event-ch)))) (defn persistent-watch-fn [event-ch id name {:keys [event-type path :as zk-event]}] (when (= event-type :NodeDataChanged) - (let [run-parameter (db/retrieve id {}) - value (uzk/get-data path :watcher (partial persistent-watch-fn event-ch id name)) - run-parameter (assoc run-parameter :value value)] + (let [run-parameter (-> (db/retrieve id {}) + (add-value-run-parameter :watcher (partial persistent-watch-fn event-ch id name)))] (sse/send-event id name run-parameter event-ch)))) (defn send-event-and-set-watcher [event-ch watch-fn {id :id name :name :as run-parameter}] - (let [node-path (zkru/run-parameter-znode-path run-parameter) - value (uzk/get-data node-path :watcher (partial watch-fn event-ch id name)) - run-parameter (assoc run-parameter :value value)] + (let [run-parameter (-> run-parameter + (add-value-run-parameter :watcher (partial watch-fn event-ch id name)))] (sse/send-event id name run-parameter event-ch))) (defn retrieve-run-parameter [{{uuid :uuid} :params :as request}] - (try - (let [run-parameter (-> (str (u/de-camelcase resource-name) "/" uuid) - (db/retrieve request) - (a/can-view? request) - (crud/set-operations request)) - value (uzk/get-data (zkru/run-parameter-znode-path run-parameter))] ;TODO what if data not found - (assoc run-parameter :value value)) - (catch ExceptionInfo ei - (ex-data ei)))) + (-> (str (u/de-camelcase resource-name) "/" uuid) + (db/retrieve request) + (a/can-view? request) + (crud/set-operations request) + (add-value-run-parameter))) (def retrieve-sse-impl (sse/event-channel-handler @@ -162,6 +164,15 @@ (def query-json-impl (std-crud/query-fn resource-name collection-acl collection-uri resource-tag)) +(defn query-json-impl [request] + (a/can-view? {:acl collection-acl} request) + (let [wrapper-fn (std-crud/collection-wrapper-fn resource-name collection-acl collection-uri resource-tag) + options (select-keys request [:identity :query-params :cimi-params :user-name :user-roles]) + [metadata entries] (db/query resource-name options) + entries (doall (map add-value-run-parameter entries)) + entries-and-count (merge metadata (wrapper-fn request entries))] + (r/json-response entries-and-count))) + (defmethod crud/query resource-name [{{accept :accept} :headers :as request}] (case accept From 023cc369100481acd555ff3a523ce4186467f96e Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Fri, 1 Sep 2017 14:25:26 +0200 Subject: [PATCH 24/46] add type to run parameter spec --- .../src/com/sixsq/slipstream/ssclj/resources/run.clj | 12 ++++++------ .../ssclj/resources/spec/run_parameter.cljc | 4 +++- .../ssclj/resources/run_parameter_lifecycle_test.clj | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj index bda9690c2..cd3b71322 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj @@ -75,17 +75,17 @@ (defn create-parameters [identity {nodes :nodes run-href :id state :state}] ; run parameter state should not (let [user (:current identity)] - (create-parameter {:run-href run-href :name "state" :value state :acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:principal user - :type "USER" - :right "VIEW"}]}}) + (create-parameter {:run-href run-href :name "state" :value state :type "run" :acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal user + :type "USER" + :right "VIEW"}]}}) (doseq [n nodes] () (let [node-name (name (key n)) multiplicity (read-string (get-in (val n) [:parameters :multiplicity :default-value] "1"))] (doseq [i (range 1 (inc multiplicity))] - (create-parameter {:run-href run-href :node-name node-name :node-index i + (create-parameter {:run-href run-href :node-name node-name :node-index i :type "node-instance" :name "vmstate" :value "init" :acl {:owner {:principal "ADMIN" :type "ROLE"} :rules [{:principal user diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc index 4c7dfd072..417f02805 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc @@ -12,11 +12,13 @@ (s/def :cimi.run-parameter/node-name :cimi.core/nonblank-string) (s/def :cimi.run-parameter/node-index pos-int?) (s/def :cimi.run-parameter/description string?) +(s/def :cimi.run-parameter/type #{"run" "node" "node-instance"}) (s/def :cimi/run-parameter (su/only-keys-maps c/common-attrs {:req-un [:cimi.run-parameter/run-href - :cimi.run-parameter/name] + :cimi.run-parameter/name + :cimi.run-parameter/type] :opt-un [:cimi.run-parameter/node-name :cimi.run-parameter/node-index :cimi.run-parameter/description diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj index 7a0088fd1..218a69ec6 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj @@ -41,7 +41,7 @@ (deftest create-run-parameter-xyz (let [run-href "run/abc34916-6ede-47f7-aaeb-a30ddecbba5b" - valid-entry {:run-href run-href :node-name "machine" :node-index 1 + valid-entry {:run-href run-href :node-name "machine" :node-index 1 :type "node" :name "xyz" :value "XYZ" :acl resource-acl-jane} znode-path (zkru/run-parameter-znode-path valid-entry) run-parameter-id (-> From 52075aa68a8c369b180a3d98a291a48bc4f4ab85 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Fri, 1 Sep 2017 18:45:06 +0200 Subject: [PATCH 25/46] store values in elasticsearch --- ssclj/jar/resources/log4j.properties | 6 ++- .../ssclj/resources/run_parameter.clj | 51 ++++++++++--------- .../ssclj/resources/zk/run/utils.clj | 7 +-- .../ssclj/resources/lifecycle_test_utils.clj | 3 +- 4 files changed, 36 insertions(+), 31 deletions(-) diff --git a/ssclj/jar/resources/log4j.properties b/ssclj/jar/resources/log4j.properties index a65e9952d..4a759462f 100644 --- a/ssclj/jar/resources/log4j.properties +++ b/ssclj/jar/resources/log4j.properties @@ -1,8 +1,12 @@ # Root logger and StratusLab logger set to INFO level of debugging. -log4j.rootLogger=INFO, A1 +log4j.rootLogger=DEBUG, console log4j.logger.com.sixsq.slipstream.ssclj=INFO log4j.logger.com.mchange=WARN +log4j.appender.console=org.apache.log4j.ConsoleAppender +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern=%-5p %c: %m%n + # A1 is set to be a ConsoleAppender. log4j.appender.A1=org.apache.log4j.RollingFileAppender log4j.appender.A1.File=logs/ssclj-${logfile.path}.log diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj index 918c31f48..e1093465f 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj @@ -1,6 +1,7 @@ (ns com.sixsq.slipstream.ssclj.resources.run-parameter (:require [clojure.spec.alpha :as s] + [clojure.string :as string] [com.sixsq.slipstream.ssclj.resources.spec.run-parameter] [com.sixsq.slipstream.ssclj.resources.common.std-crud :as std-crud] [com.sixsq.slipstream.ssclj.resources.common.schema :as c] @@ -55,6 +56,21 @@ ;; CRUD operations ;; +(def run-parameter-id-separator "_") + +(defn run-parameter-id + [{run-href :run-href node-name :node-name node-index :node-index name :name :as run-parameter}] + (let [run-href (string/replace-first run-href #"^run/" "")] + (cond + (and run-href node-name node-index) (string/join run-parameter-id-separator [run-href node-name node-index name]) + (and run-href node-name) (string/join run-parameter-id-separator [run-href node-name name]) + run-href (string/join run-parameter-id-separator [run-href name])))) + +(defmethod crud/new-identifier resource-name + [json resource-name] + (let [new-id (str resource-url "/" (run-parameter-id json))] + (assoc json :id new-id))) + (defn add-value-run-parameter [run-parameter & {:keys [watcher]}] (try (let [value (if watcher @@ -68,19 +84,14 @@ (a/can-modify? {:acl collection-acl} request) (let [run-parameter (-> body u/strip-service-attrs - (dissoc :value) (crud/new-identifier resource-name) (assoc :resourceURI resource-uri) u/update-timestamps (crud/add-acl request) crud/validate) response (db/add resource-name run-parameter {}) - run-href (:run-href body) - node-name (:node-name body) - node-index (:node-index body) - name (:name body) value (:value body) - node-path (zkru/parameter-znode-path run-href node-name node-index name)] + node-path (zkru/run-parameter-znode-path body)] (uzk/create-all node-path :persistent? true) (uzk/set-data node-path value) response)) @@ -104,12 +115,15 @@ (add-value-run-parameter :watcher (partial watch-fn event-ch id name)))] (sse/send-event id name run-parameter event-ch))) -(defn retrieve-run-parameter [{{uuid :uuid} :params :as request}] - (-> (str (u/de-camelcase resource-name) "/" uuid) - (db/retrieve request) - (a/can-view? request) - (crud/set-operations request) - (add-value-run-parameter))) +(defn retrieve-run-parameter + [{{uuid :uuid} :params :as request}] + (try + (-> (str (u/de-camelcase resource-name) "/" uuid) + (db/retrieve request) + (a/can-view? request) + (crud/set-operations request)) + (catch ExceptionInfo ei + (ex-data ei)))) (def retrieve-sse-impl (sse/event-channel-handler @@ -119,8 +133,7 @@ (send-event-and-set-watcher event-ch transiant-watch-fn run-parameter))) {:on-client-disconnect #(log/debug "sse/on-client-disconnect: " %)})) -(defn retrieve-json-impl [request] - (r/json-response (retrieve-run-parameter request))) +(def retrieve-json-impl (std-crud/retrieve-fn resource-name)) (defmethod crud/retrieve resource-name [{{accept :accept} :headers :as request}] @@ -138,7 +151,6 @@ (-> merged (u/update-timestamps) (crud/validate) - (dissoc :value) (db/edit request)) (when value (uzk/set-data (zkru/run-parameter-znode-path merged) value)))) ;TODO what if znode not found @@ -164,15 +176,6 @@ (def query-json-impl (std-crud/query-fn resource-name collection-acl collection-uri resource-tag)) -(defn query-json-impl [request] - (a/can-view? {:acl collection-acl} request) - (let [wrapper-fn (std-crud/collection-wrapper-fn resource-name collection-acl collection-uri resource-tag) - options (select-keys request [:identity :query-params :cimi-params :user-name :user-roles]) - [metadata entries] (db/query resource-name options) - entries (doall (map add-value-run-parameter entries)) - entries-and-count (merge metadata (wrapper-fn request entries))] - (r/json-response entries-and-count))) - (defmethod crud/query resource-name [{{accept :accept} :headers :as request}] (case accept diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj index 5a24db79e..144668d41 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj @@ -7,17 +7,14 @@ (def nodes-txt "nodes") -(defn parameter-znode-path [run-href node-name node-index name] +(defn run-parameter-znode-path + [{run-href :run-href node-name :node-name node-index :node-index name :name :as run-parameter}] (->> (cond (and run-href node-name node-index) (string/join znode-separator [run-href nodes-txt node-name node-index name]) (and run-href node-name) (string/join znode-separator [run-href nodes-txt node-name name]) run-href (string/join znode-separator [run-href name])) (str znode-separator))) -(defn run-parameter-znode-path - [{run-href :run-href node-name :node-name node-index :node-index name :name :as run-parameter}] - (parameter-znode-path run-href node-name node-index name)) - ;(defn run-id-path [run-id]) ; (str runs-path "/" run-id)) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj index 1800a85ec..b480f91ad 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj @@ -21,7 +21,8 @@ [com.sixsq.slipstream.db.es.binding :as esb] [com.sixsq.slipstream.db.es.utils :as esu] [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] - [zookeeper :as zk]) + [zookeeper :as zk] + [zookeeper.server :as zks]) (:import [org.apache.curator.test TestingServer])) (defn serialize-cookie-value From 266984be296940fe03d1f052dbb035b72923dea6 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Tue, 5 Sep 2017 11:38:18 +0200 Subject: [PATCH 26/46] renaming run resource to deployment --- .../resources/{run.clj => deployment.clj} | 85 +++++++++--------- ...parameter.clj => deployment_parameter.clj} | 86 +++++++++---------- .../ssclj/resources/spec/deployment.cljc | 71 +++++++++++++++ .../resources/spec/deployment_parameter.cljc | 25 ++++++ .../slipstream/ssclj/resources/spec/run.cljc | 70 --------------- .../ssclj/resources/spec/run_parameter.cljc | 25 ------ .../zk/{run => deployment}/state_machine.clj | 2 +- .../zk/{run => deployment}/utils.clj | 13 +-- ...test.clj => deployment_lifecycle_test.clj} | 60 ++++++------- ...> deployment_parameter_lifecycle_test.clj} | 25 +++--- .../ssclj/resources/spec/deployment_test.cljc | 53 ++++++++++++ .../ssclj/resources/spec/run_test.cljc | 48 ----------- 12 files changed, 285 insertions(+), 278 deletions(-) rename ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/{run.clj => deployment.clj} (63%) rename ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/{run_parameter.clj => deployment_parameter.clj} (58%) create mode 100644 ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc create mode 100644 ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_parameter.cljc delete mode 100644 ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc delete mode 100644 ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc rename ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/{run => deployment}/state_machine.clj (96%) rename ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/{run => deployment}/utils.clj (72%) rename ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/{run_lifecycle_test.clj => deployment_lifecycle_test.clj} (61%) rename ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/{run_parameter_lifecycle_test.clj => deployment_parameter_lifecycle_test.clj} (73%) create mode 100644 ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/deployment_test.cljc delete mode 100644 ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/run_test.cljc diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj similarity index 63% rename from ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj rename to ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj index cd3b71322..e65fa3424 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj @@ -1,16 +1,15 @@ -(ns com.sixsq.slipstream.ssclj.resources.run +(ns com.sixsq.slipstream.ssclj.resources.deployment (:require [clojure.stacktrace :as st] [clojure.spec.alpha :as s] - [com.sixsq.slipstream.ssclj.resources.spec.run] + [com.sixsq.slipstream.ssclj.resources.spec.deployment] [com.sixsq.slipstream.ssclj.resources.common.std-crud :as std-crud] [com.sixsq.slipstream.ssclj.resources.common.schema :as c] [com.sixsq.slipstream.ssclj.resources.common.crud :as crud] [com.sixsq.slipstream.ssclj.resources.common.utils :as u] - [com.sixsq.slipstream.ssclj.resources.zk.run.utils :as zru] - [com.sixsq.slipstream.ssclj.resources.run-parameter :as rp] + [com.sixsq.slipstream.ssclj.resources.deployment-parameter :as dp] [com.sixsq.slipstream.ssclj.middleware.authn-info-header :refer [create-identity-map]] - [com.sixsq.slipstream.ssclj.resources.zk.run.state-machine :as rsm] + [com.sixsq.slipstream.ssclj.resources.zk.deployment.state-machine :as zdsm] [com.sixsq.slipstream.auth.acl :as a] [superstring.core :as str] [ring.util.response :as r] @@ -21,13 +20,13 @@ [clj-time.core :as time]) (:import (clojure.lang ExceptionInfo))) -(def ^:const resource-name "Run") +(def ^:const resource-name "Deployment") (def ^:const resource-tag (keyword (str (str/camel-case resource-name) "s"))) (def ^:const resource-url (u/de-camelcase resource-name)) -(def ^:const collection-name "RunCollection") +(def ^:const collection-name "DeploymentCollection") (def ^:const resource-uri (str c/slipstream-schema-uri resource-name)) @@ -43,7 +42,7 @@ ;; multimethods for validation and operations ;; -(def validate-fn (u/create-spec-validation-fn :cimi/run)) +(def validate-fn (u/create-spec-validation-fn :cimi/deployment)) (defmethod crud/validate resource-uri [resource] (validate-fn resource)) @@ -60,48 +59,48 @@ [json _] json) -(defn create-parameter [run-parameter] +(defn create-parameter [deployment-parameter] (try - (let [request {:params {:resource-name rp/resource-url} + (let [request {:params {:resource-name dp/resource-url} :identity (create-identity-map ["super" #{"ADMIN"}]) - :body run-parameter} - {:keys [status body]} (rp/add-impl request)] + :body deployment-parameter} + {:keys [status body]} (dp/add-impl request)] (case status - 201 (log/info "created run-parameter: " body) - (log/info "unexpected status code when creating run-parameter resource:" status))) + 201 (log/info "created deployment-parameter: " body) + (log/info "unexpected status code when creating deployment-parameter resource:" status))) (catch Exception e - (log/warn "error when creating run-parameter resource: " (str e) "\n" + (log/warn "error when creating deployment-parameter resource: " (str e) "\n" (with-out-str (st/print-cause-trace e)))))) -(defn create-parameters [identity {nodes :nodes run-href :id state :state}] ; run parameter state should not +(defn create-parameters [identity {nodes :nodes deployment-href :id state :state}] ; deployment parameter state should not (let [user (:current identity)] - (create-parameter {:run-href run-href :name "state" :value state :type "run" :acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:principal user - :type "USER" - :right "VIEW"}]}}) + (create-parameter {:deployment-href deployment-href :name "state" :value state :type "deployment" :acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal user + :type "USER" + :right "VIEW"}]}}) (doseq [n nodes] () (let [node-name (name (key n)) multiplicity (read-string (get-in (val n) [:parameters :multiplicity :default-value] "1"))] (doseq [i (range 1 (inc multiplicity))] - (create-parameter {:run-href run-href :node-name node-name :node-index i :type "node-instance" - :name "vmstate" :value "init" :acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:principal user - :type "USER" - :right "MODIFY"}]}})))))) + (create-parameter {:deployment-href deployment-href :node-name node-name :node-index i :type "node-instance" + :name "vmstate" :value "init" :acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal user + :type "USER" + :right "MODIFY"}]}})))))) (defn add-impl [{body :body :as request}] (a/can-modify? {:acl collection-acl} request) - (let [new-run (-> body - (dissoc :created :updated :resourceURI :operations) - (crud/new-identifier resource-name) - (assoc :resourceURI resource-uri) - u/update-timestamps - (crud/add-acl request) - (assoc :state rsm/initial-state)) - response (db/add resource-name (crud/validate new-run) {})] + (let [new-deployment (-> body + (dissoc :created :updated :resourceURI :operations) + (crud/new-identifier resource-name) + (assoc :resourceURI resource-uri) + u/update-timestamps + (crud/add-acl request) + (assoc :state zdsm/initial-state)) + response (db/add resource-name (crud/validate new-deployment) {})] response)) (defmethod crud/add resource-name @@ -156,9 +155,9 @@ ;; actions ;; -(defn add-start-time [run] +(defn add-start-time [deployment] (let [now (u/time-now)] - (assoc run :start-time now))) + (assoc deployment :start-time now))) (defmethod crud/do-action [resource-url "start"] [{{uuid :uuid} :params identity :identity :as request}] @@ -166,12 +165,12 @@ (let [current (-> (str (u/de-camelcase resource-name) "/" uuid) (db/retrieve request) (a/can-modify? request)) - run (-> current - (add-start-time) - (u/update-timestamps) - (crud/validate) - (db/edit request))] + deployment (-> current + (add-start-time) + (u/update-timestamps) + (crud/validate) + (db/edit request))] (create-parameters identity current) - run) + deployment) (catch ExceptionInfo ei (ex-data ei)))) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj similarity index 58% rename from ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj rename to ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj index e1093465f..dfd39375a 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/run_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj @@ -1,8 +1,8 @@ -(ns com.sixsq.slipstream.ssclj.resources.run-parameter +(ns com.sixsq.slipstream.ssclj.resources.deployment-parameter (:require [clojure.spec.alpha :as s] [clojure.string :as string] - [com.sixsq.slipstream.ssclj.resources.spec.run-parameter] + [com.sixsq.slipstream.ssclj.resources.spec.deployment-parameter] [com.sixsq.slipstream.ssclj.resources.common.std-crud :as std-crud] [com.sixsq.slipstream.ssclj.resources.common.schema :as c] [com.sixsq.slipstream.ssclj.resources.common.crud :as crud] @@ -17,17 +17,17 @@ [clojure.core.async :as async] [zookeeper :as zk] [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] - [com.sixsq.slipstream.ssclj.resources.zk.run.utils :as zkru] + [com.sixsq.slipstream.ssclj.resources.zk.deployment.utils :as zdu] ) (:import (clojure.lang ExceptionInfo))) -(def ^:const resource-name "RunParameter") +(def ^:const resource-name "DeploymentParameter") (def ^:const resource-tag (keyword (str (str/camel-case resource-name) "s"))) (def ^:const resource-url (u/de-camelcase resource-name)) -(def ^:const collection-name "RunParameterCollection") +(def ^:const collection-name "DeploymentParameterCollection") (def ^:const resource-uri (str c/slipstream-schema-uri resource-name)) @@ -43,7 +43,7 @@ ;; multimethods for validation and operations ;; -(def validate-fn (u/create-spec-validation-fn :cimi/run-parameter)) +(def validate-fn (u/create-spec-validation-fn :cimi/deployment-parameter)) (defmethod crud/validate resource-uri [resource] (validate-fn resource)) @@ -56,66 +56,66 @@ ;; CRUD operations ;; -(def run-parameter-id-separator "_") +(def deployment-parameter-id-separator "_") -(defn run-parameter-id - [{run-href :run-href node-name :node-name node-index :node-index name :name :as run-parameter}] - (let [run-href (string/replace-first run-href #"^run/" "")] +(defn deployment-parameter-id + [{deployment-href :deployment-href node-name :node-name node-index :node-index name :name :as deployment-parameter}] + (let [deployment-href (string/replace-first deployment-href #"^deployment/" "")] (cond - (and run-href node-name node-index) (string/join run-parameter-id-separator [run-href node-name node-index name]) - (and run-href node-name) (string/join run-parameter-id-separator [run-href node-name name]) - run-href (string/join run-parameter-id-separator [run-href name])))) + (and deployment-href node-name node-index) (string/join deployment-parameter-id-separator [deployment-href node-name node-index name]) + (and deployment-href node-name) (string/join deployment-parameter-id-separator [deployment-href node-name name]) + deployment-href (string/join deployment-parameter-id-separator [deployment-href name])))) (defmethod crud/new-identifier resource-name [json resource-name] - (let [new-id (str resource-url "/" (run-parameter-id json))] + (let [new-id (str resource-url "/" (deployment-parameter-id json))] (assoc json :id new-id))) -(defn add-value-run-parameter [run-parameter & {:keys [watcher]}] +(defn add-value-deployment-parameter [deployment-parameter & {:keys [watcher]}] (try (let [value (if watcher - (uzk/get-data (zkru/run-parameter-znode-path run-parameter) :watcher watcher) - (uzk/get-data (zkru/run-parameter-znode-path run-parameter)))] - (assoc run-parameter :value value)) - (catch ExceptionInfo ei ;TODO what if data not found + (uzk/get-data (zdu/deployment-parameter-znode-path deployment-parameter) :watcher watcher) + (uzk/get-data (zdu/deployment-parameter-znode-path deployment-parameter)))] + (assoc deployment-parameter :value value)) + (catch ExceptionInfo ei ;TODO what if data not found (ex-data ei)))) (defn add-impl [{:keys [body] :as request}] (a/can-modify? {:acl collection-acl} request) - (let [run-parameter (-> body - u/strip-service-attrs - (crud/new-identifier resource-name) - (assoc :resourceURI resource-uri) - u/update-timestamps - (crud/add-acl request) - crud/validate) - response (db/add resource-name run-parameter {}) + (let [deployment-parameter (-> body + u/strip-service-attrs + (crud/new-identifier resource-name) + (assoc :resourceURI resource-uri) + u/update-timestamps + (crud/add-acl request) + crud/validate) + response (db/add resource-name deployment-parameter {}) value (:value body) - node-path (zkru/run-parameter-znode-path body)] + node-path (zdu/deployment-parameter-znode-path body)] (uzk/create-all node-path :persistent? true) (uzk/set-data node-path value) response)) (defn transiant-watch-fn [event-ch id name {:keys [event-type path :as zk-event]}] (when (= event-type :NodeDataChanged) - (let [run-parameter (-> (db/retrieve id {}) - (add-value-run-parameter))] - (sse/send-event id name run-parameter event-ch) + (let [deployment-parameter (-> (db/retrieve id {}) + (add-value-deployment-parameter))] + (sse/send-event id name deployment-parameter event-ch) (async/close! event-ch)))) (defn persistent-watch-fn [event-ch id name {:keys [event-type path :as zk-event]}] (when (= event-type :NodeDataChanged) - (let [run-parameter (-> (db/retrieve id {}) - (add-value-run-parameter :watcher (partial persistent-watch-fn event-ch id name)))] - (sse/send-event id name run-parameter event-ch)))) + (let [deployment-parameter (-> (db/retrieve id {}) + (add-value-deployment-parameter :watcher (partial persistent-watch-fn event-ch id name)))] + (sse/send-event id name deployment-parameter event-ch)))) (defn send-event-and-set-watcher - [event-ch watch-fn {id :id name :name :as run-parameter}] - (let [run-parameter (-> run-parameter - (add-value-run-parameter :watcher (partial watch-fn event-ch id name)))] - (sse/send-event id name run-parameter event-ch))) + [event-ch watch-fn {id :id name :name :as deployment-parameter}] + (let [deployment-parameter (-> deployment-parameter + (add-value-deployment-parameter :watcher (partial watch-fn event-ch id name)))] + (sse/send-event id name deployment-parameter event-ch))) -(defn retrieve-run-parameter +(defn retrieve-deployment-parameter [{{uuid :uuid} :params :as request}] (try (-> (str (u/de-camelcase resource-name) "/" uuid) @@ -128,9 +128,9 @@ (def retrieve-sse-impl (sse/event-channel-handler (fn [request response raise event-ch] - (let [{id :id name :name :as run-parameter} (retrieve-run-parameter request) - node-path (zkru/run-parameter-znode-path run-parameter)] - (send-event-and-set-watcher event-ch transiant-watch-fn run-parameter))) + (let [{id :id name :name :as deployment-parameter} (retrieve-deployment-parameter request) + node-path (zdu/deployment-parameter-znode-path deployment-parameter)] + (send-event-and-set-watcher event-ch transiant-watch-fn deployment-parameter))) {:on-client-disconnect #(log/debug "sse/on-client-disconnect: " %)})) (def retrieve-json-impl (std-crud/retrieve-fn resource-name)) @@ -153,7 +153,7 @@ (crud/validate) (db/edit request)) (when value - (uzk/set-data (zkru/run-parameter-znode-path merged) value)))) ;TODO what if znode not found + (uzk/set-data (zdu/deployment-parameter-znode-path merged) value)))) ;TODO what if znode not found (defmethod crud/edit resource-name [request] diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc new file mode 100644 index 000000000..8ab8891bc --- /dev/null +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc @@ -0,0 +1,71 @@ +(ns com.sixsq.slipstream.ssclj.resources.spec.deployment + (:require + [clojure.spec.alpha :as s] + [clojure.spec.gen.alpha :as gen] + [clojure.string :as str] + [com.sixsq.slipstream.ssclj.util.spec :as su] + [com.sixsq.slipstream.ssclj.resources.spec.common :as c])) + +(s/def :cimi.deployment/id :cimi.core/nonblank-string) ;TODO enhance +(s/def :cimi.deployment/module-resource-uri :cimi.core/uri) +(s/def :cimi.deployment/type #{"Run" "Orchestration" "Machine"}) ;TODO rename +(s/def :cimi.deployment/category #{"Image" "Deployment"}) +(s/def :cimi.deployment/start-time :cimi.core/timestamp) +(s/def :cimi.deployment/end-time :cimi.core/timestamp) +(s/def :cimi.deployment/last-state-change-time :cimi.core/timestamp) +(s/def :cimi.deployment/mutable boolean?) +(s/def :cimi.deployment/state + #{"init" "provisioning" "executing" "sending report" "finalyzing" "terminated" "canceled" "done"}) + +(s/def :cimi.deployment.parameter/description string?) +(s/def :cimi.deployment.parameter/default-value string?) +(s/def :cimi.deployment.parameter/user-choice-value string?) + +(s/def :cimi.deployment/parameter (su/only-keys-maps {:opt-un [:cimi.deployment.parameter/description + :cimi.deployment.parameter/default-value + :cimi.deployment.parameter/user-choice-value]})) + +(s/def :cimi.deployment.node/cpu.nb :cimi.deployment/parameter) +(s/def :cimi.deployment.node/ram.GB :cimi.deployment/parameter) +(s/def :cimi.deployment.node/disk.GB :cimi.deployment/parameter) +(s/def :cimi.deployment.node/multiplicity :cimi.deployment/parameter) +(s/def :cimi.deployment.node/max-provisioning-failures :cimi.deployment/parameter) +(s/def :cimi.deployment.node/cloudservice :cimi.deployment/parameter) + +(s/def :cimi.deployment/parameters + (su/only-keys-maps + {:req-un [:cimi.deployment.node/cloudservice] + :opt-un [:cimi.deployment.node/multiplicity + :cimi.deployment.node/max-provisioning-failures + :cimi.deployment.node/cpu.nb + :cimi.deployment.node/ram.GB + :cimi.deployment.node/disk.GB]})) + +(s/def :cimi.deployment.runtime-parameter/mapped-to :cimi.core/nonblank-string) + +(s/def :cimi.deployment.node/runtime-parameter (su/only-keys-maps + {:opt-un [:cimi.deployment.parameter/description + :cimi.deployment.parameter/default-value + :cimi.deployment.parameter/user-choice-value + :cimi.deployment.runtime-parameter/mapped-to]})) + +(s/def :cimi.deployment/runtime-parameters + (su/constrained-map keyword? :cimi.deployment.node/runtime-parameter)) + +(s/def :cimi.deployment/node (su/only-keys-maps {:req-un [:cimi.deployment/parameters] + :opt-un [:cimi.deployment/runtime-parameters]})) + +(s/def :cimi.deployment/nodes (su/constrained-map keyword? :cimi.deployment/node)) + +(def deployment-attrs {:req-un [:cimi.deployment/id + :cimi.deployment/module-resource-uri + :cimi.deployment/type + :cimi.deployment/category + :cimi.deployment/mutable + :cimi.deployment/nodes] + :opt-un [:cimi.deployment/start-time + :cimi.deployment/end-time + :cimi.deployment/last-state-change-time + :cimi.deployment/state]}) + +(s/def :cimi/deployment (su/only-keys-maps c/common-attrs deployment-attrs)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_parameter.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_parameter.cljc new file mode 100644 index 000000000..e630728b6 --- /dev/null +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_parameter.cljc @@ -0,0 +1,25 @@ +(ns com.sixsq.slipstream.ssclj.resources.spec.deployment-parameter + (:require + [clojure.spec.alpha :as s] + [clojure.spec.gen.alpha :as gen] + [clojure.string :as str] + [com.sixsq.slipstream.ssclj.util.spec :as su] + [com.sixsq.slipstream.ssclj.resources.spec.common :as c])) + +(s/def :cimi.deployment-parameter/deployment-href :cimi.core/nonblank-string) +(s/def :cimi.deployment-parameter/name :cimi.core/nonblank-string) +(s/def :cimi.deployment-parameter/value string?) +(s/def :cimi.deployment-parameter/node-name :cimi.core/nonblank-string) +(s/def :cimi.deployment-parameter/node-index pos-int?) +(s/def :cimi.deployment-parameter/description string?) +(s/def :cimi.deployment-parameter/type #{"deployment" "node" "node-instance"}) + +(s/def :cimi/deployment-parameter + (su/only-keys-maps c/common-attrs + {:req-un [:cimi.deployment-parameter/deployment-href + :cimi.deployment-parameter/name + :cimi.deployment-parameter/type] + :opt-un [:cimi.deployment-parameter/node-name + :cimi.deployment-parameter/node-index + :cimi.deployment-parameter/description + :cimi.deployment-parameter/value]})) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc deleted file mode 100644 index a4cf43c6c..000000000 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run.cljc +++ /dev/null @@ -1,70 +0,0 @@ -(ns com.sixsq.slipstream.ssclj.resources.spec.run - (:require - [clojure.spec.alpha :as s] - [clojure.spec.gen.alpha :as gen] - [clojure.string :as str] - [com.sixsq.slipstream.ssclj.util.spec :as su] - [com.sixsq.slipstream.ssclj.resources.spec.common :as c])) - -(s/def :cimi.run/id :cimi.core/nonblank-string) ;TODO enhance -(s/def :cimi.run/module-resource-uri :cimi.core/uri) -(s/def :cimi.run/type #{"Run" "Orchestration" "Machine"}) -(s/def :cimi.run/category #{"Image" "Deployment"}) -(s/def :cimi.run/start-time :cimi.core/timestamp) -(s/def :cimi.run/end-time :cimi.core/timestamp) -(s/def :cimi.run/last-state-change-time :cimi.core/timestamp) -(s/def :cimi.run/mutable boolean?) -(s/def :cimi.run/state #{"init" "provisioning" "executing" "sending report" "finalyzing" "terminated" "canceled" "done"}) - -(s/def :cimi.run.parameter/description string?) -(s/def :cimi.run.parameter/default-value string?) -(s/def :cimi.run.parameter/user-choice-value string?) - -(s/def :cimi.run/parameter (su/only-keys-maps {:opt-un [:cimi.run.parameter/description - :cimi.run.parameter/default-value - :cimi.run.parameter/user-choice-value]})) - -(s/def :cimi.run.node/cpu.nb :cimi.run/parameter) -(s/def :cimi.run.node/ram.GB :cimi.run/parameter) -(s/def :cimi.run.node/disk.GB :cimi.run/parameter) -(s/def :cimi.run.node/multiplicity :cimi.run/parameter) -(s/def :cimi.run.node/max-provisioning-failures :cimi.run/parameter) -(s/def :cimi.run.node/cloudservice :cimi.run/parameter) - -(s/def :cimi.run/parameters - (su/only-keys-maps - {:req-un [:cimi.run.node/cloudservice] - :opt-un [:cimi.run.node/multiplicity - :cimi.run.node/max-provisioning-failures - :cimi.run.node/cpu.nb - :cimi.run.node/ram.GB - :cimi.run.node/disk.GB]})) - -(s/def :cimi.run.runtime-parameter/mapped-to :cimi.core/nonblank-string) - -(s/def :cimi.run.node/runtime-parameter (su/only-keys-maps - {:opt-un [:cimi.run.parameter/description - :cimi.run.parameter/default-value - :cimi.run.parameter/user-choice-value - :cimi.run.runtime-parameter/mapped-to]})) - -(s/def :cimi.run/runtime-parameters - (su/constrained-map keyword? :cimi.run.node/runtime-parameter)) - -(s/def :cimi.run/node (su/only-keys-maps {:req-un [:cimi.run/parameters] - :opt-un [:cimi.run/runtime-parameters]})) - -(s/def :cimi.run/nodes (su/constrained-map keyword? :cimi.run/node)) - -(def run-attrs {:req-un [:cimi.run/id - :cimi.run/module-resource-uri - :cimi.run/type - :cimi.run/category - :cimi.run/mutable - :cimi.run/nodes] - :opt-un [:cimi.run/start-time - :cimi.run/end-time - :cimi.run/last-state-change-time - :cimi.run/state]}) - -(s/def :cimi/run (su/only-keys-maps c/common-attrs run-attrs)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc deleted file mode 100644 index 417f02805..000000000 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/run_parameter.cljc +++ /dev/null @@ -1,25 +0,0 @@ -(ns com.sixsq.slipstream.ssclj.resources.spec.run-parameter - (:require - [clojure.spec.alpha :as s] - [clojure.spec.gen.alpha :as gen] - [clojure.string :as str] - [com.sixsq.slipstream.ssclj.util.spec :as su] - [com.sixsq.slipstream.ssclj.resources.spec.common :as c])) - -(s/def :cimi.run-parameter/run-href :cimi.core/nonblank-string) -(s/def :cimi.run-parameter/name :cimi.core/nonblank-string) -(s/def :cimi.run-parameter/value string?) -(s/def :cimi.run-parameter/node-name :cimi.core/nonblank-string) -(s/def :cimi.run-parameter/node-index pos-int?) -(s/def :cimi.run-parameter/description string?) -(s/def :cimi.run-parameter/type #{"run" "node" "node-instance"}) - -(s/def :cimi/run-parameter - (su/only-keys-maps c/common-attrs - {:req-un [:cimi.run-parameter/run-href - :cimi.run-parameter/name - :cimi.run-parameter/type] - :opt-un [:cimi.run-parameter/node-name - :cimi.run-parameter/node-index - :cimi.run-parameter/description - :cimi.run-parameter/value]})) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/state_machine.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/state_machine.clj similarity index 96% rename from ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/state_machine.clj rename to ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/state_machine.clj index 59d9666ea..b1c0614a6 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/state_machine.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/state_machine.clj @@ -1,4 +1,4 @@ -(ns com.sixsq.slipstream.ssclj.resources.zk.run.state-machine +(ns com.sixsq.slipstream.ssclj.resources.zk.deployment.state-machine "This namespace uses ZooKeeper to create a distributed system to host the state of a run. Each VM is represented by an index node under its corresponding node. As each VM reports its current state completed, the corresponding index znode (i.e. ZooKeeper node) is removed from the structure. When no node remains, it means all VMs have diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj similarity index 72% rename from ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj rename to ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj index 144668d41..1cc4e5504 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/run/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj @@ -1,4 +1,4 @@ -(ns com.sixsq.slipstream.ssclj.resources.zk.run.utils +(ns com.sixsq.slipstream.ssclj.resources.zk.deployment.utils (:require [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] [zookeeper :as zk] [clojure.string :as string])) @@ -7,12 +7,13 @@ (def nodes-txt "nodes") -(defn run-parameter-znode-path - [{run-href :run-href node-name :node-name node-index :node-index name :name :as run-parameter}] +(defn deployment-parameter-znode-path + [{deployment-href :deployment-href node-name :node-name node-index :node-index name :name :as deployment-parameter}] (->> (cond - (and run-href node-name node-index) (string/join znode-separator [run-href nodes-txt node-name node-index name]) - (and run-href node-name) (string/join znode-separator [run-href nodes-txt node-name name]) - run-href (string/join znode-separator [run-href name])) + (and deployment-href node-name node-index) + (string/join znode-separator [deployment-href nodes-txt node-name node-index name]) + (and deployment-href node-name) (string/join znode-separator [deployment-href nodes-txt node-name name]) + deployment-href (string/join znode-separator [deployment-href name])) (str znode-separator))) ;(defn run-id-path [run-id]) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj similarity index 61% rename from ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj rename to ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj index 01c1d5bd2..375a32095 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj @@ -1,18 +1,18 @@ -(ns com.sixsq.slipstream.ssclj.resources.run-lifecycle-test +(ns com.sixsq.slipstream.ssclj.resources.deployment-lifecycle-test (:require [clojure.test :refer :all] [clojure.data.json :as json] [peridot.core :refer :all] [ring.util.codec :as rc] - [com.sixsq.slipstream.ssclj.resources.run :refer :all] - [com.sixsq.slipstream.ssclj.resources.run-parameter :as rp] + [com.sixsq.slipstream.ssclj.resources.deployment :refer :all] + [com.sixsq.slipstream.ssclj.resources.deployment-parameter :as rp] [com.sixsq.slipstream.ssclj.resources.lifecycle-test-utils :as t] [com.sixsq.slipstream.ssclj.middleware.authn-info-header :refer [authn-info-header]] [com.sixsq.slipstream.ssclj.app.routes :as routes] [com.sixsq.slipstream.ssclj.app.params :as p] [com.sixsq.slipstream.ssclj.resources.common.utils :as u] [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] - [com.sixsq.slipstream.ssclj.resources.zk.run.utils :as ru])) + [com.sixsq.slipstream.ssclj.resources.zk.deployment.utils :as zdu])) (use-fixtures :each t/with-test-es-client-fixture) @@ -41,7 +41,7 @@ :node2 {:parameters {:cloudservice {:description "param1 description" :default-value "abc"}}}}}) -(deftest create-run +(deftest create-deployment (let [session-admin-json (-> (session (ring-app)) (content-type "application/json") @@ -56,32 +56,34 @@ (content-type "application/json"))] ;; adding, retrieving and deleting entry as user should succeed - (let [run-href (-> session-user - (request base-uri - :request-method :post - :body (json/write-str valid-entry)) - (t/body->edn) - (t/is-status 201) - (t/location)) - abs-uri (str p/service-context (u/de-camelcase run-href)) - created-run (-> session-user - (request abs-uri) - (t/body->edn) - (t/is-status 200))] + (let [deployment-href (-> session-user + (request base-uri + :request-method :post + :body (json/write-str valid-entry)) + (t/body->edn) + (t/is-status 201) + (t/location)) + abs-uri (str p/service-context (u/de-camelcase deployment-href)) + created-deployment (-> session-user + (request abs-uri) + (t/body->edn) + (t/is-status 200))] - (is (not (uzk/exists (str ru/znode-separator run-href)))) + (is (not (uzk/exists (str zdu/znode-separator deployment-href)))) - (let [start-uri (str p/service-context (t/get-op created-run "http://schemas.dmtf.org/cimi/2/action/start")) - started-run (-> session-user - (request start-uri) - (t/body->edn) - (t/is-status 200))] + (let [start-uri (str p/service-context + (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) + started-deployment (-> session-user + (request start-uri) + (t/body->edn) + (t/is-status 200))] - (is (not (get-in created-run [:body :start-time]))) - (is (get-in started-run [:response :body :start-time])) + (is (not (get-in created-deployment [:body :start-time]))) + (is (get-in started-deployment [:response :body :start-time])) - (are [expected value] (= expected value) - "init" (uzk/get-data (str ru/znode-separator run-href "/state")) - "init" (uzk/get-data - (str ru/znode-separator run-href "/" ru/nodes-txt "/node2/1/" "vmstate"))))))) + (are [expected value] + (= expected value) + "init" (uzk/get-data (str zdu/znode-separator deployment-href "/state")) + "init" (uzk/get-data + (str zdu/znode-separator deployment-href "/" zdu/nodes-txt "/node2/1/" "vmstate"))))))) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj similarity index 73% rename from ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj rename to ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj index 218a69ec6..90830b7f0 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/run_parameter_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj @@ -1,18 +1,17 @@ -(ns com.sixsq.slipstream.ssclj.resources.run-parameter-lifecycle-test +(ns com.sixsq.slipstream.ssclj.resources.deployment-parameter-lifecycle-test (:require [clojure.test :refer :all] [clojure.data.json :as json] [peridot.core :refer :all] [ring.util.codec :as rc] - [com.sixsq.slipstream.ssclj.resources.run-parameter :refer :all] + [com.sixsq.slipstream.ssclj.resources.deployment-parameter :refer :all] [com.sixsq.slipstream.ssclj.resources.lifecycle-test-utils :as t] [com.sixsq.slipstream.ssclj.middleware.authn-info-header :refer [authn-info-header create-identity-map]] [com.sixsq.slipstream.ssclj.app.routes :as routes] [com.sixsq.slipstream.ssclj.app.params :as p] [com.sixsq.slipstream.ssclj.resources.common.utils :as u] [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] - [com.sixsq.slipstream.ssclj.resources.zk.run.utils :as ru] - [com.sixsq.slipstream.ssclj.resources.zk.run.utils :as zkru])) + [com.sixsq.slipstream.ssclj.resources.zk.deployment.utils :as zdu])) (use-fixtures :each t/with-test-es-client-fixture) @@ -39,12 +38,12 @@ :type "USER" :right "MODIFY"}]}) -(deftest create-run-parameter-xyz - (let [run-href "run/abc34916-6ede-47f7-aaeb-a30ddecbba5b" - valid-entry {:run-href run-href :node-name "machine" :node-index 1 :type "node" +(deftest create-deployment-parameter-xyz + (let [deployment-href "deployment/abc34916-6ede-47f7-aaeb-a30ddecbba5b" + valid-entry {:deployment-href deployment-href :node-name "machine" :node-index 1 :type "node" :name "xyz" :value "XYZ" :acl resource-acl-jane} - znode-path (zkru/run-parameter-znode-path valid-entry) - run-parameter-id (-> + znode-path (zdu/deployment-parameter-znode-path valid-entry) + deployment-parameter-id (-> (->> {:params {:resource-name resource-url} :identity identity-admin :body valid-entry} @@ -52,8 +51,8 @@ (assoc {} :response)) (t/is-status 201) (t/location)) - abs-uri (str p/service-context (u/de-camelcase run-parameter-id)) - created-run-parameter (-> session-user-jane + abs-uri (str p/service-context (u/de-camelcase deployment-parameter-id)) + created-deployment-parameter (-> session-user-jane (request abs-uri) (t/body->edn) (t/is-status 200))] @@ -66,7 +65,7 @@ (t/body->edn) (t/is-status 200)) - (is (= "newvalue" (uzk/get-data znode-path)) "run parameter can be updated") + (is (= "newvalue" (uzk/get-data znode-path)) "deployment parameter can be updated") (-> session-user-albert (request abs-uri :request-method :put @@ -74,5 +73,5 @@ (t/body->edn) (t/is-status 403)) - (is (not (= "newvalue-albert" (uzk/get-data znode-path))) "run parameter can be updated"))) + (is (not (= "newvalue-albert" (uzk/get-data znode-path))) "deployment parameter can be updated"))) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/deployment_test.cljc b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/deployment_test.cljc new file mode 100644 index 000000000..4cd2fb498 --- /dev/null +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/deployment_test.cljc @@ -0,0 +1,53 @@ +(ns com.sixsq.slipstream.ssclj.resources.spec.deployment-test + (:require + [clojure.test :refer :all] + [clojure.spec.alpha :as s] + [com.sixsq.slipstream.ssclj.resources.deployment :as d])) + +(def valid-acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:type "ROLE", + :principal "ADMIN", + :right "ALL"}]}) + +(deftest check-DeploymentInfo + (let [timestamp "1964-08-25T10:00:00.0Z" + deployment {:id (str d/resource-url "/deployment-uuid") + :created timestamp + :updated timestamp + :resourceURI d/resource-uri + :acl valid-acl + :module-resource-uri "module/examples/tutorials/service-testing/system/1940" + :category "Deployment" + :type "Orchestration" + :mutable false + :nodes {:node1 + {:parameters + {:cloudservice {:description "p1 description" + :default-value "abc" + :user-choice-value "ABC"} + :multiplicity {:default-value "1"}} + :runtime-parameters + {:p1 {:description "p1 description" + :default-value "abc" + :user-choice-value "ABC" + :mapped-to "a"}}} + :node2 + {:parameters + {:cloudservice {:description "param1 description" + :default-value "abc"}}}}}] + + (are [expect-fn arg] (expect-fn (s/valid? :cimi/deployment arg)) + true? deployment + false? (dissoc deployment :id) + false? (dissoc deployment :created) + false? (dissoc deployment :updated) + false? (dissoc deployment :acl) + false? (dissoc deployment :module-resource-uri) + false? (dissoc deployment :category) + false? (dissoc deployment :type) + false? (update deployment :category (constantly "bonjour")) + false? (dissoc deployment :mutable) + false? (assoc deployment :other "abc") + false? (dissoc deployment :nodes) + true? (assoc deployment :start-time timestamp)))) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/run_test.cljc b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/run_test.cljc deleted file mode 100644 index 2f8862849..000000000 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/run_test.cljc +++ /dev/null @@ -1,48 +0,0 @@ -(ns com.sixsq.slipstream.ssclj.resources.spec.run-test - (:require - [clojure.test :refer :all] - [clojure.spec.alpha :as s] - [com.sixsq.slipstream.ssclj.resources.run :as r])) - -(def valid-acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:type "ROLE", - :principal "ADMIN", - :right "ALL"}]}) - -(deftest check-RunInfo - (let [timestamp "1964-08-25T10:00:00.0Z" - run {:id (str r/resource-url "/run-uuid") - :created timestamp - :updated timestamp - :resourceURI r/resource-uri - :acl valid-acl - :module-resource-uri "module/examples/tutorials/service-testing/system/1940" - :category "Deployment" - :type "Orchestration" - :mutable false - :nodes {:node1 {:parameters {:cloudservice {:description "p1 description" - :default-value "abc" - :user-choice-value "ABC"} - :multiplicity {:default-value "1"}} - :runtime-parameters {:p1 {:description "p1 description" - :default-value "abc" - :user-choice-value "ABC" - :mapped-to "a"}}} - :node2 {:parameters {:cloudservice {:description "param1 description" - :default-value "abc"}}}}}] - - (are [expect-fn arg] (expect-fn (s/valid? :cimi/run arg)) - true? run - false? (dissoc run :id) - false? (dissoc run :created) - false? (dissoc run :updated) - false? (dissoc run :acl) - false? (dissoc run :module-resource-uri) - false? (dissoc run :category) - false? (dissoc run :type) - false? (update run :category (constantly "bonjour")) - false? (dissoc run :mutable) - false? (assoc run :other "abc") - false? (dissoc run :nodes) - true? (assoc run :start-time timestamp)))) From a63d62363613e6028b71d39f0a89e228fe137eb8 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Tue, 5 Sep 2017 20:19:06 +0200 Subject: [PATCH 27/46] update deployment attribute state when run parameter is updated --- .../slipstream/ssclj/resources/deployment.clj | 43 +---- .../ssclj/resources/deployment/utils.clj | 98 +++++++++++ .../ssclj/resources/deployment_parameter.clj | 45 ++--- .../sixsq/slipstream/ssclj/util/zookeeper.clj | 5 +- .../resources/deployment_lifecycle_test.clj | 160 ++++++++++++++++-- .../deployment_parameter_lifecycle_test.clj | 5 +- 6 files changed, 270 insertions(+), 86 deletions(-) create mode 100644 ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj index e65fa3424..1ad00a1ff 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj @@ -10,6 +10,7 @@ [com.sixsq.slipstream.ssclj.resources.deployment-parameter :as dp] [com.sixsq.slipstream.ssclj.middleware.authn-info-header :refer [create-identity-map]] [com.sixsq.slipstream.ssclj.resources.zk.deployment.state-machine :as zdsm] + [com.sixsq.slipstream.ssclj.resources.deployment.utils :as du] [com.sixsq.slipstream.auth.acl :as a] [superstring.core :as str] [ring.util.response :as r] @@ -20,11 +21,11 @@ [clj-time.core :as time]) (:import (clojure.lang ExceptionInfo))) -(def ^:const resource-name "Deployment") +(def ^:const resource-name du/deployment-resource-name) (def ^:const resource-tag (keyword (str (str/camel-case resource-name) "s"))) -(def ^:const resource-url (u/de-camelcase resource-name)) +(def ^:const resource-url du/deployment-resource-url) (def ^:const collection-name "DeploymentCollection") @@ -59,38 +60,6 @@ [json _] json) -(defn create-parameter [deployment-parameter] - (try - (let [request {:params {:resource-name dp/resource-url} - :identity (create-identity-map ["super" #{"ADMIN"}]) - :body deployment-parameter} - {:keys [status body]} (dp/add-impl request)] - (case status - 201 (log/info "created deployment-parameter: " body) - (log/info "unexpected status code when creating deployment-parameter resource:" status))) - (catch Exception e - (log/warn "error when creating deployment-parameter resource: " (str e) "\n" - (with-out-str (st/print-cause-trace e)))))) - -(defn create-parameters [identity {nodes :nodes deployment-href :id state :state}] ; deployment parameter state should not - (let [user (:current identity)] - (create-parameter {:deployment-href deployment-href :name "state" :value state :type "deployment" :acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:principal user - :type "USER" - :right "VIEW"}]}}) - (doseq [n nodes] - () - (let [node-name (name (key n)) - multiplicity (read-string (get-in (val n) [:parameters :multiplicity :default-value] "1"))] - (doseq [i (range 1 (inc multiplicity))] - (create-parameter {:deployment-href deployment-href :node-name node-name :node-index i :type "node-instance" - :name "vmstate" :value "init" :acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:principal user - :type "USER" - :right "MODIFY"}]}})))))) - (defn add-impl [{body :body :as request}] (a/can-modify? {:acl collection-acl} request) (let [new-deployment (-> body @@ -113,11 +82,9 @@ [request] (retrieve-impl request)) -(def edit-impl (std-crud/edit-fn resource-name)) - (defmethod crud/edit resource-name [request] - (edit-impl request)) + (du/edit-deployment-impl request)) (def delete-impl (std-crud/delete-fn resource-name)) @@ -170,7 +137,7 @@ (u/update-timestamps) (crud/validate) (db/edit request))] - (create-parameters identity current) + (du/create-parameters identity current) deployment) (catch ExceptionInfo ei (ex-data ei)))) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj new file mode 100644 index 000000000..768082526 --- /dev/null +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj @@ -0,0 +1,98 @@ +(ns com.sixsq.slipstream.ssclj.resources.deployment.utils + (:require + [com.sixsq.slipstream.auth.acl :as a] + [com.sixsq.slipstream.db.impl :as db] + [clojure.tools.logging :as log] + [clojure.stacktrace :as st] + [com.sixsq.slipstream.ssclj.resources.common.utils :as u] + [com.sixsq.slipstream.ssclj.resources.common.schema :as c] + [com.sixsq.slipstream.ssclj.resources.common.crud :as crud] + [com.sixsq.slipstream.ssclj.resources.common.std-crud :as std-crud] + [com.sixsq.slipstream.ssclj.middleware.authn-info-header :refer [create-identity-map]] + [com.sixsq.slipstream.ssclj.resources.zk.deployment.utils :as zdu] + [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] + [clojure.string :as string])) + +(def ^:const deployment-parameter-resource-name "DeploymentParameter") + +(def ^:const deployment-parameter-resource-url (u/de-camelcase deployment-parameter-resource-name)) + +(def ^:const deployment-parameter-resource-uri (str c/slipstream-schema-uri deployment-parameter-resource-name)) + +(def deployment-parameter-collection-acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal "USER" + :type "ROLE" + :right "MODIFY"}]}) + +(defn add-deployment-parameter-impl [{:keys [body] :as request}] + (a/can-modify? {:acl deployment-parameter-collection-acl} request) + (let [deployment-parameter (-> body + u/strip-service-attrs + (crud/new-identifier deployment-parameter-resource-name) + (assoc :resourceURI deployment-parameter-resource-uri) + u/update-timestamps + (crud/add-acl request) + crud/validate) + response (db/add deployment-parameter-resource-name deployment-parameter {}) + value (:value body) + node-path (zdu/deployment-parameter-znode-path body)] + (uzk/create-all node-path :persistent? true) + (uzk/set-data node-path value) + response)) + +(defn create-parameter [deployment-parameter] + (try + (let [request {:params {:resource-name deployment-parameter-resource-url} + :identity (create-identity-map ["super" #{"ADMIN"}]) + :body deployment-parameter} + {:keys [status body]} (add-deployment-parameter-impl request)] + (case status + 201 (log/info "created deployment-parameter: " body) + (log/info "unexpected status code when creating deployment-parameter resource:" status))) + (catch Exception e + (log/warn "error when creating deployment-parameter resource: " (str e) "\n" + (with-out-str (st/print-cause-trace e)))))) + +(defn create-parameters [identity {nodes :nodes deployment-href :id state :state}] + (let [user (:current identity)] + (create-parameter + {:deployment-href deployment-href :name "state" :value state :type "deployment" + :acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal user + :type "USER" + :right "VIEW"}]}}) + (doseq [n nodes] + () + (let [node-name (name (key n)) + multiplicity (read-string (get-in (val n) [:parameters :multiplicity :default-value] "1"))] + (doseq [i (range 1 (inc multiplicity))] + (create-parameter {:deployment-href deployment-href :node-name node-name :node-index i :type "node-instance" + :name "vmstate" :value "init" :acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal user + :type "USER" + :right "MODIFY"}]}})))))) + +(def ^:const deployment-resource-name "Deployment") + +(def ^:const deployment-resource-url (u/de-camelcase deployment-resource-name)) + +(def edit-deployment-impl (std-crud/edit-fn deployment-resource-name)) + +(defn deployment-href-to-uuid [href] (string/replace-first href #"^deployment/" "")) + +(defn update-deployment-state [deployment-uuid state] + (try + (let [request {:params {:resource-name deployment-resource-url + :uuid deployment-uuid} + :identity (create-identity-map ["super" #{"ADMIN"}]) + :body {:state state}} + {:keys [status body]} (edit-deployment-impl request)] + (case status + 200 (log/info "udpated deployment state: " body) + (log/info "unexpected status code when udpating deployment resource:" status))) + (catch Exception e + (log/warn "error when updating deployment resource: " (str e) "\n" + (with-out-str (st/print-cause-trace e)))))) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj index dfd39375a..6ee69b0de 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj @@ -18,26 +18,23 @@ [zookeeper :as zk] [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] [com.sixsq.slipstream.ssclj.resources.zk.deployment.utils :as zdu] + [com.sixsq.slipstream.ssclj.resources.deployment.utils :as du] ) (:import (clojure.lang ExceptionInfo))) -(def ^:const resource-name "DeploymentParameter") +(def ^:const resource-name du/deployment-parameter-resource-name) (def ^:const resource-tag (keyword (str (str/camel-case resource-name) "s"))) -(def ^:const resource-url (u/de-camelcase resource-name)) +(def ^:const resource-url du/deployment-parameter-resource-url) (def ^:const collection-name "DeploymentParameterCollection") -(def ^:const resource-uri (str c/slipstream-schema-uri resource-name)) +(def ^:const resource-uri du/deployment-parameter-resource-uri) (def ^:const collection-uri (str c/slipstream-schema-uri collection-name)) -(def collection-acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:principal "USER" - :type "ROLE" - :right "MODIFY"}]}) +(def collection-acl du/deployment-parameter-collection-acl) ;; ;; multimethods for validation and operations @@ -60,11 +57,11 @@ (defn deployment-parameter-id [{deployment-href :deployment-href node-name :node-name node-index :node-index name :name :as deployment-parameter}] - (let [deployment-href (string/replace-first deployment-href #"^deployment/" "")] + (let [deployment-uuid (du/deployment-href-to-uuid deployment-href)] (cond - (and deployment-href node-name node-index) (string/join deployment-parameter-id-separator [deployment-href node-name node-index name]) - (and deployment-href node-name) (string/join deployment-parameter-id-separator [deployment-href node-name name]) - deployment-href (string/join deployment-parameter-id-separator [deployment-href name])))) + (and deployment-uuid node-name node-index) (string/join deployment-parameter-id-separator [deployment-uuid node-name node-index name]) + (and deployment-uuid node-name) (string/join deployment-parameter-id-separator [deployment-uuid node-name name]) + deployment-uuid (string/join deployment-parameter-id-separator [deployment-uuid name])))) (defmethod crud/new-identifier resource-name [json resource-name] @@ -80,22 +77,6 @@ (catch ExceptionInfo ei ;TODO what if data not found (ex-data ei)))) -(defn add-impl [{:keys [body] :as request}] - (a/can-modify? {:acl collection-acl} request) - (let [deployment-parameter (-> body - u/strip-service-attrs - (crud/new-identifier resource-name) - (assoc :resourceURI resource-uri) - u/update-timestamps - (crud/add-acl request) - crud/validate) - response (db/add resource-name deployment-parameter {}) - value (:value body) - node-path (zdu/deployment-parameter-znode-path body)] - (uzk/create-all node-path :persistent? true) - (uzk/set-data node-path value) - response)) - (defn transiant-watch-fn [event-ch id name {:keys [event-type path :as zk-event]}] (when (= event-type :NodeDataChanged) (let [deployment-parameter (-> (db/retrieve id {}) @@ -153,7 +134,13 @@ (crud/validate) (db/edit request)) (when value - (uzk/set-data (zdu/deployment-parameter-znode-path merged) value)))) ;TODO what if znode not found + (uzk/set-data (zdu/deployment-parameter-znode-path merged) value) + (when + (and (= (:type merged) "deployment") + (= (:name merged) "state")) + (du/update-deployment-state (du/deployment-href-to-uuid (:deployment-href merged)) value))) + merged) + ) ;TODO what if znode not found (defmethod crud/edit resource-name [request] diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj index 8b82ba32d..aad7b0ebd 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj @@ -52,4 +52,7 @@ (apply zk/set-data *client* path data version options))) (defn exists [path & options] - (apply zk/exists *client* path options)) \ No newline at end of file + (apply zk/exists *client* path options)) + +(defn children [path & options] + (apply zk/children *client* path options)) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj index 375a32095..3ac67a9fa 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj @@ -5,7 +5,7 @@ [peridot.core :refer :all] [ring.util.codec :as rc] [com.sixsq.slipstream.ssclj.resources.deployment :refer :all] - [com.sixsq.slipstream.ssclj.resources.deployment-parameter :as rp] + [com.sixsq.slipstream.ssclj.resources.deployment-parameter :as dp] [com.sixsq.slipstream.ssclj.resources.lifecycle-test-utils :as t] [com.sixsq.slipstream.ssclj.middleware.authn-info-header :refer [authn-info-header]] [com.sixsq.slipstream.ssclj.app.routes :as routes] @@ -23,8 +23,10 @@ (defn ring-app [] (t/make-ring-app (t/concat-routes routes/final-routes))) +(def valid-entry-deployment-uuid "dfd34916-6ede-47f7-aaeb-a30ddecbba5c") + (def valid-entry - {:id (str resource-url "/dfd34916-6ede-47f7-aaeb-a30ddecbba5b") + {:id (str resource-url "/" valid-entry-deployment-uuid) :resourceURI resource-uri :module-resource-uri "module/examples/tutorials/service-testing/system/1940" :category "Deployment" @@ -69,21 +71,147 @@ (t/body->edn) (t/is-status 200))] - (is (not (uzk/exists (str zdu/znode-separator deployment-href)))) + (is (not (uzk/exists (str zdu/znode-separator deployment-href))))))) + +(deftest start-deployment + + (let [session-admin-json (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "super ADMIN USER ANON")) + session-admin-form (-> (session (ring-app)) + (content-type "application/x-www-form-urlencoded") + (header authn-info-header "super ADMIN USER ANON")) + session-user (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "jane USER ANON")) + session-anon (-> (session (ring-app)) + (content-type "application/json"))] + + ;; adding, retrieving and deleting entry as user should succeed + (let [deployment-href (-> session-user + (request base-uri + :request-method :post + :body (json/write-str valid-entry)) + (t/body->edn) + (t/is-status 201) + (t/location)) + abs-uri (str p/service-context (u/de-camelcase deployment-href)) + created-deployment (-> session-user + (request abs-uri) + (t/body->edn) + (t/is-status 200)) + start-uri (str p/service-context + (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) + started-deployment (-> session-user + (request start-uri) + (t/body->edn) + (t/is-status 200)) + ] + + (is (not (get-in created-deployment [:body :start-time]))) + (is (get-in started-deployment [:response :body :start-time])) + + (is (= "init" (get-in started-deployment [:response :body :state]))) + + (are [expected value] + (= expected value) + "init" (uzk/get-data (str zdu/znode-separator deployment-href "/state")) + "init" (uzk/get-data + (str zdu/znode-separator deployment-href "/" zdu/nodes-txt "/node2/1/" "vmstate")))))) + + +(deftest start-deployment + + (let [session-admin-json (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "super ADMIN USER ANON")) + session-admin-form (-> (session (ring-app)) + (content-type "application/x-www-form-urlencoded") + (header authn-info-header "super ADMIN USER ANON")) + session-user (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "jane USER ANON")) + session-anon (-> (session (ring-app)) + (content-type "application/json"))] + + ;; adding, retrieving and deleting entry as user should succeed + (let [deployment-href (-> session-user + (request base-uri + :request-method :post + :body (json/write-str valid-entry)) + (t/body->edn) + (t/is-status 201) + (t/location)) + abs-uri (str p/service-context (u/de-camelcase deployment-href)) + created-deployment (-> session-user + (request abs-uri) + (t/body->edn) + (t/is-status 200)) + start-uri (str p/service-context + (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) + started-deployment (-> session-user + (request start-uri) + (t/body->edn) + (t/is-status 200)) + ] + + (is (not (get-in created-deployment [:body :start-time]))) + (is (get-in started-deployment [:response :body :start-time])) - (let [start-uri (str p/service-context - (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) - started-deployment (-> session-user - (request start-uri) - (t/body->edn) - (t/is-status 200))] + (is (= "init" (get-in started-deployment [:response :body :state]))) - (is (not (get-in created-deployment [:body :start-time]))) - (is (get-in started-deployment [:response :body :start-time])) + (are [expected value] + (= expected value) + "init" (uzk/get-data (str zdu/znode-separator deployment-href "/state")) + "init" (uzk/get-data + (str zdu/znode-separator deployment-href "/" zdu/nodes-txt "/node2/1/" "vmstate")))))) +(deftest create-deployment-update-deployment-state + + (let [session-admin-json (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "super ADMIN USER ANON")) + session-user (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "jane USER ANON"))] + + ;; adding, retrieving and deleting entry as user should succeed + (let [deployment-href (-> session-user + (request base-uri + :request-method :post + :body (json/write-str valid-entry)) + (t/body->edn) + (t/is-status 201) + (t/location)) + abs-uri (str p/service-context (u/de-camelcase deployment-href)) + abs-uri-deployment-parameter-state (str p/service-context dp/resource-url "/" valid-entry-deployment-uuid "_state") + created-deployment (-> session-user + (request abs-uri) + (t/body->edn) + (t/is-status 200)) + start-uri (str p/service-context + (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) + started-deployment (-> session-user + (request start-uri) + (t/body->edn) + (t/is-status 200)) + update-deployment-parameter-state + (-> session-user + (request abs-uri-deployment-parameter-state :request-method :put + :body (json/write-str {:value "provisioning"})) + (t/body->edn) + (t/is-status 403)) + update-deployment-parameter-state + (-> session-admin-json + (request abs-uri-deployment-parameter-state :request-method :put + :body (json/write-str {:value "provisioning"})) + (t/body->edn) + (t/is-status 200)) + provisioning-deployment (-> session-user + (request start-uri) + (t/body->edn) + (t/is-status 200))] - (are [expected value] - (= expected value) - "init" (uzk/get-data (str zdu/znode-separator deployment-href "/state")) - "init" (uzk/get-data - (str zdu/znode-separator deployment-href "/" zdu/nodes-txt "/node2/1/" "vmstate"))))))) + (is (= "provisioning" (get-in provisioning-deployment [:response :body :state]))) + (is (= "provisioning" (uzk/get-data (str zdu/znode-separator deployment-href "/state")))) + ))) \ No newline at end of file diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj index 90830b7f0..4bd43e006 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj @@ -11,7 +11,8 @@ [com.sixsq.slipstream.ssclj.app.params :as p] [com.sixsq.slipstream.ssclj.resources.common.utils :as u] [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] - [com.sixsq.slipstream.ssclj.resources.zk.deployment.utils :as zdu])) + [com.sixsq.slipstream.ssclj.resources.zk.deployment.utils :as zdu] + [com.sixsq.slipstream.ssclj.resources.deployment.utils :as du])) (use-fixtures :each t/with-test-es-client-fixture) @@ -47,7 +48,7 @@ (->> {:params {:resource-name resource-url} :identity identity-admin :body valid-entry} - (add-impl) + (du/add-deployment-parameter-impl) (assoc {} :response)) (t/is-status 201) (t/location)) From 591feab106c77ec97202f3be78f8890c408c350c Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Wed, 6 Sep 2017 14:19:54 +0200 Subject: [PATCH 28/46] in lifecycle test clean all zk nodes after each test --- ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj | 3 +++ .../ssclj/resources/deployment_lifecycle_test.clj | 6 ++++-- .../slipstream/ssclj/resources/lifecycle_test_utils.clj | 6 ++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj index aad7b0ebd..f8d26fce4 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj @@ -56,3 +56,6 @@ (defn children [path & options] (apply zk/children *client* path options)) + +(defn delete-all [path & options] + (apply zk/delete-all *client* path options)) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj index 3ac67a9fa..80982fa48 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj @@ -14,12 +14,14 @@ [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] [com.sixsq.slipstream.ssclj.resources.zk.deployment.utils :as zdu])) -(use-fixtures :each t/with-test-es-client-fixture) - (use-fixtures :once t/setup-embedded-zk) +(use-fixtures :each (join-fixtures [t/with-test-es-client-fixture t/cleanup-all-zk-nodes])) + (def base-uri (str p/service-context resource-url)) + + (defn ring-app [] (t/make-ring-app (t/concat-routes routes/final-routes))) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj index b480f91ad..3a4e13322 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj @@ -227,3 +227,9 @@ (catch Exception e)) (.close server) )) + +(defn cleanup-all-zk-nodes [f] + (f) + (let [nodes (->> (uzk/children "/") + (remove #{"zookeeper"}))] + (doall (map #(uzk/delete-all (str "/" %)) nodes)))) From afb1b85a90a736313c5ce28bc74381dbce1ade83 Mon Sep 17 00:00:00 2001 From: Konstantin Skaburskas Date: Wed, 6 Sep 2017 16:09:15 +0200 Subject: [PATCH 29/46] FIXME: temporarily adding explicit dependency on clojure/tools.reader --- ssclj/jar/build.boot | 1 + 1 file changed, 1 insertion(+) diff --git a/ssclj/jar/build.boot b/ssclj/jar/build.boot index 366683cf0..1efb6f992 100644 --- a/ssclj/jar/build.boot +++ b/ssclj/jar/build.boot @@ -39,6 +39,7 @@ [metrics-clojure-graphite] [me.raynes/fs] [org.clojure/core.async :exclusions []] + [org.clojure/tools.reader "1.0.0-beta4"] [org.clojure/data.json] [org.clojure/java.classpath] [org.clojure/tools.cli] From d953909046c9f3d7f60cf0039aabb983abd7c3c5 Mon Sep 17 00:00:00 2001 From: Konstantin Skaburskas Date: Wed, 6 Sep 2017 16:14:06 +0200 Subject: [PATCH 30/46] removed unused requires --- .../jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj | 1 - .../sixsq/slipstream/ssclj/resources/deployment_parameter.clj | 1 - 2 files changed, 2 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj index 1ad00a1ff..c28c84ec9 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj @@ -1,6 +1,5 @@ (ns com.sixsq.slipstream.ssclj.resources.deployment (:require - [clojure.stacktrace :as st] [clojure.spec.alpha :as s] [com.sixsq.slipstream.ssclj.resources.spec.deployment] [com.sixsq.slipstream.ssclj.resources.common.std-crud :as std-crud] diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj index 6ee69b0de..bb9beb19c 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj @@ -15,7 +15,6 @@ [com.sixsq.slipstream.ssclj.util.log :as logu] [com.sixsq.slipstream.ssclj.util.sse :as sse] [clojure.core.async :as async] - [zookeeper :as zk] [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] [com.sixsq.slipstream.ssclj.resources.zk.deployment.utils :as zdu] [com.sixsq.slipstream.ssclj.resources.deployment.utils :as du] From cf9faf61b8846e67b9f2a33c46dab8f2cff2b024 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Wed, 6 Sep 2017 20:58:02 +0200 Subject: [PATCH 31/46] WIP update of state-complete for node instance have special behavior on deployment state --- .../slipstream/ssclj/resources/deployment.clj | 2 +- .../ssclj/resources/deployment/utils.clj | 64 ++++++++++++------- .../ssclj/resources/deployment_parameter.clj | 43 +++++++------ .../ssclj/resources/zk/deployment/utils.clj | 6 ++ .../sixsq/slipstream/ssclj/util/zookeeper.clj | 3 + .../deployment_parameter_lifecycle_test.clj | 38 ++++++++++- 6 files changed, 110 insertions(+), 46 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj index c28c84ec9..66129bcca 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj @@ -89,7 +89,7 @@ (defmethod crud/delete resource-name [request] - (delete-impl request)) + (delete-impl request)) ;TODO cleanup of deployment parameter and in zk should also be done (def query-impl (std-crud/query-fn resource-name collection-acl collection-uri resource-tag)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj index 768082526..85e7c85ac 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj @@ -13,6 +13,29 @@ [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] [clojure.string :as string])) + +(def ^:const deployment-resource-name "Deployment") + +(def ^:const deployment-resource-url (u/de-camelcase deployment-resource-name)) + +(def edit-deployment-impl (std-crud/edit-fn deployment-resource-name)) + +(defn deployment-href-to-uuid [href] (string/replace-first href #"^deployment/" "")) + +(defn update-deployment-attribut [deployment-uuid attribute-name value] + (try + (let [request {:params {:resource-name deployment-resource-url + :uuid deployment-uuid} + :identity (create-identity-map ["super" #{"ADMIN"}]) + :body {(keyword attribute-name) value}} + {:keys [status body]} (edit-deployment-impl request)] + (case status + 200 (log/info "udpated deployment attribute: " body) + (log/info "unexpected status code when udpating deployment resource:" status))) + (catch Exception e + (log/warn "error when updating deployment resource: " (str e) "\n" + (with-out-str (st/print-cause-trace e)))))) + (def ^:const deployment-parameter-resource-name "DeploymentParameter") (def ^:const deployment-parameter-resource-url (u/de-camelcase deployment-parameter-resource-name)) @@ -25,6 +48,16 @@ :type "ROLE" :right "MODIFY"}]}) +(def deployment-parameter-id-separator "_") + +(defn deployment-parameter-id + [{deployment-href :deployment-href node-name :node-name node-index :node-index name :name :as deployment-parameter}] + (let [deployment-uuid (deployment-href-to-uuid deployment-href)] + (cond + (and deployment-uuid node-name node-index) (string/join deployment-parameter-id-separator [deployment-uuid node-name node-index name]) + (and deployment-uuid node-name) (string/join deployment-parameter-id-separator [deployment-uuid node-name name]) + deployment-uuid (string/join deployment-parameter-id-separator [deployment-uuid name])))) + (defn add-deployment-parameter-impl [{:keys [body] :as request}] (a/can-modify? {:acl deployment-parameter-collection-acl} request) (let [deployment-parameter (-> body @@ -39,6 +72,9 @@ node-path (zdu/deployment-parameter-znode-path body)] (uzk/create-all node-path :persistent? true) (uzk/set-data node-path value) + (when (and (= "state-complete" (:name deployment-parameter)) + (= "node-instance" (:type deployment-parameter))) + (uzk/create-all (zdu/deployment-parameter-node-instance-complete-state-znode-path deployment-parameter))) response)) (defn create-parameter [deployment-parameter] @@ -64,10 +100,15 @@ :type "USER" :right "VIEW"}]}}) (doseq [n nodes] - () (let [node-name (name (key n)) multiplicity (read-string (get-in (val n) [:parameters :multiplicity :default-value] "1"))] (doseq [i (range 1 (inc multiplicity))] + (create-parameter {:deployment-href deployment-href :node-name node-name :node-index i :type "node-instance" + :name "state-complete" :value "" :acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal user + :type "USER" + :right "MODIFY"}]}}) (create-parameter {:deployment-href deployment-href :node-name node-name :node-index i :type "node-instance" :name "vmstate" :value "init" :acl {:owner {:principal "ADMIN" :type "ROLE"} @@ -75,24 +116,3 @@ :type "USER" :right "MODIFY"}]}})))))) -(def ^:const deployment-resource-name "Deployment") - -(def ^:const deployment-resource-url (u/de-camelcase deployment-resource-name)) - -(def edit-deployment-impl (std-crud/edit-fn deployment-resource-name)) - -(defn deployment-href-to-uuid [href] (string/replace-first href #"^deployment/" "")) - -(defn update-deployment-state [deployment-uuid state] - (try - (let [request {:params {:resource-name deployment-resource-url - :uuid deployment-uuid} - :identity (create-identity-map ["super" #{"ADMIN"}]) - :body {:state state}} - {:keys [status body]} (edit-deployment-impl request)] - (case status - 200 (log/info "udpated deployment state: " body) - (log/info "unexpected status code when udpating deployment resource:" status))) - (catch Exception e - (log/warn "error when updating deployment resource: " (str e) "\n" - (with-out-str (st/print-cause-trace e)))))) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj index bb9beb19c..f4878e909 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj @@ -52,19 +52,9 @@ ;; CRUD operations ;; -(def deployment-parameter-id-separator "_") - -(defn deployment-parameter-id - [{deployment-href :deployment-href node-name :node-name node-index :node-index name :name :as deployment-parameter}] - (let [deployment-uuid (du/deployment-href-to-uuid deployment-href)] - (cond - (and deployment-uuid node-name node-index) (string/join deployment-parameter-id-separator [deployment-uuid node-name node-index name]) - (and deployment-uuid node-name) (string/join deployment-parameter-id-separator [deployment-uuid node-name name]) - deployment-uuid (string/join deployment-parameter-id-separator [deployment-uuid name])))) - (defmethod crud/new-identifier resource-name [json resource-name] - (let [new-id (str resource-url "/" (deployment-parameter-id json))] + (let [new-id (str resource-url "/" (du/deployment-parameter-id json))] (assoc json :id new-id))) (defn add-value-deployment-parameter [deployment-parameter & {:keys [watcher]}] @@ -125,21 +115,34 @@ [{{uuid :uuid} :params body :body :as request}] (let [current (-> (str (u/de-camelcase resource-name) "/" uuid) (db/retrieve request) - (a/can-modify? request)) + (a/can-modify? request)) ;TODO we should not allow user to update type and some other properties of deployment parameter (use dissoc) merged (merge current body) - value (:value merged)] + value (:value merged) + deployment-href (:deployment-href merged)] (-> merged (u/update-timestamps) (crud/validate) (db/edit request)) (when value - (uzk/set-data (zdu/deployment-parameter-znode-path merged) value) - (when - (and (= (:type merged) "deployment") - (= (:name merged) "state")) - (du/update-deployment-state (du/deployment-href-to-uuid (:deployment-href merged)) value))) - merged) - ) ;TODO what if znode not found + ;TODO what if znode not found + (condp = (:type merged) + "deployment" (do + (uzk/set-data (zdu/deployment-parameter-znode-path merged) value) + (du/update-deployment-attribut + (du/deployment-href-to-uuid deployment-href) (:name merged) value)) + "node-instance" (condp = (:name merged) + "state-complete" (do + (uzk/set-data (zdu/deployment-parameter-znode-path merged) value) + (uzk/delete (zdu/deployment-parameter-node-instance-complete-state-znode-path merged)) + (let [children-in-state-count (count (uzk/children (zdu/deployment-parameter-znode-path {:deployment-href deployment-href :name "state"})))] + (when (= 0 children-in-state-count) + ;TODO function trigger next state for current deployment + (println "post with next state on run parameter state with next state value") + (println "create all nodes instances state-compete of next global state") + ))) + (uzk/set-data (zdu/deployment-parameter-znode-path merged) value) + ))) + merged)) (defmethod crud/edit resource-name [request] diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj index 1cc4e5504..54d8d10bc 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj @@ -16,6 +16,12 @@ deployment-href (string/join znode-separator [deployment-href name])) (str znode-separator))) +(defn deployment-parameter-node-instance-complete-state-znode-path + [{deployment-href :deployment-href node-name :node-name node-index :node-index name :name :as deployment-parameter}] + (let [node-instance-complete-state-znode-id (string/join "_" [node-name node-index name])] + (str znode-separator + (string/join znode-separator [deployment-href "state" node-instance-complete-state-znode-id])))) + ;(defn run-id-path [run-id]) ; (str runs-path "/" run-id)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj index f8d26fce4..aac9396eb 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj @@ -59,3 +59,6 @@ (defn delete-all [path & options] (apply zk/delete-all *client* path options)) + +(defn delete [path & options] + (apply zk/delete *client* path options)) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj index 4bd43e006..2052e1ed3 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj @@ -12,9 +12,10 @@ [com.sixsq.slipstream.ssclj.resources.common.utils :as u] [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] [com.sixsq.slipstream.ssclj.resources.zk.deployment.utils :as zdu] - [com.sixsq.slipstream.ssclj.resources.deployment.utils :as du])) + [com.sixsq.slipstream.ssclj.resources.deployment.utils :as du] + [zookeeper :as zk])) -(use-fixtures :each t/with-test-es-client-fixture) +(use-fixtures :each (join-fixtures [t/with-test-es-client-fixture t/cleanup-all-zk-nodes])) (use-fixtures :once t/setup-embedded-zk) @@ -41,7 +42,7 @@ (deftest create-deployment-parameter-xyz (let [deployment-href "deployment/abc34916-6ede-47f7-aaeb-a30ddecbba5b" - valid-entry {:deployment-href deployment-href :node-name "machine" :node-index 1 :type "node" + valid-entry {:deployment-href deployment-href :node-name "machine" :node-index 1 :type "node-instance" :name "xyz" :value "XYZ" :acl resource-acl-jane} znode-path (zdu/deployment-parameter-znode-path valid-entry) deployment-parameter-id (-> @@ -76,3 +77,34 @@ (is (not (= "newvalue-albert" (uzk/get-data znode-path))) "deployment parameter can be updated"))) +(deftest deployment-parameter-state-complete + (let [deployment-href "deployment/abc34916-6ede-47f7-aaeb-a30ddecbba5b" + valid-entry {:deployment-href deployment-href :node-name "machine" :node-index 1 :type "node-instance" + :name "state-complete" :value "executing" :acl resource-acl-jane} + znode-path (zdu/deployment-parameter-znode-path valid-entry) + deployment-parameter-id (-> + (->> {:params {:resource-name resource-url} + :identity identity-admin + :body valid-entry} + (du/add-deployment-parameter-impl) + (assoc {} :response)) + (t/is-status 201) + (t/location)) + abs-uri (str p/service-context (u/de-camelcase deployment-parameter-id)) + created-deployment-parameter (-> session-user-jane + (request abs-uri) + (t/body->edn) + (t/is-status 200))] + (is (uzk/exists "/deployment/abc34916-6ede-47f7-aaeb-a30ddecbba5b/state/machine_1_state-complete")) + + (is (= "executing" (uzk/get-data znode-path))) + + (-> session-user-jane + (request abs-uri :request-method :put + :body (json/write-str {:value "running"})) + (t/body->edn) + (t/is-status 200)) + + (is (not (uzk/exists "/deployment/abc34916-6ede-47f7-aaeb-a30ddecbba5b/state/machine_1_state-complete"))))) + + From bbf5162f928ec38012a65b2406b851ce7a719b0e Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Fri, 8 Sep 2017 20:04:30 +0200 Subject: [PATCH 32/46] WIP for lock and deployment state move --- .../slipstream/ssclj/resources/deployment.clj | 5 +- .../{zk => }/deployment/state_machine.clj | 6 + .../ssclj/resources/deployment/utils.clj | 68 ++++++++++- .../ssclj/resources/deployment_parameter.clj | 83 ++++--------- .../ssclj/resources/zk/deployment/utils.clj | 110 ++++++++++-------- .../resources/deployment_lifecycle_test.clj | 55 +-------- .../deployment_parameter_lifecycle_test.clj | 12 +- 7 files changed, 168 insertions(+), 171 deletions(-) rename ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/{zk => }/deployment/state_machine.clj (94%) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj index 66129bcca..849d0929b 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj @@ -134,9 +134,8 @@ deployment (-> current (add-start-time) (u/update-timestamps) - (crud/validate) - (db/edit request))] + (crud/validate))] (du/create-parameters identity current) - deployment) + (db/edit deployment request)) (catch ExceptionInfo ei (ex-data ei)))) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/state_machine.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/state_machine.clj similarity index 94% rename from ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/state_machine.clj rename to ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/state_machine.clj index b1c0614a6..1fbb998f0 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/state_machine.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/state_machine.clj @@ -30,3 +30,9 @@ "ready" ["provisioning" ] "finalyzing" ["terminated"] "terminated" []}) + + +(defn get-next-state [current-state] + (-> current-state + (get valid-transitions) + first)) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj index 85e7c85ac..d0f66717d 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj @@ -10,6 +10,7 @@ [com.sixsq.slipstream.ssclj.resources.common.std-crud :as std-crud] [com.sixsq.slipstream.ssclj.middleware.authn-info-header :refer [create-identity-map]] [com.sixsq.slipstream.ssclj.resources.zk.deployment.utils :as zdu] + [com.sixsq.slipstream.ssclj.resources.zk.deployment.state-machine :as dsm] [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] [clojure.string :as string])) @@ -25,7 +26,7 @@ (defn update-deployment-attribut [deployment-uuid attribute-name value] (try (let [request {:params {:resource-name deployment-resource-url - :uuid deployment-uuid} + :uuid deployment-uuid} :identity (create-identity-map ["super" #{"ADMIN"}]) :body {(keyword attribute-name) value}} {:keys [status body]} (edit-deployment-impl request)] @@ -54,7 +55,8 @@ [{deployment-href :deployment-href node-name :node-name node-index :node-index name :name :as deployment-parameter}] (let [deployment-uuid (deployment-href-to-uuid deployment-href)] (cond - (and deployment-uuid node-name node-index) (string/join deployment-parameter-id-separator [deployment-uuid node-name node-index name]) + (and deployment-uuid node-name node-index) (string/join deployment-parameter-id-separator + [deployment-uuid node-name node-index name]) (and deployment-uuid node-name) (string/join deployment-parameter-id-separator [deployment-uuid node-name name]) deployment-uuid (string/join deployment-parameter-id-separator [deployment-uuid name])))) @@ -67,15 +69,69 @@ u/update-timestamps (crud/add-acl request) crud/validate) - response (db/add deployment-parameter-resource-name deployment-parameter {}) value (:value body) - node-path (zdu/deployment-parameter-znode-path body)] + node-path (zdu/deployment-parameter-path body)] (uzk/create-all node-path :persistent? true) (uzk/set-data node-path value) (when (and (= "state-complete" (:name deployment-parameter)) (= "node-instance" (:type deployment-parameter))) - (uzk/create-all (zdu/deployment-parameter-node-instance-complete-state-znode-path deployment-parameter))) - response)) + (uzk/create-all + (zdu/deployment-parameter-node-instance-complete-state-path deployment-parameter) :persistent? true)) + (db/add deployment-parameter-resource-name deployment-parameter {}))) + +(defn edit-deployment-parameter-impl + [{{uuid :uuid} :params body :body :as request}] + (let [current (-> (str deployment-parameter-resource-url "/" uuid) + (db/retrieve request) + (a/can-modify? request)) ;TODO we should not allow user to update type and some other properties of deployment parameter (use dissoc) + merged (merge current body) + value (:value merged) + deployment-href (:deployment-href merged) + deployment-parameter (-> merged + (u/update-timestamps) + (crud/validate))] + (when value + (condp = (:type merged) + "deployment" (do + (zdu/check-deployment-lock-and-throw! deployment-href) + (zdu/lock-deployment deployment-href) + (uzk/set-data (zdu/deployment-parameter-path merged) value) + (update-deployment-attribut + (deployment-href-to-uuid deployment-href) (:name merged) value) + (zdu/unlock-deployment deployment-href)) + "node-instance" (condp = (:name merged) + "state-complete" (do + (zdu/check-deployment-lock-and-throw! deployment-href) + (zdu/check-same-state-and-throw! deployment-href value) + (zdu/lock-deployment deployment-href) + (zdu/complete-node-instance-state merged) + (when-not (uzk/children + (zdu/deployment-state-path deployment-href)) + ;TODO function trigger next state for current deployment + (println "post with next state on run parameter state with next state value") + (println "create all nodes instances state-complete of next global state") + #_(update-deployment-attribut ;TODO this will create a deadlock, I should update directly ES db + (deployment-href-to-uuid deployment-href) (:name "state") + (dsm/get-next-state value)) + (zdu/unlock-deployment deployment-href) + )) + (uzk/set-data (zdu/deployment-parameter-path merged) value) + ))) + (db/edit deployment-parameter request))) + +(defn update-parameter [deployment-parameter] + (try + (let [request {:params {:resource-name deployment-parameter-resource-url + :uuid (deployment-href-to-uuid (:deployment-href deployment-parameter))} + :identity (create-identity-map ["super" #{"ADMIN"}]) + :body deployment-parameter} + {:keys [status body]} (edit-deployment-parameter-impl request)] + (case status + 200 (log/info "updated deployment-parameter: " body) + (log/info "unexpected status code when updating deployment-parameter resource:" status))) + (catch Exception e + (log/warn "error when updating deployment-parameter resource: " (str e) "\n" + (with-out-str (st/print-cause-trace e)))))) (defn create-parameter [deployment-parameter] (try diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj index f4878e909..c91ea6bbe 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj @@ -57,32 +57,23 @@ (let [new-id (str resource-url "/" (du/deployment-parameter-id json))] (assoc json :id new-id))) -(defn add-value-deployment-parameter [deployment-parameter & {:keys [watcher]}] - (try - (let [value (if watcher - (uzk/get-data (zdu/deployment-parameter-znode-path deployment-parameter) :watcher watcher) - (uzk/get-data (zdu/deployment-parameter-znode-path deployment-parameter)))] - (assoc deployment-parameter :value value)) - (catch ExceptionInfo ei ;TODO what if data not found - (ex-data ei)))) - -(defn transiant-watch-fn [event-ch id name {:keys [event-type path :as zk-event]}] - (when (= event-type :NodeDataChanged) - (let [deployment-parameter (-> (db/retrieve id {}) - (add-value-deployment-parameter))] - (sse/send-event id name deployment-parameter event-ch) - (async/close! event-ch)))) - -(defn persistent-watch-fn [event-ch id name {:keys [event-type path :as zk-event]}] - (when (= event-type :NodeDataChanged) - (let [deployment-parameter (-> (db/retrieve id {}) - (add-value-deployment-parameter :watcher (partial persistent-watch-fn event-ch id name)))] - (sse/send-event id name deployment-parameter event-ch)))) +(defn deployment-parameter-watch-fn [is-transiant] + (fn [event-ch id name {:keys [event-type path :as zk-event]}] + (when (= event-type :NodeDataChanged) + (let [deployment-parameter (db/retrieve id {}) + value (if is-transiant + (zdu/get-deployment-parameter-value deployment-parameter) + (zdu/get-deployment-parameter-value + deployment-parameter :watcher + (partial (deployment-parameter-watch-fn is-transiant) event-ch id name))) + deployment-parameter (assoc deployment-parameter :value value)] + (sse/send-event id name deployment-parameter event-ch) + (when is-transiant (async/close! event-ch)))))) (defn send-event-and-set-watcher [event-ch watch-fn {id :id name :name :as deployment-parameter}] - (let [deployment-parameter (-> deployment-parameter - (add-value-deployment-parameter :watcher (partial watch-fn event-ch id name)))] + (let [value (zdu/get-deployment-parameter-value deployment-parameter :watcher (partial watch-fn event-ch id name)) + deployment-parameter (assoc deployment-parameter :value value)] (sse/send-event id name deployment-parameter event-ch))) (defn retrieve-deployment-parameter @@ -99,8 +90,8 @@ (sse/event-channel-handler (fn [request response raise event-ch] (let [{id :id name :name :as deployment-parameter} (retrieve-deployment-parameter request) - node-path (zdu/deployment-parameter-znode-path deployment-parameter)] - (send-event-and-set-watcher event-ch transiant-watch-fn deployment-parameter))) + node-path (zdu/deployment-parameter-path deployment-parameter)] + (send-event-and-set-watcher event-ch (deployment-parameter-watch-fn true) deployment-parameter))) {:on-client-disconnect #(log/debug "sse/on-client-disconnect: " %)})) (def retrieve-json-impl (std-crud/retrieve-fn resource-name)) @@ -111,42 +102,9 @@ "text/event-stream" retrieve-sse-impl retrieve-json-impl)) -(defn edit-impl - [{{uuid :uuid} :params body :body :as request}] - (let [current (-> (str (u/de-camelcase resource-name) "/" uuid) - (db/retrieve request) - (a/can-modify? request)) ;TODO we should not allow user to update type and some other properties of deployment parameter (use dissoc) - merged (merge current body) - value (:value merged) - deployment-href (:deployment-href merged)] - (-> merged - (u/update-timestamps) - (crud/validate) - (db/edit request)) - (when value - ;TODO what if znode not found - (condp = (:type merged) - "deployment" (do - (uzk/set-data (zdu/deployment-parameter-znode-path merged) value) - (du/update-deployment-attribut - (du/deployment-href-to-uuid deployment-href) (:name merged) value)) - "node-instance" (condp = (:name merged) - "state-complete" (do - (uzk/set-data (zdu/deployment-parameter-znode-path merged) value) - (uzk/delete (zdu/deployment-parameter-node-instance-complete-state-znode-path merged)) - (let [children-in-state-count (count (uzk/children (zdu/deployment-parameter-znode-path {:deployment-href deployment-href :name "state"})))] - (when (= 0 children-in-state-count) - ;TODO function trigger next state for current deployment - (println "post with next state on run parameter state with next state value") - (println "create all nodes instances state-compete of next global state") - ))) - (uzk/set-data (zdu/deployment-parameter-znode-path merged) value) - ))) - merged)) - (defmethod crud/edit resource-name [request] - (edit-impl request)) + (du/edit-deployment-parameter-impl request)) (def delete-impl (std-crud/delete-fn resource-name)) @@ -159,8 +117,11 @@ (fn [request response raise event-ch] (a/can-view? {:acl collection-acl} request) (let [options (select-keys request [:identity :query-params :cimi-params :user-name :user-roles]) - [count-before-pagination entries] (db/query resource-name options)] - (doall (map (partial send-event-and-set-watcher event-ch persistent-watch-fn) entries)))) + [count-before-pagination entries] (db/query resource-name options) + transient-deployment-parameter-watch (deployment-parameter-watch-fn false) + send-event-and-set-watcher-partial (partial send-event-and-set-watcher + event-ch transient-deployment-parameter-watch)] + (doall (map send-event-and-set-watcher-partial entries)))) {:on-client-disconnect #(log/debug "sse/on-client-disconnect: " %) :heartbeat-delay 10})) (def query-json-impl (std-crud/query-fn resource-name collection-acl collection-uri resource-tag)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj index 54d8d10bc..e386105e2 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj @@ -1,58 +1,74 @@ (ns com.sixsq.slipstream.ssclj.resources.zk.deployment.utils (:require [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] - [zookeeper :as zk] [clojure.string :as string])) -(def znode-separator "/") +(def separator "/") +(def nodes-name "nodes") +(def lock-name "lock") -(def nodes-txt "nodes") +(defn deployment-path [deployment-href] + (str separator deployment-href)) -(defn deployment-parameter-znode-path +(defn lock-deployment-path [deployment-href] + (str (deployment-path deployment-href) separator lock-name)) + +(defn deployment-parameter-path [{deployment-href :deployment-href node-name :node-name node-index :node-index name :name :as deployment-parameter}] (->> (cond - (and deployment-href node-name node-index) - (string/join znode-separator [deployment-href nodes-txt node-name node-index name]) - (and deployment-href node-name) (string/join znode-separator [deployment-href nodes-txt node-name name]) - deployment-href (string/join znode-separator [deployment-href name])) - (str znode-separator))) + (and node-name node-index) + (string/join separator [nodes-name node-name node-index name]) + (and deployment-href node-name) + (string/join separator [nodes-name node-name name]) + deployment-href name) + (str (deployment-path deployment-href) separator))) -(defn deployment-parameter-node-instance-complete-state-znode-path +(defn deployment-parameter-node-instance-complete-state-path [{deployment-href :deployment-href node-name :node-name node-index :node-index name :name :as deployment-parameter}] (let [node-instance-complete-state-znode-id (string/join "_" [node-name node-index name])] - (str znode-separator - (string/join znode-separator [deployment-href "state" node-instance-complete-state-znode-id])))) - -;(defn run-id-path [run-id]) - -; (str runs-path "/" run-id)) -; -;(defn nodes-path [run-id] -; (str (run-id-path run-id) "/nodes")) -; -;(defn node-path -; [run-id node-name] -; (str (nodes-path run-id) "/" node-name)) -; -;(defn indexed-node-path [run-id node-name node-index] -; (str (node-path run-id node-name) "/" node-index)) -; -;(defn create-run [run-id] -; (uzk/create (run-id-path run-id) :persistent? true)) - - - -#_(defn create-zk-run [{run-id :id nodes :nodes :as run}] - (doseq [n nodes] - (zk/create-all uzk/*client* (node-path run-id (key n)) :persistent? true) - (let [{:keys [params multiplicity mapping]} (val n)] - (doseq [i (range 1 (inc multiplicity))] - (zk/create-all client (rzu/params-znode-path run-id (key n) i) :persistent? true) - (doseq [p params] - (if-let [default (-> p val :default)] - (zk/create client (rzu/param-znode-path run-id (key n) i (key p)) - :data (zdata/to-bytes default) - :persistent? true) - (zk/create client (rzu/param-znode-path run-id (key n) i (key p)) - :persistent? true)))))) - (rsm/create client run-id module params) - ) \ No newline at end of file + (str separator + (string/join separator [deployment-href "state" node-instance-complete-state-znode-id])))) + +(defn lock-deployment + "Create a lock for the deployment. This should be used each time multi-operations on zookeeper are needed to complete + a request on deployment or deployment-parameter HTTP resource." + [deployment-href] + (uzk/create (lock-deployment-path deployment-href) :persistent? false)) + +(defn unlock-deployment + "Release the lock for the specified deployment." + [deployment-href] + (uzk/delete (lock-deployment-path deployment-href))) + +(defn is-deployment-locked? + "Check if the deployment is locked." + [deployment-href] + (not (nil? (uzk/exists (lock-deployment-path deployment-href))))) + +(defn check-deployment-lock-and-throw! + "Throw if deployment is locked." + [deployment-href] + (when (is-deployment-locked? deployment-href) ; TODO throw well know error code + (throw (Exception. "Deployment is locked, come back later!")))) + +(defn get-deployment-parameter-value [deployment-parameter & {:keys [watcher]}] + (if watcher + (uzk/get-data (deployment-parameter-path deployment-parameter) :watcher watcher) + (uzk/get-data (deployment-parameter-path deployment-parameter)))) + +(defn deployment-state-path [deployment-href] + (deployment-parameter-path {:deployment-href deployment-href :name "state"})) + +(defn get-deployment-state [deployment-href] + (uzk/get-data (deployment-state-path deployment-href))) + +(defn check-same-state-and-throw! + [deployment-href state] + (let [current-state (get-deployment-state deployment-href)] + (when-not (= state current-state) + (throw (Exception. + (str "State machine (complete-state = " current-state + ") in different state from deployment state = " state "!")))))) + +(defn complete-node-instance-state [{state :value :as deployment-parameter}] + (uzk/delete (deployment-parameter-node-instance-complete-state-path deployment-parameter)) + (uzk/set-data (deployment-parameter-path deployment-parameter) state)) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj index 80982fa48..26385a18b 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj @@ -73,53 +73,7 @@ (t/body->edn) (t/is-status 200))] - (is (not (uzk/exists (str zdu/znode-separator deployment-href))))))) - -(deftest start-deployment - - (let [session-admin-json (-> (session (ring-app)) - (content-type "application/json") - (header authn-info-header "super ADMIN USER ANON")) - session-admin-form (-> (session (ring-app)) - (content-type "application/x-www-form-urlencoded") - (header authn-info-header "super ADMIN USER ANON")) - session-user (-> (session (ring-app)) - (content-type "application/json") - (header authn-info-header "jane USER ANON")) - session-anon (-> (session (ring-app)) - (content-type "application/json"))] - - ;; adding, retrieving and deleting entry as user should succeed - (let [deployment-href (-> session-user - (request base-uri - :request-method :post - :body (json/write-str valid-entry)) - (t/body->edn) - (t/is-status 201) - (t/location)) - abs-uri (str p/service-context (u/de-camelcase deployment-href)) - created-deployment (-> session-user - (request abs-uri) - (t/body->edn) - (t/is-status 200)) - start-uri (str p/service-context - (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) - started-deployment (-> session-user - (request start-uri) - (t/body->edn) - (t/is-status 200)) - ] - - (is (not (get-in created-deployment [:body :start-time]))) - (is (get-in started-deployment [:response :body :start-time])) - - (is (= "init" (get-in started-deployment [:response :body :state]))) - - (are [expected value] - (= expected value) - "init" (uzk/get-data (str zdu/znode-separator deployment-href "/state")) - "init" (uzk/get-data - (str zdu/znode-separator deployment-href "/" zdu/nodes-txt "/node2/1/" "vmstate")))))) + (is (not (uzk/exists (str zdu/separator deployment-href))))))) (deftest start-deployment @@ -164,9 +118,10 @@ (are [expected value] (= expected value) - "init" (uzk/get-data (str zdu/znode-separator deployment-href "/state")) + "init" (uzk/get-data (str zdu/separator deployment-href "/state")) "init" (uzk/get-data - (str zdu/znode-separator deployment-href "/" zdu/nodes-txt "/node2/1/" "vmstate")))))) + (str zdu/separator deployment-href "/" zdu/nodes-name "/node2/1/" "vmstate")))))) + (deftest create-deployment-update-deployment-state (let [session-admin-json (-> (session (ring-app)) @@ -215,5 +170,5 @@ (is (= "provisioning" (get-in provisioning-deployment [:response :body :state]))) - (is (= "provisioning" (uzk/get-data (str zdu/znode-separator deployment-href "/state")))) + (is (= "provisioning" (uzk/get-data (str zdu/separator deployment-href "/state")))) ))) \ No newline at end of file diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj index 2052e1ed3..3093d7eec 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj @@ -44,7 +44,7 @@ (let [deployment-href "deployment/abc34916-6ede-47f7-aaeb-a30ddecbba5b" valid-entry {:deployment-href deployment-href :node-name "machine" :node-index 1 :type "node-instance" :name "xyz" :value "XYZ" :acl resource-acl-jane} - znode-path (zdu/deployment-parameter-znode-path valid-entry) + znode-path (zdu/deployment-parameter-path valid-entry) deployment-parameter-id (-> (->> {:params {:resource-name resource-url} :identity identity-admin @@ -77,11 +77,13 @@ (is (not (= "newvalue-albert" (uzk/get-data znode-path))) "deployment parameter can be updated"))) -(deftest deployment-parameter-state-complete + +; TODO move deployment parameter with special behavior to deployment lifecycle test +#_(deftest deployment-parameter-state-complete (let [deployment-href "deployment/abc34916-6ede-47f7-aaeb-a30ddecbba5b" valid-entry {:deployment-href deployment-href :node-name "machine" :node-index 1 :type "node-instance" :name "state-complete" :value "executing" :acl resource-acl-jane} - znode-path (zdu/deployment-parameter-znode-path valid-entry) + znode-path (zdu/deployment-parameter-path valid-entry) deployment-parameter-id (-> (->> {:params {:resource-name resource-url} :identity identity-admin @@ -99,9 +101,11 @@ (is (= "executing" (uzk/get-data znode-path))) + + (-> session-user-jane (request abs-uri :request-method :put - :body (json/write-str {:value "running"})) + :body (json/write-str {:value ""})) (t/body->edn) (t/is-status 200)) From f0c8ffd31c270347d8cbe6e4c07cc2b2621a04c5 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Mon, 11 Sep 2017 09:27:08 +0200 Subject: [PATCH 33/46] next-state working and idempotent --- .../slipstream/ssclj/resources/deployment.clj | 4 +- .../resources/deployment/state_machine.clj | 6 +- .../ssclj/resources/deployment/utils.clj | 154 ++++++++++++------ .../ssclj/resources/deployment_parameter.clj | 2 +- .../ssclj/resources/zk/deployment/utils.clj | 12 +- .../deployment/state_machine_test.clj | 6 + .../resources/deployment_lifecycle_test.clj | 107 +++++++++++- .../deployment_parameter_lifecycle_test.clj | 27 +-- 8 files changed, 248 insertions(+), 70 deletions(-) create mode 100644 ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment/state_machine_test.clj diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj index 849d0929b..27227fb9c 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj @@ -8,7 +8,7 @@ [com.sixsq.slipstream.ssclj.resources.common.utils :as u] [com.sixsq.slipstream.ssclj.resources.deployment-parameter :as dp] [com.sixsq.slipstream.ssclj.middleware.authn-info-header :refer [create-identity-map]] - [com.sixsq.slipstream.ssclj.resources.zk.deployment.state-machine :as zdsm] + [com.sixsq.slipstream.ssclj.resources.deployment.state-machine :as dsm] [com.sixsq.slipstream.ssclj.resources.deployment.utils :as du] [com.sixsq.slipstream.auth.acl :as a] [superstring.core :as str] @@ -67,7 +67,7 @@ (assoc :resourceURI resource-uri) u/update-timestamps (crud/add-acl request) - (assoc :state zdsm/initial-state)) + (assoc :state dsm/initial-state)) response (db/add resource-name (crud/validate new-deployment) {})] response)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/state_machine.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/state_machine.clj index 1fbb998f0..2d5921e1f 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/state_machine.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/state_machine.clj @@ -1,4 +1,4 @@ -(ns com.sixsq.slipstream.ssclj.resources.zk.deployment.state-machine +(ns com.sixsq.slipstream.ssclj.resources.deployment.state-machine "This namespace uses ZooKeeper to create a distributed system to host the state of a run. Each VM is represented by an index node under its corresponding node. As each VM reports its current state completed, the corresponding index znode (i.e. ZooKeeper node) is removed from the structure. When no node remains, it means all VMs have @@ -27,12 +27,12 @@ "provisioning" ["executing"] "executing" ["sending report"] "sending report" ["ready"] - "ready" ["provisioning" ] + "ready" ["provisioning"] "finalyzing" ["terminated"] "terminated" []}) (defn get-next-state [current-state] - (-> current-state + (->> current-state (get valid-transitions) first)) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj index d0f66717d..3ee59f855 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj @@ -10,9 +10,10 @@ [com.sixsq.slipstream.ssclj.resources.common.std-crud :as std-crud] [com.sixsq.slipstream.ssclj.middleware.authn-info-header :refer [create-identity-map]] [com.sixsq.slipstream.ssclj.resources.zk.deployment.utils :as zdu] - [com.sixsq.slipstream.ssclj.resources.zk.deployment.state-machine :as dsm] + [com.sixsq.slipstream.ssclj.resources.deployment.state-machine :as dsm] [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] - [clojure.string :as string])) + [clojure.string :as string]) + (:import (clojure.lang ExceptionInfo))) (def ^:const deployment-resource-name "Deployment") @@ -21,21 +22,47 @@ (def edit-deployment-impl (std-crud/edit-fn deployment-resource-name)) +(defn edit-deployment + [deployment-href deployment-body] + (try + (let [current (db/retrieve deployment-href {}) + merged (merge current deployment-body)] + (-> merged + (u/update-timestamps) + (crud/validate) + (db/edit {}) + :body)) + (catch ExceptionInfo ei + (ex-data ei)))) + +(defn edit-deployment-parameter + [deployment-parameter-href deployment-parameter-body] + (try + (let [current (db/retrieve deployment-parameter-href {}) + merged (merge current deployment-parameter-body)] + (-> merged + (u/update-timestamps) + (crud/validate) + (db/edit {}) + :body)) + (catch ExceptionInfo ei + (ex-data ei)))) + (defn deployment-href-to-uuid [href] (string/replace-first href #"^deployment/" "")) -(defn update-deployment-attribut [deployment-uuid attribute-name value] - (try - (let [request {:params {:resource-name deployment-resource-url - :uuid deployment-uuid} - :identity (create-identity-map ["super" #{"ADMIN"}]) - :body {(keyword attribute-name) value}} - {:keys [status body]} (edit-deployment-impl request)] - (case status - 200 (log/info "udpated deployment attribute: " body) - (log/info "unexpected status code when udpating deployment resource:" status))) - (catch Exception e - (log/warn "error when updating deployment resource: " (str e) "\n" - (with-out-str (st/print-cause-trace e)))))) +;(defn update-deployment-attribut [deployment-uuid attribute-name value] +; (try +; (let [request {:params {:resource-name deployment-resource-url +; :uuid deployment-uuid} +; :identity (create-identity-map ["super" #{"ADMIN"}]) +; :body {(keyword attribute-name) value}} +; {:keys [status body]} (edit-deployment-impl request)] +; (case status +; 200 (log/info "udpated deployment attribute: " body) +; (log/info "unexpected status code when udpating deployment resource:" status))) +; (catch Exception e +; (log/warn "error when updating deployment resource: " (str e) "\n" +; (with-out-str (st/print-cause-trace e)))))) (def ^:const deployment-parameter-resource-name "DeploymentParameter") @@ -51,16 +78,17 @@ (def deployment-parameter-id-separator "_") -(defn deployment-parameter-id +(defn deployment-parameter-href [{deployment-href :deployment-href node-name :node-name node-index :node-index name :name :as deployment-parameter}] - (let [deployment-uuid (deployment-href-to-uuid deployment-href)] - (cond - (and deployment-uuid node-name node-index) (string/join deployment-parameter-id-separator - [deployment-uuid node-name node-index name]) - (and deployment-uuid node-name) (string/join deployment-parameter-id-separator [deployment-uuid node-name name]) - deployment-uuid (string/join deployment-parameter-id-separator [deployment-uuid name])))) - -(defn add-deployment-parameter-impl [{:keys [body] :as request}] + (let [deployment-uuid (deployment-href-to-uuid deployment-href) + deployment-parameter-element (cond + (and deployment-uuid node-name node-index) [deployment-uuid node-name node-index name] + (and deployment-uuid node-name) [deployment-uuid node-name name] + deployment-uuid [deployment-uuid name]) + deployment-parameter-path (string/join deployment-parameter-id-separator deployment-parameter-element)] + (string/join "/" [deployment-parameter-resource-url deployment-parameter-path]))) + +#_(defn add-deployment-parameter-impl [{:keys [body] :as request}] (a/can-modify? {:acl deployment-parameter-collection-acl} request) (let [deployment-parameter (-> body u/strip-service-attrs @@ -79,13 +107,34 @@ (zdu/deployment-parameter-node-instance-complete-state-path deployment-parameter) :persistent? true)) (db/add deployment-parameter-resource-name deployment-parameter {}))) +(defn create-deployment-parameter [deployment-parameter] + (let [deployment-parameter (-> deployment-parameter + u/strip-service-attrs + (crud/new-identifier deployment-parameter-resource-name) + (assoc :resourceURI deployment-parameter-resource-uri) + u/update-timestamps + (crud/add-acl {}) + crud/validate) + value (:value deployment-parameter) + node-path (zdu/deployment-parameter-path deployment-parameter)] + (uzk/create-all node-path :persistent? true) + (uzk/set-data node-path value) + (when (and (= "state-complete" (:name deployment-parameter)) + (= "node-instance" (:type deployment-parameter))) + (uzk/create-all + (zdu/deployment-parameter-node-instance-complete-state-path deployment-parameter) :persistent? true)) + (-> (db/add deployment-parameter-resource-name deployment-parameter {}) + :body))) + (defn edit-deployment-parameter-impl [{{uuid :uuid} :params body :body :as request}] (let [current (-> (str deployment-parameter-resource-url "/" uuid) (db/retrieve request) (a/can-modify? request)) ;TODO we should not allow user to update type and some other properties of deployment parameter (use dissoc) - merged (merge current body) + merged (->> (dissoc body :type :deployment-href :node-name :node-index) + (merge current)) value (:value merged) + parameter-name (:name merged) deployment-href (:deployment-href merged) deployment-parameter (-> merged (u/update-timestamps) @@ -96,25 +145,35 @@ (zdu/check-deployment-lock-and-throw! deployment-href) (zdu/lock-deployment deployment-href) (uzk/set-data (zdu/deployment-parameter-path merged) value) - (update-deployment-attribut - (deployment-href-to-uuid deployment-href) (:name merged) value) + (edit-deployment deployment-href {(keyword parameter-name) value}) (zdu/unlock-deployment deployment-href)) "node-instance" (condp = (:name merged) - "state-complete" (do - (zdu/check-deployment-lock-and-throw! deployment-href) - (zdu/check-same-state-and-throw! deployment-href value) - (zdu/lock-deployment deployment-href) - (zdu/complete-node-instance-state merged) - (when-not (uzk/children - (zdu/deployment-state-path deployment-href)) - ;TODO function trigger next state for current deployment - (println "post with next state on run parameter state with next state value") - (println "create all nodes instances state-complete of next global state") - #_(update-deployment-attribut ;TODO this will create a deadlock, I should update directly ES db - (deployment-href-to-uuid deployment-href) (:name "state") - (dsm/get-next-state value)) - (zdu/unlock-deployment deployment-href) - )) + "state-complete" + (do + (zdu/check-deployment-lock-and-throw! deployment-href) + (zdu/check-same-state-and-throw! deployment-href value) + (zdu/lock-deployment deployment-href) + (zdu/complete-node-instance-state merged) + (when-not (uzk/children + (zdu/deployment-state-path deployment-href)) + ;TODO function trigger next state for current deployment + (let [next-state (dsm/get-next-state value) ;TODO final state what should be done? + deployment (edit-deployment deployment-href {:state next-state}) + deployment-parameter-state {:deployment-href deployment-href :name "state" + :value next-state} + deployment-parameter-state-id (deployment-parameter-href deployment-parameter-state) + deployment-parameter-state (edit-deployment-parameter deployment-parameter-state-id + deployment-parameter-state)] + (uzk/set-data (zdu/deployment-state-path deployment-href) next-state) + (doseq [n (:nodes deployment)] + (let [node-name (name (key n)) + multiplicity (read-string (get-in (val n) [:parameters :multiplicity :default-value] "1"))] + (doseq [i (range 1 (inc multiplicity))] + (uzk/create-all + (zdu/deployment-parameter-node-instance-complete-state-path + deployment-href node-name i "state-complete") :persistent? true) + ))))) + (zdu/unlock-deployment deployment-href)) (uzk/set-data (zdu/deployment-parameter-path merged) value) ))) (db/edit deployment-parameter request))) @@ -133,7 +192,7 @@ (log/warn "error when updating deployment-parameter resource: " (str e) "\n" (with-out-str (st/print-cause-trace e)))))) -(defn create-parameter [deployment-parameter] +#_(defn create-parameter [deployment-parameter] (try (let [request {:params {:resource-name deployment-parameter-resource-url} :identity (create-identity-map ["super" #{"ADMIN"}]) @@ -148,7 +207,7 @@ (defn create-parameters [identity {nodes :nodes deployment-href :id state :state}] (let [user (:current identity)] - (create-parameter + (create-deployment-parameter #_create-parameter {:deployment-href deployment-href :name "state" :value state :type "deployment" :acl {:owner {:principal "ADMIN" :type "ROLE"} @@ -159,16 +218,15 @@ (let [node-name (name (key n)) multiplicity (read-string (get-in (val n) [:parameters :multiplicity :default-value] "1"))] (doseq [i (range 1 (inc multiplicity))] - (create-parameter {:deployment-href deployment-href :node-name node-name :node-index i :type "node-instance" + (create-deployment-parameter #_create-parameter {:deployment-href deployment-href :node-name node-name :node-index i :type "node-instance" :name "state-complete" :value "" :acl {:owner {:principal "ADMIN" :type "ROLE"} :rules [{:principal user :type "USER" :right "MODIFY"}]}}) - (create-parameter {:deployment-href deployment-href :node-name node-name :node-index i :type "node-instance" + (create-deployment-parameter #_create-parameter {:deployment-href deployment-href :node-name node-name :node-index i :type "node-instance" :name "vmstate" :value "init" :acl {:owner {:principal "ADMIN" :type "ROLE"} :rules [{:principal user :type "USER" - :right "MODIFY"}]}})))))) - + :right "MODIFY"}]}})))))) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj index c91ea6bbe..015fa9874 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj @@ -54,7 +54,7 @@ (defmethod crud/new-identifier resource-name [json resource-name] - (let [new-id (str resource-url "/" (du/deployment-parameter-id json))] + (let [new-id (du/deployment-parameter-href json)] (assoc json :id new-id))) (defn deployment-parameter-watch-fn [is-transiant] diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj index e386105e2..219ed3a95 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj @@ -22,11 +22,15 @@ deployment-href name) (str (deployment-path deployment-href) separator))) + + (defn deployment-parameter-node-instance-complete-state-path - [{deployment-href :deployment-href node-name :node-name node-index :node-index name :name :as deployment-parameter}] - (let [node-instance-complete-state-znode-id (string/join "_" [node-name node-index name])] - (str separator - (string/join separator [deployment-href "state" node-instance-complete-state-znode-id])))) + ([deployment-href node-name node-index parameter-name] + (let [node-instance-complete-state-znode-id (string/join "_" [node-name node-index name])] + (str separator + (string/join separator [deployment-href "state" node-instance-complete-state-znode-id])))) + ([{deployment-href :deployment-href node-name :node-name node-index :node-index name :name :as deployment-parameter}] + (deployment-parameter-node-instance-complete-state-path deployment-href node-name node-index name))) (defn lock-deployment "Create a lock for the deployment. This should be used each time multi-operations on zookeeper are needed to complete diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment/state_machine_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment/state_machine_test.clj new file mode 100644 index 000000000..442d7db24 --- /dev/null +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment/state_machine_test.clj @@ -0,0 +1,6 @@ +(ns com.sixsq.slipstream.ssclj.resources.deployment.state-machine-test + (:require [clojure.test :refer [deftest are is]] + [com.sixsq.slipstream.ssclj.resources.deployment.state-machine :refer :all])) + +(deftest next-state + (is (= "executing" (get-next-state "provisioning")))) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj index 26385a18b..8968c3294 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj @@ -12,7 +12,8 @@ [com.sixsq.slipstream.ssclj.app.params :as p] [com.sixsq.slipstream.ssclj.resources.common.utils :as u] [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] - [com.sixsq.slipstream.ssclj.resources.zk.deployment.utils :as zdu])) + [com.sixsq.slipstream.ssclj.resources.zk.deployment.utils :as zdu] + [com.sixsq.slipstream.ssclj.resources.deployment.utils :as du])) (use-fixtures :once t/setup-embedded-zk) @@ -37,7 +38,7 @@ :nodes {:node1 {:parameters {:cloudservice {:description "p1 description" ;TODO only node name and multiplicity are being used for now from all these parameters :default-value "abc" :user-choice-value "ABC"} - :multiplicity {:default-value "1"}} + :multiplicity {:default-value "2"}} :runtime-parameters {:p1 {:description "p1 description" :default-value "abc" :user-choice-value "ABC" @@ -171,4 +172,106 @@ (is (= "provisioning" (get-in provisioning-deployment [:response :body :state]))) (is (= "provisioning" (uzk/get-data (str zdu/separator deployment-href "/state")))) + ))) + +(deftest create-deployment-move-states + + (let [session-admin-json (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "super ADMIN USER ANON")) + session-user (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "jane USER ANON"))] + + ;; adding, retrieving and deleting entry as user should succeed + (let [deployment-href (-> session-user + (request base-uri + :request-method :post + :body (json/write-str valid-entry)) + (t/body->edn) + (t/location)) + abs-uri (str p/service-context (u/de-camelcase deployment-href)) + abs-uri-deployment-parameter-state (str p/service-context dp/resource-url "/" valid-entry-deployment-uuid "_state") + created-deployment (-> session-user + (request abs-uri) + (t/body->edn)) + start-uri (str p/service-context + (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) + started-deployment (-> session-user + (request start-uri) + (t/body->edn)) + update-deployment-parameter-state + (-> session-admin-json + (request abs-uri-deployment-parameter-state :request-method :put + :body (json/write-str {:value "provisioning"})) + (t/body->edn) + (t/is-status 200)) + + provisioning-deployment (-> session-user + (request start-uri) + (t/body->edn) + (t/is-status 200))] + (is (= "provisioning" (get-in provisioning-deployment [:response :body :state]))) + + (is (= "provisioning" (uzk/get-data (str zdu/separator deployment-href "/state")))) + + (-> session-admin-json + (request (str p/service-context (du/deployment-parameter-href + {:deployment-href deployment-href :node-name "node1" :node-index 1 :name "state-complete"})) + :request-method :put :body (json/write-str {:value "provisioning"})) + (t/body->edn) + (t/is-status 200)) + (-> session-admin-json + (request (str p/service-context (du/deployment-parameter-href + {:deployment-href deployment-href :node-name "node1" :node-index 2 :name "state-complete"})) + :request-method :put :body (json/write-str {:value "provisioning"})) + (t/body->edn) + (t/is-status 200)) + + (is (= 1 (count (uzk/children + (zdu/deployment-state-path deployment-href))))) + + (-> session-admin-json + (request (str p/service-context (du/deployment-parameter-href + {:deployment-href deployment-href :node-name "node2" :node-index 1 :name "state-complete"})) + :request-method :put :body (json/write-str {:value "provisioning"})) + (t/body->edn) + (t/is-status 200)) + + (is (= "executing" (uzk/get-data (str zdu/separator deployment-href "/state")))) + + (is (= "executing" (-> session-user + (request (str p/service-context deployment-href)) + (t/body->edn) + (get-in [:response :body :state])))) + + (is (= 3 (count (uzk/children + (zdu/deployment-state-path deployment-href))))) + + (-> session-admin-json + (request (str p/service-context (du/deployment-parameter-href + {:deployment-href deployment-href :node-name "node1" :node-index 1 :name "state-complete"})) + :request-method :put :body (json/write-str {:value "executing"})) + (t/body->edn) + (t/is-status 200)) + (-> session-admin-json + (request (str p/service-context (du/deployment-parameter-href + {:deployment-href deployment-href :node-name "node1" :node-index 2 :name "state-complete"})) + :request-method :put :body (json/write-str {:value "executing"})) + (t/body->edn) + (t/is-status 200)) + + (-> session-admin-json + (request (str p/service-context (du/deployment-parameter-href + {:deployment-href deployment-href :node-name "node2" :node-index 1 :name "state-complete"})) + :request-method :put :body (json/write-str {:value "executing"})) + (t/body->edn) + (t/is-status 200)) + + (is (= "sending report" (-> session-user + (request (str p/service-context deployment-href)) + (t/body->edn) + (get-in [:response :body :state])))) + + ))) \ No newline at end of file diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj index 3093d7eec..e3ac3ae02 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj @@ -45,15 +45,10 @@ valid-entry {:deployment-href deployment-href :node-name "machine" :node-index 1 :type "node-instance" :name "xyz" :value "XYZ" :acl resource-acl-jane} znode-path (zdu/deployment-parameter-path valid-entry) - deployment-parameter-id (-> - (->> {:params {:resource-name resource-url} - :identity identity-admin - :body valid-entry} - (du/add-deployment-parameter-impl) - (assoc {} :response)) - (t/is-status 201) - (t/location)) - abs-uri (str p/service-context (u/de-camelcase deployment-parameter-id)) + deployment-parameter-href (-> valid-entry + du/create-deployment-parameter + :resource-id) + abs-uri (str p/service-context (u/de-camelcase deployment-parameter-href)) created-deployment-parameter (-> session-user-jane (request abs-uri) (t/body->edn) @@ -75,7 +70,19 @@ (t/body->edn) (t/is-status 403)) - (is (not (= "newvalue-albert" (uzk/get-data znode-path))) "deployment parameter can be updated"))) + (is (not (= "newvalue-albert" (uzk/get-data znode-path))) "deployment parameter can be updated") + + + (-> session-user-jane + (request abs-uri :request-method :put + :body (json/write-str {:type "deployment"})) + (t/body->edn) + (t/is-status 200) + (get-in [:response :body :type]) + (= "node-instance") + (is "type should not be updated"))) + + ) ; TODO move deployment parameter with special behavior to deployment lifecycle test From 5d509e5aee3db144ef81605f1301383025f7f083 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Mon, 11 Sep 2017 11:12:04 +0200 Subject: [PATCH 34/46] SSE should answer in json --- .../slipstream/ssclj/resources/deployment_parameter.clj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj index 015fa9874..ac96de3e9 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj @@ -18,7 +18,7 @@ [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] [com.sixsq.slipstream.ssclj.resources.zk.deployment.utils :as zdu] [com.sixsq.slipstream.ssclj.resources.deployment.utils :as du] - ) + [cheshire.core :as json]) (:import (clojure.lang ExceptionInfo))) (def ^:const resource-name du/deployment-parameter-resource-name) @@ -67,14 +67,14 @@ deployment-parameter :watcher (partial (deployment-parameter-watch-fn is-transiant) event-ch id name))) deployment-parameter (assoc deployment-parameter :value value)] - (sse/send-event id name deployment-parameter event-ch) + (sse/send-event id name (json/generate-string deployment-parameter) event-ch) (when is-transiant (async/close! event-ch)))))) (defn send-event-and-set-watcher [event-ch watch-fn {id :id name :name :as deployment-parameter}] (let [value (zdu/get-deployment-parameter-value deployment-parameter :watcher (partial watch-fn event-ch id name)) deployment-parameter (assoc deployment-parameter :value value)] - (sse/send-event id name deployment-parameter event-ch))) + (sse/send-event id name (json/generate-string deployment-parameter) event-ch))) (defn retrieve-deployment-parameter [{{uuid :uuid} :params :as request}] From f7d363ff1782377fa1c4d7e0fe7e6372bb98cfef Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Mon, 11 Sep 2017 12:34:14 +0200 Subject: [PATCH 35/46] enhance http accept header interpretation --- .../ssclj/resources/deployment_parameter.clj | 14 +++++++++++--- .../deployment_parameter_lifecycle_test.clj | 12 ++++++------ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj index ac96de3e9..954853f1b 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_parameter.clj @@ -98,9 +98,17 @@ (defmethod crud/retrieve resource-name [{{accept :accept} :headers :as request}] - (case accept - "text/event-stream" retrieve-sse-impl - retrieve-json-impl)) + (let [accept (if accept (-> accept + (string/replace #"\s" "") + (string/split #",") + set) #{}) + accept-json? (contains? accept "application/json") + accept-sse? (contains? accept "text/event-stream")] + (cond + (and accept-json? accept-sse?) retrieve-sse-impl + accept-json? retrieve-json-impl + accept-sse? retrieve-sse-impl + :else retrieve-json-impl))) (defmethod crud/edit resource-name [request] diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj index e3ac3ae02..91c85ca84 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj @@ -43,16 +43,16 @@ (deftest create-deployment-parameter-xyz (let [deployment-href "deployment/abc34916-6ede-47f7-aaeb-a30ddecbba5b" valid-entry {:deployment-href deployment-href :node-name "machine" :node-index 1 :type "node-instance" - :name "xyz" :value "XYZ" :acl resource-acl-jane} + :name "xyz" :value "XYZ" :acl resource-acl-jane} znode-path (zdu/deployment-parameter-path valid-entry) deployment-parameter-href (-> valid-entry - du/create-deployment-parameter - :resource-id) + du/create-deployment-parameter + :resource-id) abs-uri (str p/service-context (u/de-camelcase deployment-parameter-href)) created-deployment-parameter (-> session-user-jane - (request abs-uri) - (t/body->edn) - (t/is-status 200))] + (request abs-uri) + (t/body->edn) + (t/is-status 200))] (is (= "XYZ" (uzk/get-data znode-path))) From 2984d4f50010bfbf442388886a4c6681b5d912e5 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Mon, 11 Sep 2017 18:46:41 +0200 Subject: [PATCH 36/46] enhance code and fix deployment-href in deployment parameter --- .../slipstream/ssclj/resources/deployment.clj | 9 +- .../ssclj/resources/deployment/utils.clj | 230 +++++++----------- .../resources/spec/deployment_parameter.cljc | 2 +- .../ssclj/resources/zk/deployment/utils.clj | 24 +- .../resources/deployment_lifecycle_test.clj | 41 ++-- .../deployment_parameter_lifecycle_test.clj | 38 +-- 6 files changed, 124 insertions(+), 220 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj index 27227fb9c..5b2bd8048 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj @@ -81,15 +81,11 @@ [request] (retrieve-impl request)) -(defmethod crud/edit resource-name - [request] - (du/edit-deployment-impl request)) - (def delete-impl (std-crud/delete-fn resource-name)) (defmethod crud/delete resource-name [request] - (delete-impl request)) ;TODO cleanup of deployment parameter and in zk should also be done + (delete-impl request)) ;TODO cleanup of deployment parameter and in zk should also be done (def query-impl (std-crud/query-fn resource-name collection-acl collection-uri resource-tag)) @@ -108,8 +104,7 @@ (a/can-modify? resource request) (let [ops (if (.endsWith resourceURI "Collection") [{:rel (:add c/action-uri) :href id}] - [{:rel (:edit c/action-uri) :href id} - {:rel (:delete c/action-uri) :href id} + [{:rel (:delete c/action-uri) :href id} {:rel (:start c/action-uri) :href href}])] (assoc resource :operations ops)) (catch Exception e diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj index 3ee59f855..40217294b 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj @@ -15,55 +15,10 @@ [clojure.string :as string]) (:import (clojure.lang ExceptionInfo))) - (def ^:const deployment-resource-name "Deployment") (def ^:const deployment-resource-url (u/de-camelcase deployment-resource-name)) -(def edit-deployment-impl (std-crud/edit-fn deployment-resource-name)) - -(defn edit-deployment - [deployment-href deployment-body] - (try - (let [current (db/retrieve deployment-href {}) - merged (merge current deployment-body)] - (-> merged - (u/update-timestamps) - (crud/validate) - (db/edit {}) - :body)) - (catch ExceptionInfo ei - (ex-data ei)))) - -(defn edit-deployment-parameter - [deployment-parameter-href deployment-parameter-body] - (try - (let [current (db/retrieve deployment-parameter-href {}) - merged (merge current deployment-parameter-body)] - (-> merged - (u/update-timestamps) - (crud/validate) - (db/edit {}) - :body)) - (catch ExceptionInfo ei - (ex-data ei)))) - -(defn deployment-href-to-uuid [href] (string/replace-first href #"^deployment/" "")) - -;(defn update-deployment-attribut [deployment-uuid attribute-name value] -; (try -; (let [request {:params {:resource-name deployment-resource-url -; :uuid deployment-uuid} -; :identity (create-identity-map ["super" #{"ADMIN"}]) -; :body {(keyword attribute-name) value}} -; {:keys [status body]} (edit-deployment-impl request)] -; (case status -; 200 (log/info "udpated deployment attribute: " body) -; (log/info "unexpected status code when udpating deployment resource:" status))) -; (catch Exception e -; (log/warn "error when updating deployment resource: " (str e) "\n" -; (with-out-str (st/print-cause-trace e)))))) - (def ^:const deployment-parameter-resource-name "DeploymentParameter") (def ^:const deployment-parameter-resource-url (u/de-camelcase deployment-parameter-resource-name)) @@ -78,34 +33,66 @@ (def deployment-parameter-id-separator "_") +(defn deployment-href-to-uuid [href] (string/replace-first href #"^deployment/" "")) + (defn deployment-parameter-href - [{deployment-href :deployment-href node-name :node-name node-index :node-index name :name :as deployment-parameter}] + [{{deployment-href :href} :deployment-href node-name :node-name node-index + :node-index name :name :as deployment-parameter}] (let [deployment-uuid (deployment-href-to-uuid deployment-href) deployment-parameter-element (cond - (and deployment-uuid node-name node-index) [deployment-uuid node-name node-index name] - (and deployment-uuid node-name) [deployment-uuid node-name name] - deployment-uuid [deployment-uuid name]) + (and deployment-uuid node-name node-index) [deployment-uuid node-name + node-index name] + (and deployment-uuid node-name) [deployment-uuid node-name name] + deployment-uuid [deployment-uuid name]) deployment-parameter-path (string/join deployment-parameter-id-separator deployment-parameter-element)] - (string/join "/" [deployment-parameter-resource-url deployment-parameter-path]))) + (string/join "/" [deployment-parameter-resource-url deployment-parameter-path]))) -#_(defn add-deployment-parameter-impl [{:keys [body] :as request}] - (a/can-modify? {:acl deployment-parameter-collection-acl} request) - (let [deployment-parameter (-> body - u/strip-service-attrs - (crud/new-identifier deployment-parameter-resource-name) - (assoc :resourceURI deployment-parameter-resource-uri) - u/update-timestamps - (crud/add-acl request) - crud/validate) - value (:value body) - node-path (zdu/deployment-parameter-path body)] - (uzk/create-all node-path :persistent? true) - (uzk/set-data node-path value) - (when (and (= "state-complete" (:name deployment-parameter)) - (= "node-instance" (:type deployment-parameter))) - (uzk/create-all - (zdu/deployment-parameter-node-instance-complete-state-path deployment-parameter) :persistent? true)) - (db/add deployment-parameter-resource-name deployment-parameter {}))) +(defn set-global-deployment-parameter + [deployment-href parameter-name value] + (try + (let [deployment-parameter {:deployment-href {:href deployment-href} + :name parameter-name + :value value} + current (db/retrieve (deployment-parameter-href deployment-parameter) {}) + merged (-> current + (merge deployment-parameter) + (u/update-timestamps) + (crud/validate))] + (uzk/set-data (zdu/deployment-parameter-path merged) value) + (-> merged + (db/edit {}) + :body)) + (catch ExceptionInfo ei + (ex-data ei)))) + +(defn set-deployment-attribute + [deployment-href attribute-name value] + (try + (let [current-deployment (db/retrieve deployment-href {}) + merged-deployment (-> current-deployment + (merge {(keyword attribute-name) value}) + (u/update-timestamps) + (crud/validate))] + (set-global-deployment-parameter deployment-href attribute-name value) + (-> merged-deployment + (db/edit {}) + :body)) + (catch ExceptionInfo ei + (ex-data ei)))) + +(defn move-deployment-next-state [deployment-href current-state] + (zdu/check-deployment-lock-and-throw! deployment-href) + (zdu/lock-deployment-path deployment-href) + (let [next-state (dsm/get-next-state current-state) ;TODO final state what should be done? + deployment (set-deployment-attribute deployment-href "state" next-state)] + (doseq [n (:nodes deployment)] + (let [node-name (name (key n)) + multiplicity (read-string (get-in (val n) [:parameters :multiplicity :default-value] "1"))] + (doseq [i (range 1 (inc multiplicity))] + (uzk/create-all + (zdu/deployment-parameter-node-instance-complete-state-path + deployment-href node-name i "state-complete") :persistent? true))))) + (zdu/unlock-deployment deployment-href)) (defn create-deployment-parameter [deployment-parameter] (let [deployment-parameter (-> deployment-parameter @@ -130,85 +117,32 @@ [{{uuid :uuid} :params body :body :as request}] (let [current (-> (str deployment-parameter-resource-url "/" uuid) (db/retrieve request) - (a/can-modify? request)) ;TODO we should not allow user to update type and some other properties of deployment parameter (use dissoc) + (a/can-modify? request)) merged (->> (dissoc body :type :deployment-href :node-name :node-index) (merge current)) value (:value merged) parameter-name (:name merged) - deployment-href (:deployment-href merged) + deployment-href (get-in merged [:deployment-href :href]) deployment-parameter (-> merged (u/update-timestamps) (crud/validate))] (when value - (condp = (:type merged) - "deployment" (do - (zdu/check-deployment-lock-and-throw! deployment-href) - (zdu/lock-deployment deployment-href) - (uzk/set-data (zdu/deployment-parameter-path merged) value) - (edit-deployment deployment-href {(keyword parameter-name) value}) - (zdu/unlock-deployment deployment-href)) - "node-instance" (condp = (:name merged) - "state-complete" - (do - (zdu/check-deployment-lock-and-throw! deployment-href) - (zdu/check-same-state-and-throw! deployment-href value) - (zdu/lock-deployment deployment-href) - (zdu/complete-node-instance-state merged) - (when-not (uzk/children - (zdu/deployment-state-path deployment-href)) - ;TODO function trigger next state for current deployment - (let [next-state (dsm/get-next-state value) ;TODO final state what should be done? - deployment (edit-deployment deployment-href {:state next-state}) - deployment-parameter-state {:deployment-href deployment-href :name "state" - :value next-state} - deployment-parameter-state-id (deployment-parameter-href deployment-parameter-state) - deployment-parameter-state (edit-deployment-parameter deployment-parameter-state-id - deployment-parameter-state)] - (uzk/set-data (zdu/deployment-state-path deployment-href) next-state) - (doseq [n (:nodes deployment)] - (let [node-name (name (key n)) - multiplicity (read-string (get-in (val n) [:parameters :multiplicity :default-value] "1"))] - (doseq [i (range 1 (inc multiplicity))] - (uzk/create-all - (zdu/deployment-parameter-node-instance-complete-state-path - deployment-href node-name i "state-complete") :persistent? true) - ))))) - (zdu/unlock-deployment deployment-href)) - (uzk/set-data (zdu/deployment-parameter-path merged) value) - ))) + (case (:type deployment-parameter) + "deployment" (set-deployment-attribute deployment-href parameter-name value) + "node-instance" (case parameter-name + "state-complete" (do + (zdu/check-deployment-lock-and-throw! deployment-href) + (zdu/check-same-state-and-throw! deployment-href value) + (zdu/complete-node-instance-state merged) + (when (zdu/all-nodes-completed-current-state? deployment-href) + (move-deployment-next-state deployment-href value))) + (uzk/set-data (zdu/deployment-parameter-path deployment-parameter) value)))) (db/edit deployment-parameter request))) -(defn update-parameter [deployment-parameter] - (try - (let [request {:params {:resource-name deployment-parameter-resource-url - :uuid (deployment-href-to-uuid (:deployment-href deployment-parameter))} - :identity (create-identity-map ["super" #{"ADMIN"}]) - :body deployment-parameter} - {:keys [status body]} (edit-deployment-parameter-impl request)] - (case status - 200 (log/info "updated deployment-parameter: " body) - (log/info "unexpected status code when updating deployment-parameter resource:" status))) - (catch Exception e - (log/warn "error when updating deployment-parameter resource: " (str e) "\n" - (with-out-str (st/print-cause-trace e)))))) - -#_(defn create-parameter [deployment-parameter] - (try - (let [request {:params {:resource-name deployment-parameter-resource-url} - :identity (create-identity-map ["super" #{"ADMIN"}]) - :body deployment-parameter} - {:keys [status body]} (add-deployment-parameter-impl request)] - (case status - 201 (log/info "created deployment-parameter: " body) - (log/info "unexpected status code when creating deployment-parameter resource:" status))) - (catch Exception e - (log/warn "error when creating deployment-parameter resource: " (str e) "\n" - (with-out-str (st/print-cause-trace e)))))) - (defn create-parameters [identity {nodes :nodes deployment-href :id state :state}] (let [user (:current identity)] - (create-deployment-parameter #_create-parameter - {:deployment-href deployment-href :name "state" :value state :type "deployment" + (create-deployment-parameter + {:deployment-href {:href deployment-href} :name "state" :value state :type "deployment" :acl {:owner {:principal "ADMIN" :type "ROLE"} :rules [{:principal user @@ -218,15 +152,17 @@ (let [node-name (name (key n)) multiplicity (read-string (get-in (val n) [:parameters :multiplicity :default-value] "1"))] (doseq [i (range 1 (inc multiplicity))] - (create-deployment-parameter #_create-parameter {:deployment-href deployment-href :node-name node-name :node-index i :type "node-instance" - :name "state-complete" :value "" :acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:principal user - :type "USER" - :right "MODIFY"}]}}) - (create-deployment-parameter #_create-parameter {:deployment-href deployment-href :node-name node-name :node-index i :type "node-instance" - :name "vmstate" :value "init" :acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:principal user - :type "USER" - :right "MODIFY"}]}})))))) \ No newline at end of file + (create-deployment-parameter + {:deployment-href {:href deployment-href} :node-name node-name :node-index i :type "node-instance" + :name "state-complete" :value "" :acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal user + :type "USER" + :right "MODIFY"}]}}) + (create-deployment-parameter + {:deployment-href {:href deployment-href} :node-name node-name :node-index i :type "node-instance" + :name "vmstate" :value "init" :acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal user + :type "USER" + :right "MODIFY"}]}})))))) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_parameter.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_parameter.cljc index e630728b6..522a97601 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_parameter.cljc +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_parameter.cljc @@ -6,7 +6,7 @@ [com.sixsq.slipstream.ssclj.util.spec :as su] [com.sixsq.slipstream.ssclj.resources.spec.common :as c])) -(s/def :cimi.deployment-parameter/deployment-href :cimi.core/nonblank-string) +(s/def :cimi.deployment-parameter/deployment-href :cimi.common/resource-link) (s/def :cimi.deployment-parameter/name :cimi.core/nonblank-string) (s/def :cimi.deployment-parameter/value string?) (s/def :cimi.deployment-parameter/node-name :cimi.core/nonblank-string) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj index 219ed3a95..3ed403887 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj @@ -1,6 +1,7 @@ (ns com.sixsq.slipstream.ssclj.resources.zk.deployment.utils (:require [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] - [clojure.string :as string])) + [clojure.string :as string] + [clojure.tools.logging :as log])) (def separator "/") (def nodes-name "nodes") @@ -13,7 +14,7 @@ (str (deployment-path deployment-href) separator lock-name)) (defn deployment-parameter-path - [{deployment-href :deployment-href node-name :node-name node-index :node-index name :name :as deployment-parameter}] + [{{deployment-href :href} :deployment-href node-name :node-name node-index :node-index name :name :as deployment-parameter}] (->> (cond (and node-name node-index) (string/join separator [nodes-name node-name node-index name]) @@ -29,7 +30,7 @@ (let [node-instance-complete-state-znode-id (string/join "_" [node-name node-index name])] (str separator (string/join separator [deployment-href "state" node-instance-complete-state-znode-id])))) - ([{deployment-href :deployment-href node-name :node-name node-index :node-index name :name :as deployment-parameter}] + ([{{deployment-href :href} :deployment-href node-name :node-name node-index :node-index name :name :as deployment-parameter}] (deployment-parameter-node-instance-complete-state-path deployment-href node-name node-index name))) (defn lock-deployment @@ -51,7 +52,7 @@ (defn check-deployment-lock-and-throw! "Throw if deployment is locked." [deployment-href] - (when (is-deployment-locked? deployment-href) ; TODO throw well know error code + (when (is-deployment-locked? deployment-href) ; TODO throw well known error code (throw (Exception. "Deployment is locked, come back later!")))) (defn get-deployment-parameter-value [deployment-parameter & {:keys [watcher]}] @@ -60,19 +61,22 @@ (uzk/get-data (deployment-parameter-path deployment-parameter)))) (defn deployment-state-path [deployment-href] - (deployment-parameter-path {:deployment-href deployment-href :name "state"})) + (deployment-parameter-path {:deployment-href {:href deployment-href} :name "state"})) (defn get-deployment-state [deployment-href] (uzk/get-data (deployment-state-path deployment-href))) (defn check-same-state-and-throw! - [deployment-href state] - (let [current-state (get-deployment-state deployment-href)] - (when-not (= state current-state) + [deployment-href node-complete-state] + (let [current-deployment-state (get-deployment-state deployment-href)] + (when-not (= node-complete-state current-deployment-state) (throw (Exception. - (str "State machine (complete-state = " current-state - ") in different state from deployment state = " state "!")))))) + (str "State machine (complete-state = " node-complete-state + ") in different state from deployment state = " current-deployment-state "!")))))) (defn complete-node-instance-state [{state :value :as deployment-parameter}] (uzk/delete (deployment-parameter-node-instance-complete-state-path deployment-parameter)) (uzk/set-data (deployment-parameter-path deployment-parameter) state)) + +(defn all-nodes-completed-current-state? [deployment-href] + (not (uzk/children (deployment-state-path deployment-href)))) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj index 8968c3294..4417be197 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj @@ -21,8 +21,6 @@ (def base-uri (str p/service-context resource-url)) - - (defn ring-app [] (t/make-ring-app (t/concat-routes routes/final-routes))) @@ -141,7 +139,8 @@ (t/is-status 201) (t/location)) abs-uri (str p/service-context (u/de-camelcase deployment-href)) - abs-uri-deployment-parameter-state (str p/service-context dp/resource-url "/" valid-entry-deployment-uuid "_state") + abs-uri-deployment-parameter-state (str p/service-context dp/resource-url + "/" valid-entry-deployment-uuid "_state") created-deployment (-> session-user (request abs-uri) (t/body->edn) @@ -165,9 +164,9 @@ (t/body->edn) (t/is-status 200)) provisioning-deployment (-> session-user - (request start-uri) - (t/body->edn) - (t/is-status 200))] + (request start-uri) + (t/body->edn) + (t/is-status 200))] (is (= "provisioning" (get-in provisioning-deployment [:response :body :state]))) @@ -191,7 +190,8 @@ (t/body->edn) (t/location)) abs-uri (str p/service-context (u/de-camelcase deployment-href)) - abs-uri-deployment-parameter-state (str p/service-context dp/resource-url "/" valid-entry-deployment-uuid "_state") + abs-uri-deployment-parameter-state (str p/service-context dp/resource-url + "/" valid-entry-deployment-uuid "_state") created-deployment (-> session-user (request abs-uri) (t/body->edn)) @@ -217,23 +217,26 @@ (-> session-admin-json (request (str p/service-context (du/deployment-parameter-href - {:deployment-href deployment-href :node-name "node1" :node-index 1 :name "state-complete"})) + {:deployment-href {:href deployment-href} :node-name "node1" + :node-index 1 :name "state-complete"})) :request-method :put :body (json/write-str {:value "provisioning"})) (t/body->edn) (t/is-status 200)) (-> session-admin-json (request (str p/service-context (du/deployment-parameter-href - {:deployment-href deployment-href :node-name "node1" :node-index 2 :name "state-complete"})) + {:deployment-href {:href deployment-href} :node-name "node1" + :node-index 2 :name "state-complete"})) :request-method :put :body (json/write-str {:value "provisioning"})) (t/body->edn) (t/is-status 200)) (is (= 1 (count (uzk/children - (zdu/deployment-state-path deployment-href))))) + (zdu/deployment-state-path deployment-href))))) (-> session-admin-json (request (str p/service-context (du/deployment-parameter-href - {:deployment-href deployment-href :node-name "node2" :node-index 1 :name "state-complete"})) + {:deployment-href {:href deployment-href} :node-name "node2" + :node-index 1 :name "state-complete"})) :request-method :put :body (json/write-str {:value "provisioning"})) (t/body->edn) (t/is-status 200)) @@ -250,28 +253,30 @@ (-> session-admin-json (request (str p/service-context (du/deployment-parameter-href - {:deployment-href deployment-href :node-name "node1" :node-index 1 :name "state-complete"})) + {:deployment-href {:href deployment-href} :node-name "node1" + :node-index 1 :name "state-complete"})) :request-method :put :body (json/write-str {:value "executing"})) (t/body->edn) (t/is-status 200)) (-> session-admin-json (request (str p/service-context (du/deployment-parameter-href - {:deployment-href deployment-href :node-name "node1" :node-index 2 :name "state-complete"})) + {:deployment-href {:href deployment-href} :node-name "node1" + :node-index 2 :name "state-complete"})) :request-method :put :body (json/write-str {:value "executing"})) (t/body->edn) (t/is-status 200)) (-> session-admin-json (request (str p/service-context (du/deployment-parameter-href - {:deployment-href deployment-href :node-name "node2" :node-index 1 :name "state-complete"})) + {:deployment-href {:href deployment-href} :node-name "node2" + :node-index 1 :name "state-complete"})) :request-method :put :body (json/write-str {:value "executing"})) (t/body->edn) (t/is-status 200)) (is (= "sending report" (-> session-user - (request (str p/service-context deployment-href)) - (t/body->edn) - (get-in [:response :body :state])))) - + (request (str p/service-context deployment-href)) + (t/body->edn) + (get-in [:response :body :state])))) ))) \ No newline at end of file diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj index 91c85ca84..76cf20ecf 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj @@ -42,7 +42,7 @@ (deftest create-deployment-parameter-xyz (let [deployment-href "deployment/abc34916-6ede-47f7-aaeb-a30ddecbba5b" - valid-entry {:deployment-href deployment-href :node-name "machine" :node-index 1 :type "node-instance" + valid-entry {:deployment-href {:href deployment-href} :node-name "machine" :node-index 1 :type "node-instance" :name "xyz" :value "XYZ" :acl resource-acl-jane} znode-path (zdu/deployment-parameter-path valid-entry) deployment-parameter-href (-> valid-entry @@ -83,39 +83,3 @@ (is "type should not be updated"))) ) - - -; TODO move deployment parameter with special behavior to deployment lifecycle test -#_(deftest deployment-parameter-state-complete - (let [deployment-href "deployment/abc34916-6ede-47f7-aaeb-a30ddecbba5b" - valid-entry {:deployment-href deployment-href :node-name "machine" :node-index 1 :type "node-instance" - :name "state-complete" :value "executing" :acl resource-acl-jane} - znode-path (zdu/deployment-parameter-path valid-entry) - deployment-parameter-id (-> - (->> {:params {:resource-name resource-url} - :identity identity-admin - :body valid-entry} - (du/add-deployment-parameter-impl) - (assoc {} :response)) - (t/is-status 201) - (t/location)) - abs-uri (str p/service-context (u/de-camelcase deployment-parameter-id)) - created-deployment-parameter (-> session-user-jane - (request abs-uri) - (t/body->edn) - (t/is-status 200))] - (is (uzk/exists "/deployment/abc34916-6ede-47f7-aaeb-a30ddecbba5b/state/machine_1_state-complete")) - - (is (= "executing" (uzk/get-data znode-path))) - - - - (-> session-user-jane - (request abs-uri :request-method :put - :body (json/write-str {:value ""})) - (t/body->edn) - (t/is-status 200)) - - (is (not (uzk/exists "/deployment/abc34916-6ede-47f7-aaeb-a30ddecbba5b/state/machine_1_state-complete"))))) - - From 24dfaf13b7c883deb86ff0105ab3090e88befe4b Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Mon, 11 Sep 2017 23:36:29 +0200 Subject: [PATCH 37/46] rename deployment-href to deployment in deployment parameter and minor --- .../slipstream/ssclj/resources/deployment.clj | 2 +- .../resources/deployment/state_machine.clj | 30 ++++--- .../ssclj/resources/deployment/utils.clj | 50 ++++++------ .../resources/spec/deployment_parameter.cljc | 4 +- .../ssclj/resources/zk/deployment/utils.clj | 7 +- .../resources/deployment_lifecycle_test.clj | 79 ++++++++++--------- .../deployment_parameter_lifecycle_test.clj | 2 +- 7 files changed, 90 insertions(+), 84 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj index 5b2bd8048..44298f5a5 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj @@ -67,7 +67,7 @@ (assoc :resourceURI resource-uri) u/update-timestamps (crud/add-acl request) - (assoc :state dsm/initial-state)) + (assoc :state dsm/init-state)) response (db/add resource-name (crud/validate new-deployment) {})] response)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/state_machine.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/state_machine.clj index 2d5921e1f..c8c44afa2 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/state_machine.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/state_machine.clj @@ -16,23 +16,27 @@ coordination required. The topology of the run is persisted as an edn structure inside the ./topology znode. This can be changed as nodes - come and go, for scalable deployments." - (:require [zookeeper :as zk])) + come and go, for scalable deployments.") -;; State machine states -(def initial-state "init") +(def init-state "init") +(def provisioning-state "provisioning") +(def executing-state "executing") +(def sending-report-state "sending report") +(def ready-state "ready") +(def finalyzing-state "finalyzing") +(def terminated-state "terminated") (def valid-transitions - {initial-state ["provisioning"] - "provisioning" ["executing"] - "executing" ["sending report"] - "sending report" ["ready"] - "ready" ["provisioning"] - "finalyzing" ["terminated"] - "terminated" []}) + {init-state [provisioning-state] + provisioning-state [executing-state] + executing-state [sending-report-state] + sending-report-state [ready-state] + ready-state [provisioning-state] + finalyzing-state [terminated-state] + terminated-state []}) (defn get-next-state [current-state] (->> current-state - (get valid-transitions) - first)) \ No newline at end of file + (get valid-transitions) + first)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj index 40217294b..bc27ee08c 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj @@ -36,8 +36,8 @@ (defn deployment-href-to-uuid [href] (string/replace-first href #"^deployment/" "")) (defn deployment-parameter-href - [{{deployment-href :href} :deployment-href node-name :node-name node-index - :node-index name :name :as deployment-parameter}] + [{{deployment-href :href} :deployment node-name :node-name node-index + :node-index name :name :as deployment-parameter}] (let [deployment-uuid (deployment-href-to-uuid deployment-href) deployment-parameter-element (cond (and deployment-uuid node-name node-index) [deployment-uuid node-name @@ -50,9 +50,9 @@ (defn set-global-deployment-parameter [deployment-href parameter-name value] (try - (let [deployment-parameter {:deployment-href {:href deployment-href} - :name parameter-name - :value value} + (let [deployment-parameter {:deployment {:href deployment-href} + :name parameter-name + :value value} current (db/retrieve (deployment-parameter-href deployment-parameter) {}) merged (-> current (merge deployment-parameter) @@ -118,11 +118,11 @@ (let [current (-> (str deployment-parameter-resource-url "/" uuid) (db/retrieve request) (a/can-modify? request)) - merged (->> (dissoc body :type :deployment-href :node-name :node-index) + merged (->> (dissoc body :type :deployment :node-name :node-index) (merge current)) value (:value merged) parameter-name (:name merged) - deployment-href (get-in merged [:deployment-href :href]) + deployment-href (get-in merged [:deployment :href]) deployment-parameter (-> merged (u/update-timestamps) (crud/validate))] @@ -142,27 +142,27 @@ (defn create-parameters [identity {nodes :nodes deployment-href :id state :state}] (let [user (:current identity)] (create-deployment-parameter - {:deployment-href {:href deployment-href} :name "state" :value state :type "deployment" - :acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:principal user - :type "USER" - :right "VIEW"}]}}) + {:deployment {:href deployment-href} :name "state" :value state :type "deployment" + :acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal user + :type "USER" + :right "VIEW"}]}}) (doseq [n nodes] (let [node-name (name (key n)) multiplicity (read-string (get-in (val n) [:parameters :multiplicity :default-value] "1"))] (doseq [i (range 1 (inc multiplicity))] (create-deployment-parameter - {:deployment-href {:href deployment-href} :node-name node-name :node-index i :type "node-instance" - :name "state-complete" :value "" :acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:principal user - :type "USER" - :right "MODIFY"}]}}) + {:deployment {:href deployment-href} :node-name node-name :node-index i :type "node-instance" + :name "state-complete" :value "" :acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal user + :type "USER" + :right "MODIFY"}]}}) (create-deployment-parameter - {:deployment-href {:href deployment-href} :node-name node-name :node-index i :type "node-instance" - :name "vmstate" :value "init" :acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:principal user - :type "USER" - :right "MODIFY"}]}})))))) \ No newline at end of file + {:deployment {:href deployment-href} :node-name node-name :node-index i :type "node-instance" + :name "vmstate" :value "unknown" :acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal user + :type "USER" + :right "MODIFY"}]}})))))) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_parameter.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_parameter.cljc index 522a97601..8dbb14945 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_parameter.cljc +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_parameter.cljc @@ -6,7 +6,7 @@ [com.sixsq.slipstream.ssclj.util.spec :as su] [com.sixsq.slipstream.ssclj.resources.spec.common :as c])) -(s/def :cimi.deployment-parameter/deployment-href :cimi.common/resource-link) +(s/def :cimi.deployment-parameter/deployment :cimi.common/resource-link) (s/def :cimi.deployment-parameter/name :cimi.core/nonblank-string) (s/def :cimi.deployment-parameter/value string?) (s/def :cimi.deployment-parameter/node-name :cimi.core/nonblank-string) @@ -16,7 +16,7 @@ (s/def :cimi/deployment-parameter (su/only-keys-maps c/common-attrs - {:req-un [:cimi.deployment-parameter/deployment-href + {:req-un [:cimi.deployment-parameter/deployment :cimi.deployment-parameter/name :cimi.deployment-parameter/type] :opt-un [:cimi.deployment-parameter/node-name diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj index 3ed403887..36d1a473b 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj @@ -14,7 +14,7 @@ (str (deployment-path deployment-href) separator lock-name)) (defn deployment-parameter-path - [{{deployment-href :href} :deployment-href node-name :node-name node-index :node-index name :name :as deployment-parameter}] + [{{deployment-href :href} :deployment node-name :node-name node-index :node-index name :name :as deployment-parameter}] (->> (cond (and node-name node-index) (string/join separator [nodes-name node-name node-index name]) @@ -30,7 +30,8 @@ (let [node-instance-complete-state-znode-id (string/join "_" [node-name node-index name])] (str separator (string/join separator [deployment-href "state" node-instance-complete-state-znode-id])))) - ([{{deployment-href :href} :deployment-href node-name :node-name node-index :node-index name :name :as deployment-parameter}] + ([{{deployment-href :href} :deployment node-name :node-name node-index :node-index name :name + :as deployment-parameter}] (deployment-parameter-node-instance-complete-state-path deployment-href node-name node-index name))) (defn lock-deployment @@ -61,7 +62,7 @@ (uzk/get-data (deployment-parameter-path deployment-parameter)))) (defn deployment-state-path [deployment-href] - (deployment-parameter-path {:deployment-href {:href deployment-href} :name "state"})) + (deployment-parameter-path {:deployment {:href deployment-href} :name "state"})) (defn get-deployment-state [deployment-href] (uzk/get-data (deployment-state-path deployment-href))) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj index 4417be197..851340ced 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj @@ -13,7 +13,8 @@ [com.sixsq.slipstream.ssclj.resources.common.utils :as u] [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] [com.sixsq.slipstream.ssclj.resources.zk.deployment.utils :as zdu] - [com.sixsq.slipstream.ssclj.resources.deployment.utils :as du])) + [com.sixsq.slipstream.ssclj.resources.deployment.utils :as du] + [com.sixsq.slipstream.ssclj.resources.deployment.state-machine :as dsm])) (use-fixtures :once t/setup-embedded-zk) @@ -113,13 +114,13 @@ (is (not (get-in created-deployment [:body :start-time]))) (is (get-in started-deployment [:response :body :start-time])) - (is (= "init" (get-in started-deployment [:response :body :state]))) + (is (= dsm/init-state (get-in started-deployment [:response :body :state]))) (are [expected value] (= expected value) - "init" (uzk/get-data (str zdu/separator deployment-href "/state")) - "init" (uzk/get-data - (str zdu/separator deployment-href "/" zdu/nodes-name "/node2/1/" "vmstate")))))) + dsm/init-state (uzk/get-data (str zdu/separator deployment-href "/state")) + "unknown" (uzk/get-data + (str zdu/separator deployment-href "/" zdu/nodes-name "/node2/1/" "vmstate")))))) (deftest create-deployment-update-deployment-state @@ -154,13 +155,13 @@ update-deployment-parameter-state (-> session-user (request abs-uri-deployment-parameter-state :request-method :put - :body (json/write-str {:value "provisioning"})) + :body (json/write-str {:value dsm/provisioning-state})) (t/body->edn) (t/is-status 403)) update-deployment-parameter-state (-> session-admin-json (request abs-uri-deployment-parameter-state :request-method :put - :body (json/write-str {:value "provisioning"})) + :body (json/write-str {:value dsm/provisioning-state})) (t/body->edn) (t/is-status 200)) provisioning-deployment (-> session-user @@ -168,9 +169,9 @@ (t/body->edn) (t/is-status 200))] - (is (= "provisioning" (get-in provisioning-deployment [:response :body :state]))) + (is (= dsm/provisioning-state (get-in provisioning-deployment [:response :body :state]))) - (is (= "provisioning" (uzk/get-data (str zdu/separator deployment-href "/state")))) + (is (= dsm/provisioning-state (uzk/get-data (str zdu/separator deployment-href "/state")))) ))) (deftest create-deployment-move-states @@ -203,7 +204,7 @@ update-deployment-parameter-state (-> session-admin-json (request abs-uri-deployment-parameter-state :request-method :put - :body (json/write-str {:value "provisioning"})) + :body (json/write-str {:value dsm/provisioning-state})) (t/body->edn) (t/is-status 200)) @@ -211,22 +212,22 @@ (request start-uri) (t/body->edn) (t/is-status 200))] - (is (= "provisioning" (get-in provisioning-deployment [:response :body :state]))) + (is (= dsm/provisioning-state (get-in provisioning-deployment [:response :body :state]))) - (is (= "provisioning" (uzk/get-data (str zdu/separator deployment-href "/state")))) + (is (= dsm/provisioning-state (uzk/get-data (str zdu/separator deployment-href "/state")))) (-> session-admin-json (request (str p/service-context (du/deployment-parameter-href - {:deployment-href {:href deployment-href} :node-name "node1" - :node-index 1 :name "state-complete"})) - :request-method :put :body (json/write-str {:value "provisioning"})) + {:deployment {:href deployment-href} :node-name "node1" + :node-index 1 :name "state-complete"})) + :request-method :put :body (json/write-str {:value dsm/provisioning-state})) (t/body->edn) (t/is-status 200)) (-> session-admin-json (request (str p/service-context (du/deployment-parameter-href - {:deployment-href {:href deployment-href} :node-name "node1" - :node-index 2 :name "state-complete"})) - :request-method :put :body (json/write-str {:value "provisioning"})) + {:deployment {:href deployment-href} :node-name "node1" + :node-index 2 :name "state-complete"})) + :request-method :put :body (json/write-str {:value dsm/provisioning-state})) (t/body->edn) (t/is-status 200)) @@ -235,48 +236,48 @@ (-> session-admin-json (request (str p/service-context (du/deployment-parameter-href - {:deployment-href {:href deployment-href} :node-name "node2" - :node-index 1 :name "state-complete"})) - :request-method :put :body (json/write-str {:value "provisioning"})) + {:deployment {:href deployment-href} :node-name "node2" + :node-index 1 :name "state-complete"})) + :request-method :put :body (json/write-str {:value dsm/provisioning-state})) (t/body->edn) (t/is-status 200)) - (is (= "executing" (uzk/get-data (str zdu/separator deployment-href "/state")))) + (is (= dsm/executing-state (uzk/get-data (str zdu/separator deployment-href "/state")))) - (is (= "executing" (-> session-user - (request (str p/service-context deployment-href)) - (t/body->edn) - (get-in [:response :body :state])))) + (is (= dsm/executing-state (-> session-user + (request (str p/service-context deployment-href)) + (t/body->edn) + (get-in [:response :body :state])))) (is (= 3 (count (uzk/children (zdu/deployment-state-path deployment-href))))) (-> session-admin-json (request (str p/service-context (du/deployment-parameter-href - {:deployment-href {:href deployment-href} :node-name "node1" - :node-index 1 :name "state-complete"})) - :request-method :put :body (json/write-str {:value "executing"})) + {:deployment {:href deployment-href} :node-name "node1" + :node-index 1 :name "state-complete"})) + :request-method :put :body (json/write-str {:value dsm/executing-state})) (t/body->edn) (t/is-status 200)) (-> session-admin-json (request (str p/service-context (du/deployment-parameter-href - {:deployment-href {:href deployment-href} :node-name "node1" - :node-index 2 :name "state-complete"})) - :request-method :put :body (json/write-str {:value "executing"})) + {:deployment {:href deployment-href} :node-name "node1" + :node-index 2 :name "state-complete"})) + :request-method :put :body (json/write-str {:value dsm/executing-state})) (t/body->edn) (t/is-status 200)) (-> session-admin-json (request (str p/service-context (du/deployment-parameter-href - {:deployment-href {:href deployment-href} :node-name "node2" - :node-index 1 :name "state-complete"})) - :request-method :put :body (json/write-str {:value "executing"})) + {:deployment {:href deployment-href} :node-name "node2" + :node-index 1 :name "state-complete"})) + :request-method :put :body (json/write-str {:value dsm/executing-state})) (t/body->edn) (t/is-status 200)) - (is (= "sending report" (-> session-user - (request (str p/service-context deployment-href)) - (t/body->edn) - (get-in [:response :body :state])))) + (is (= dsm/sending-report-state (-> session-user + (request (str p/service-context deployment-href)) + (t/body->edn) + (get-in [:response :body :state])))) ))) \ No newline at end of file diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj index 76cf20ecf..2ab7534b0 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj @@ -42,7 +42,7 @@ (deftest create-deployment-parameter-xyz (let [deployment-href "deployment/abc34916-6ede-47f7-aaeb-a30ddecbba5b" - valid-entry {:deployment-href {:href deployment-href} :node-name "machine" :node-index 1 :type "node-instance" + valid-entry {:deployment {:href deployment-href} :node-name "machine" :node-index 1 :type "node-instance" :name "xyz" :value "XYZ" :acl resource-acl-jane} znode-path (zdu/deployment-parameter-path valid-entry) deployment-parameter-href (-> valid-entry From 86a1d2a389262316c653f85aaec4dd9f5bf166f8 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Thu, 14 Sep 2017 09:39:27 +0200 Subject: [PATCH 38/46] abort deployment possible and creation of deployment from java code --- .../slipstream/persistence/Deployment.java | 180 ++++++++++++++++++ .../sixsq/slipstream/run/RunListResource.java | 22 +-- .../resources/deployment/state_machine.clj | 27 ++- .../ssclj/resources/deployment/utils.clj | 29 ++- .../ssclj/resources/spec/deployment.cljc | 27 +-- .../deployment/state_machine_test.clj | 13 +- .../resources/deployment_lifecycle_test.clj | 89 ++++++++- 7 files changed, 335 insertions(+), 52 deletions(-) create mode 100644 jar-persistence/src/main/java/com/sixsq/slipstream/persistence/Deployment.java diff --git a/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/Deployment.java b/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/Deployment.java new file mode 100644 index 000000000..cbb683312 --- /dev/null +++ b/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/Deployment.java @@ -0,0 +1,180 @@ +package com.sixsq.slipstream.persistence; + +import com.google.gson.annotations.SerializedName; +import com.sixsq.slipstream.acl.TypePrincipal; +import com.sixsq.slipstream.acl.TypePrincipalRight; +import com.sixsq.slipstream.util.SscljProxy; +import com.sixsq.slipstream.acl.ACL; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +public class Deployment { + private static final String DEPLOYMENT_RESOURCE = "api/deployment"; + + @SuppressWarnings("unused") + private String id; + + @SuppressWarnings("unused") + @SerializedName("module-resource-uri") + private String moduleResourceUri; + + @SuppressWarnings("unused") + private String type; + + @SuppressWarnings("unused") + private String category; + + @SuppressWarnings("unused") + private boolean mutable; + + @SuppressWarnings("unused") + @SerializedName("keep-running") + private boolean keepRunning; + + @SuppressWarnings("unused") + private ArrayList tags; + + @SuppressWarnings("unused") + private ACL acl; + + @SuppressWarnings("unused") + private String state; + + @SuppressWarnings("unused") + private HashMap nodes = new HashMap<>(); + + public void setId(String id) { + this.id = id; + } + + public void setModuleResourceUri(String moduleResourceUri) { + this.moduleResourceUri = moduleResourceUri; + } + + public void setType(String type) { + this.type = type; + } + + public void setCategory(String category) { + this.category = category; + } + + public void setMutable(boolean mutable) { + this.mutable = mutable; + } + + public void setAcl(ACL acl) { + this.acl = acl; + } + + public void setState(String state) { + this.state = state; + } + + public void setKeepRunning(boolean keepRunning) { + this.keepRunning = keepRunning; + } + + public void setNodes(HashMap nodes) { + this.nodes = nodes; + } + + public void setTags(ArrayList tags) { + this.tags = tags; + } + + public String getId() { + return id; + } + + public String getModuleResourceUri() { + return moduleResourceUri; + } + + public String getType() { + return type; + } + + public String getCategory() { + return category; + } + + public boolean isMutable() { + return mutable; + } + + public ACL getAcl() { + return acl; + } + + public String getState() { + return state; + } + + public boolean isKeepRunning() { + return keepRunning; + } + + public ArrayList getTags() { + return tags; + } + + public HashMap getNodes() { + return nodes; + } + + class Node { + class Parameter { + String description; + String value; + + Parameter (String value, String description) { + this.value = value; + this.description = description; + } + } + @SerializedName("runtime-parameters") + HashMap runtimeParameters = new HashMap<>(); + + Node (String nodeName, Run run) { + for (RuntimeParameter rp : run.getRuntimeParameters().values()) { + if (rp.getGroup().equals(nodeName)) { + runtimeParameters.put(rp.getName(), new Parameter(rp.getValue(), rp.getDescription())); + } + } + } + } + + public Deployment(Run run) { + this.id = "deployment/" + run.getUuid(); + this.moduleResourceUri = run.getRefqname(); + this.type = run.getType().name(); + this.category = run.getCategory().name(); + this.mutable = run.isMutable(); + this.state = run.getState().name(); + + for (String nodeName: run.getNodeNamesList()) { + this.nodes.put(nodeName, new Node(nodeName, run)); + } + + try { + this.tags = new ArrayList<>(Arrays.asList(run.getRuntimeParameterValue("ss:tags").split(","))); + } catch (Exception ignored) { } + + TypePrincipal owner = new TypePrincipal(TypePrincipal.PrincipalType.USER, run.getUser()); + List rules = new ArrayList(); + rules.add(new TypePrincipalRight(TypePrincipal.PrincipalType.USER, run.getUser(), TypePrincipalRight.Right.MODIFY)); + this.acl = new ACL(owner, rules); + } + + public String toJson() { + return SscljProxy.toJson(this); + } + + public static void post(Deployment deployment) { + SscljProxy.post(DEPLOYMENT_RESOURCE, "internal ADMIN", deployment); + } +} diff --git a/jar-service/src/main/java/com/sixsq/slipstream/run/RunListResource.java b/jar-service/src/main/java/com/sixsq/slipstream/run/RunListResource.java index 47ff30476..38e46780f 100644 --- a/jar-service/src/main/java/com/sixsq/slipstream/run/RunListResource.java +++ b/jar-service/src/main/java/com/sixsq/slipstream/run/RunListResource.java @@ -34,6 +34,8 @@ import javax.persistence.RollbackException; import com.sixsq.slipstream.dashboard.DashboardResource; +import com.sixsq.slipstream.persistence.*; +import com.sixsq.slipstream.util.*; import org.hibernate.StaleObjectStateException; import org.restlet.data.Form; import org.restlet.data.MediaType; @@ -55,24 +57,7 @@ import com.sixsq.slipstream.exceptions.SlipStreamException; import com.sixsq.slipstream.exceptions.ValidationException; import com.sixsq.slipstream.factory.RunFactory; -import com.sixsq.slipstream.persistence.Module; -import com.sixsq.slipstream.persistence.ModuleCategory; -import com.sixsq.slipstream.persistence.ModuleParameter; -import com.sixsq.slipstream.persistence.NodeParameter; -import com.sixsq.slipstream.persistence.Parameter; -import com.sixsq.slipstream.persistence.Run; -import com.sixsq.slipstream.persistence.RunParameter; -import com.sixsq.slipstream.persistence.RunType; -import com.sixsq.slipstream.persistence.RuntimeParameter; -import com.sixsq.slipstream.persistence.ServiceConfiguration; -import com.sixsq.slipstream.persistence.User; -import com.sixsq.slipstream.persistence.UserParameter; -import com.sixsq.slipstream.persistence.Vm; import com.sixsq.slipstream.resource.BaseResource; -import com.sixsq.slipstream.util.ConfigurationUtil; -import com.sixsq.slipstream.util.HtmlUtil; -import com.sixsq.slipstream.util.RequestUtil; -import com.sixsq.slipstream.util.SerializationUtil; /** * Unit test: @@ -189,6 +174,9 @@ public void createRun(Representation entity) setLastExecute(user); + Deployment deployment = new Deployment(run); + Deployment.post(deployment); + run.postEventCreated(); } catch (SlipStreamClientException ex) { diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/state_machine.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/state_machine.clj index c8c44afa2..076b569e7 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/state_machine.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/state_machine.clj @@ -18,13 +18,17 @@ The topology of the run is persisted as an edn structure inside the ./topology znode. This can be changed as nodes come and go, for scalable deployments.") -(def init-state "init") -(def provisioning-state "provisioning") -(def executing-state "executing") -(def sending-report-state "sending report") -(def ready-state "ready") -(def finalyzing-state "finalyzing") -(def terminated-state "terminated") +(def init-state "Initializing") +(def provisioning-state "Provisioning") +(def executing-state "Executing") +(def sending-report-state "SendingReports") +(def ready-state "Ready") +(def finalyzing-state "Finalizing") +(def done-state "Done") + +(def cancelled-state "Cancelled") +(def aborted-state "Aborted") +(def unknown-state "Unknown") (def valid-transitions {init-state [provisioning-state] @@ -32,9 +36,14 @@ executing-state [sending-report-state] sending-report-state [ready-state] ready-state [provisioning-state] - finalyzing-state [terminated-state] - terminated-state []}) + finalyzing-state [done-state] + done-state []}) + +(defn is-completed? [current-state] + (contains? #{cancelled-state aborted-state done-state unknown-state} current-state)) +(defn can-terminate? [current-state] + (contains? #{cancelled-state aborted-state done-state ready-state} current-state)) (defn get-next-state [current-state] (->> current-state diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj index bc27ee08c..052872771 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj @@ -87,13 +87,20 @@ deployment (set-deployment-attribute deployment-href "state" next-state)] (doseq [n (:nodes deployment)] (let [node-name (name (key n)) - multiplicity (read-string (get-in (val n) [:parameters :multiplicity :default-value] "1"))] + multiplicity (read-string (get-in (val n) [:parameters :multiplicity :value] "1"))] (doseq [i (range 1 (inc multiplicity))] (uzk/create-all (zdu/deployment-parameter-node-instance-complete-state-path deployment-href node-name i "state-complete") :persistent? true))))) (zdu/unlock-deployment deployment-href)) +(defn abort-deployment [deployment-href current-state] + (zdu/check-deployment-lock-and-throw! deployment-href) + (zdu/lock-deployment-path deployment-href) + (set-deployment-attribute deployment-href "abort" current-state) + (set-deployment-attribute deployment-href "state" dsm/aborted-state) + (zdu/unlock-deployment deployment-href)) + (defn create-deployment-parameter [deployment-parameter] (let [deployment-parameter (-> deployment-parameter u/strip-service-attrs @@ -136,6 +143,10 @@ (zdu/complete-node-instance-state merged) (when (zdu/all-nodes-completed-current-state? deployment-href) (move-deployment-next-state deployment-href value))) + "abort" (do + (zdu/check-deployment-lock-and-throw! deployment-href) + (uzk/set-data (zdu/deployment-parameter-path deployment-parameter) value) + (abort-deployment deployment-href value)) (uzk/set-data (zdu/deployment-parameter-path deployment-parameter) value)))) (db/edit deployment-parameter request))) @@ -148,9 +159,16 @@ :rules [{:principal user :type "USER" :right "VIEW"}]}}) + (create-deployment-parameter + {:deployment {:href deployment-href} :name "abort" :value state :type "deployment" + :acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal user + :type "USER" + :right "VIEW"}]}}) (doseq [n nodes] (let [node-name (name (key n)) - multiplicity (read-string (get-in (val n) [:parameters :multiplicity :default-value] "1"))] + multiplicity (read-string (get-in (val n) [:parameters :multiplicity :value] "1"))] (doseq [i (range 1 (inc multiplicity))] (create-deployment-parameter {:deployment {:href deployment-href} :node-name node-name :node-index i :type "node-instance" @@ -159,6 +177,13 @@ :rules [{:principal user :type "USER" :right "MODIFY"}]}}) + (create-deployment-parameter + {:deployment {:href deployment-href} :node-name node-name :node-index i :type "node-instance" + :name "abort" :value "" :acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal user + :type "USER" + :right "MODIFY"}]}}) (create-deployment-parameter {:deployment {:href deployment-href} :node-name node-name :node-index i :type "node-instance" :name "vmstate" :value "unknown" :acl {:owner {:principal "ADMIN" diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc index 8ab8891bc..13db7278e 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc @@ -6,7 +6,7 @@ [com.sixsq.slipstream.ssclj.util.spec :as su] [com.sixsq.slipstream.ssclj.resources.spec.common :as c])) -(s/def :cimi.deployment/id :cimi.core/nonblank-string) ;TODO enhance +(s/def :cimi.deployment/id :cimi.core/resource-href) (s/def :cimi.deployment/module-resource-uri :cimi.core/uri) (s/def :cimi.deployment/type #{"Run" "Orchestration" "Machine"}) ;TODO rename (s/def :cimi.deployment/category #{"Image" "Deployment"}) @@ -14,16 +14,16 @@ (s/def :cimi.deployment/end-time :cimi.core/timestamp) (s/def :cimi.deployment/last-state-change-time :cimi.core/timestamp) (s/def :cimi.deployment/mutable boolean?) -(s/def :cimi.deployment/state - #{"init" "provisioning" "executing" "sending report" "finalyzing" "terminated" "canceled" "done"}) +(s/def :cimi.deployment/keep-running boolean?) +(s/def :cimi.deployment/tags (s/coll-of string?)) +(s/def :cimi.deployment/state #{"Initializing" "Provisioning" "Executing" "SendingReports" "Ready" "Finalizing" "Done" + "Cancelled" "Aborted" "Unknown"}) (s/def :cimi.deployment.parameter/description string?) -(s/def :cimi.deployment.parameter/default-value string?) -(s/def :cimi.deployment.parameter/user-choice-value string?) +(s/def :cimi.deployment.parameter/value string?) (s/def :cimi.deployment/parameter (su/only-keys-maps {:opt-un [:cimi.deployment.parameter/description - :cimi.deployment.parameter/default-value - :cimi.deployment.parameter/user-choice-value]})) + :cimi.deployment.parameter/value]})) (s/def :cimi.deployment.node/cpu.nb :cimi.deployment/parameter) (s/def :cimi.deployment.node/ram.GB :cimi.deployment/parameter) @@ -45,15 +45,14 @@ (s/def :cimi.deployment.node/runtime-parameter (su/only-keys-maps {:opt-un [:cimi.deployment.parameter/description - :cimi.deployment.parameter/default-value - :cimi.deployment.parameter/user-choice-value + :cimi.deployment.parameter/value :cimi.deployment.runtime-parameter/mapped-to]})) (s/def :cimi.deployment/runtime-parameters (su/constrained-map keyword? :cimi.deployment.node/runtime-parameter)) -(s/def :cimi.deployment/node (su/only-keys-maps {:req-un [:cimi.deployment/parameters] - :opt-un [:cimi.deployment/runtime-parameters]})) +(s/def :cimi.deployment/node (su/only-keys-maps {:opt-un [:cimi.deployment/parameters + :cimi.deployment/runtime-parameters]})) (s/def :cimi.deployment/nodes (su/constrained-map keyword? :cimi.deployment/node)) @@ -62,10 +61,12 @@ :cimi.deployment/type :cimi.deployment/category :cimi.deployment/mutable - :cimi.deployment/nodes] + :cimi.deployment/keep-running + :cimi.deployment/nodes + :cimi.deployment/state] :opt-un [:cimi.deployment/start-time :cimi.deployment/end-time :cimi.deployment/last-state-change-time - :cimi.deployment/state]}) + :cimi.deployment/tags]}) (s/def :cimi/deployment (su/only-keys-maps c/common-attrs deployment-attrs)) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment/state_machine_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment/state_machine_test.clj index 442d7db24..4ef47e2ee 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment/state_machine_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment/state_machine_test.clj @@ -3,4 +3,15 @@ [com.sixsq.slipstream.ssclj.resources.deployment.state-machine :refer :all])) (deftest next-state - (is (= "executing" (get-next-state "provisioning")))) + (is (= executing-state (get-next-state provisioning-state)))) + +(deftest competed-run + (is (is-completed? done-state)) + (is (is-completed? cancelled-state)) + (is (not (is-completed? executing-state)))) + +(deftest can-terminate + (is (can-terminate? ready-state)) + (is (can-terminate? aborted-state)) + (is (can-terminate? cancelled-state)) + (is (not (can-terminate? executing-state)))) \ No newline at end of file diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj index 851340ced..e2aab5dff 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj @@ -34,16 +34,15 @@ :category "Deployment" :type "Orchestration" :mutable false - :nodes {:node1 {:parameters {:cloudservice {:description "p1 description" ;TODO only node name and multiplicity are being used for now from all these parameters - :default-value "abc" - :user-choice-value "ABC"} - :multiplicity {:default-value "2"}} - :runtime-parameters {:p1 {:description "p1 description" - :default-value "abc" - :user-choice-value "ABC" - :mapped-to "a"}}} - :node2 {:parameters {:cloudservice {:description "param1 description" - :default-value "abc"}}}}}) + :keep-running true + :nodes {:node1 {:parameters {:cloudservice {:description "p1 description" ;TODO only node name and multiplicity are being used for now from all these parameters + :value "abc"} + :multiplicity {:value "2"}} + :runtime-parameters {:p1 {:description "p1 description" + :value "abc" + :mapped-to "a"}}} + :node2 {:parameters {:cloudservice {:description "param1 description" + :value "abc"}}}}}) (deftest create-deployment @@ -280,4 +279,74 @@ (t/body->edn) (get-in [:response :body :state])))) + ))) + + +(deftest create-deployment-move-states-abort + + (let [session-admin-json (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "super ADMIN USER ANON")) + session-user (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "jane USER ANON"))] + + ;; adding, retrieving and deleting entry as user should succeed + (let [deployment-href (-> session-user + (request base-uri + :request-method :post + :body (json/write-str valid-entry)) + (t/body->edn) + (t/location)) + abs-uri (str p/service-context (u/de-camelcase deployment-href)) + abs-uri-deployment-parameter-state (str p/service-context dp/resource-url + "/" valid-entry-deployment-uuid "_state") + created-deployment (-> session-user + (request abs-uri) + (t/body->edn)) + start-uri (str p/service-context + (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) + started-deployment (-> session-user + (request start-uri) + (t/body->edn)) + update-deployment-parameter-state + (-> session-admin-json + (request abs-uri-deployment-parameter-state :request-method :put + :body (json/write-str {:value dsm/provisioning-state})) + (t/body->edn) + (t/is-status 200))] + + (-> session-admin-json + (request (str p/service-context (du/deployment-parameter-href + {:deployment {:href deployment-href} :node-name "node1" + :node-index 1 :name "state-complete"})) + :request-method :put :body (json/write-str {:value dsm/provisioning-state})) + (t/body->edn) + (t/is-status 200)) + (-> session-admin-json + (request (str p/service-context (du/deployment-parameter-href + {:deployment {:href deployment-href} :node-name "node1" + :node-index 2 :name "state-complete"})) + :request-method :put :body (json/write-str {:value dsm/provisioning-state})) + (t/body->edn) + (t/is-status 200)) + + (-> session-admin-json + (request (str p/service-context (du/deployment-parameter-href + {:deployment {:href deployment-href} :node-name "node2" + :node-index 1 :name "abort"})) + :request-method :put :body (json/write-str {:value "Error in node 1 abort the run"})) + (t/body->edn) + (t/is-status 200)) + + (is (= 1 (count (uzk/children + (zdu/deployment-state-path deployment-href))))) + + (is (= dsm/aborted-state (uzk/get-data (str zdu/separator deployment-href "/state")))) + + (is (= dsm/aborted-state (-> session-user + (request (str p/service-context deployment-href)) + (t/body->edn) + (get-in [:response :body :state])))) + ))) \ No newline at end of file From bead98da6da73c7f152672e6edc90ac2af560d3b Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Thu, 14 Sep 2017 10:10:36 +0200 Subject: [PATCH 39/46] fix deployment spec, add abort --- .../com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc index 13db7278e..76933abf5 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc @@ -18,6 +18,7 @@ (s/def :cimi.deployment/tags (s/coll-of string?)) (s/def :cimi.deployment/state #{"Initializing" "Provisioning" "Executing" "SendingReports" "Ready" "Finalizing" "Done" "Cancelled" "Aborted" "Unknown"}) +(s/def :cimi.deployment/abort string?) (s/def :cimi.deployment.parameter/description string?) (s/def :cimi.deployment.parameter/value string?) @@ -67,6 +68,7 @@ :opt-un [:cimi.deployment/start-time :cimi.deployment/end-time :cimi.deployment/last-state-change-time - :cimi.deployment/tags]}) + :cimi.deployment/tags + :cimi.deployment/abort]}) (s/def :cimi/deployment (su/only-keys-maps c/common-attrs deployment-attrs)) From 54d863c8d7d680ef73f2853642db3af70c3d0bbf Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Fri, 15 Sep 2017 17:55:17 +0200 Subject: [PATCH 40/46] new header auth for java, ssclj deployment template --- .../application/RootApplication.java | 15 +- .../slipstream/authn/HeaderAuthenticator.java | 121 +++ .../sixsq/slipstream/run/RunListResource.java | 14 +- .../com/sixsq/slipstream/run/RunResource.java | 15 + .../slipstream/ssclj/resources/deployment.clj | 55 +- .../ssclj/resources/deployment_std.clj | 113 +++ .../ssclj/resources/deployment_template.clj | 177 +++++ .../resources/deployment_template_std.clj | 59 ++ .../ssclj/resources/spec/deployment.cljc | 15 +- .../resources/spec/deployment_template.cljc | 36 + .../spec/deployment_template_std.cljc | 28 + .../resources/deployment_lifecycle_test.clj | 751 +++++++++++------- .../deployment_template_lifecycle_test.clj | 98 +++ .../ssclj/resources/lifecycle_test_utils.clj | 8 +- .../ssclj/resources/spec/deployment_test.cljc | 53 -- 15 files changed, 1172 insertions(+), 386 deletions(-) create mode 100644 jar-service/src/main/java/com/sixsq/slipstream/authn/HeaderAuthenticator.java create mode 100644 ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_std.clj create mode 100644 ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_template.clj create mode 100644 ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_template_std.clj create mode 100644 ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_template.cljc create mode 100644 ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_template_std.cljc create mode 100644 ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_template_lifecycle_test.clj delete mode 100644 ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/deployment_test.cljc diff --git a/jar-service/src/main/java/com/sixsq/slipstream/application/RootApplication.java b/jar-service/src/main/java/com/sixsq/slipstream/application/RootApplication.java index ce62e3aa9..75b284eb1 100644 --- a/jar-service/src/main/java/com/sixsq/slipstream/application/RootApplication.java +++ b/jar-service/src/main/java/com/sixsq/slipstream/application/RootApplication.java @@ -24,12 +24,7 @@ import com.sixsq.slipstream.action.ActionRouter; import com.sixsq.slipstream.attribute.AttributeRouter; -import com.sixsq.slipstream.authn.BasicAuthenticator; -import com.sixsq.slipstream.authn.CookieAuthenticator; -import com.sixsq.slipstream.authn.LoginResource; -import com.sixsq.slipstream.authn.LogoutResource; -import com.sixsq.slipstream.authn.RegistrationResource; -import com.sixsq.slipstream.authn.ResetPasswordResource; +import com.sixsq.slipstream.authn.*; import com.sixsq.slipstream.authz.SuperEnroler; import com.sixsq.slipstream.cloudusage.CloudUsageRouter; import com.sixsq.slipstream.configuration.Configuration; @@ -61,6 +56,7 @@ import com.sixsq.slipstream.resource.configuration.ServiceConfigurationResource; import com.sixsq.slipstream.resource.NuvlaboxAdminRouter; import com.sixsq.slipstream.resource.NuvlaboxAdminResource; +import com.sixsq.slipstream.run.RunResource; import com.sixsq.slipstream.run.RunRouter; import com.sixsq.slipstream.run.VmsRouter; import com.sixsq.slipstream.serviceinfo.ServiceInfoRouter; @@ -381,14 +377,21 @@ private Authenticators getAuthenticators(Application application) { Authenticator basicAuthenticator = new BasicAuthenticator(getContext()); basicAuthenticator.setEnroler(new SuperEnroler(application)); + Authenticator headerAuthenticator = new HeaderAuthenticator(getContext()); + headerAuthenticator.setEnroler(new SuperEnroler(application)); + Authenticator cookieAuthenticator = new CookieAuthenticator(getContext()); cookieAuthenticator.setOptional(true); cookieAuthenticator.setNext(basicAuthenticator); cookieAuthenticator.setEnroler(new SuperEnroler(application)); + basicAuthenticator.setOptional(true); + basicAuthenticator.setNext(headerAuthenticator); + authenticators.add(cookieAuthenticator); authenticators.add(basicAuthenticator); + authenticators.add(headerAuthenticator); return authenticators; } diff --git a/jar-service/src/main/java/com/sixsq/slipstream/authn/HeaderAuthenticator.java b/jar-service/src/main/java/com/sixsq/slipstream/authn/HeaderAuthenticator.java new file mode 100644 index 000000000..5653c8110 --- /dev/null +++ b/jar-service/src/main/java/com/sixsq/slipstream/authn/HeaderAuthenticator.java @@ -0,0 +1,121 @@ +package com.sixsq.slipstream.authn; + +/* + * +=================================================================+ + * SlipStream Server (WAR) + * ===== + * Copyright (C) 2013 SixSq Sarl (sixsq.com) + * ===== + * Licensed 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. + * -=================================================================- + */ + +import com.sixsq.slipstream.cookie.CookieUtils; +import com.sixsq.slipstream.exceptions.ConfigurationException; +import com.sixsq.slipstream.exceptions.ValidationException; +import com.sixsq.slipstream.util.RequestUtil; +import com.sixsq.slipstream.util.ResourceUriUtil; +import org.restlet.Context; +import org.restlet.Request; +import org.restlet.Response; +import org.restlet.data.MediaType; +import org.restlet.data.Reference; +import org.restlet.data.Status; +import org.restlet.engine.header.Header; +import org.restlet.security.User; +import org.restlet.util.Series; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +public class HeaderAuthenticator extends AuthenticatorBase { + + private static final Logger logger = Logger.getLogger(HeaderAuthenticator.class.getName()); + + public HeaderAuthenticator(Context context) { + super(context, false); + } + + @Override + protected boolean authenticate(Request request, Response response) { + + //Form headers = (Form) request.getAttributes().get("org.restlet.http.headers"); + //String username = headers.getFirstValue("slipstream-authn-info"); + + Series
series = (Series
) request.getAttributes().get("org.restlet.http.headers"); + String username = series.getFirst("slipstream-authn-info").getValue(); + + if (username != null && !username.isEmpty()) { + return handleValid(request, username); + } else { + return handleNotValid(request, response); + } + } + + private boolean handleValid(Request request, String username) { + + setClientInfo(request, username); + + com.sixsq.slipstream.persistence.User user = null; + try { + user = com.sixsq.slipstream.persistence.User.loadByName(username); + } catch (ConfigurationException e) { + return false; + } catch (ValidationException e) { + return false; + } + if (user == null) { + return false; + } + + setUserInRequest(user, request); + + return true; + } + + private boolean handleNotValid(Request request, Response response) { + CookieUtils.removeAuthnCookie(response); + + List supported = new ArrayList(); + supported.add(MediaType.APPLICATION_XML); + supported.add(MediaType.TEXT_HTML); + MediaType prefered = request.getClientInfo().getPreferredMediaType(supported); + + if (prefered != null && prefered.isCompatible(MediaType.TEXT_HTML)) { + Reference baseRef = ResourceUriUtil.getBaseRef(request); + + Reference redirectRef = new Reference(baseRef, LoginResource.getResourceRoot()); + redirectRef.setQuery("redirectURL=" + request.getResourceRef().getPath()); + + String absolutePath = RequestUtil.constructAbsolutePath(request, redirectRef.toString()); + + response.redirectTemporary(absolutePath); + } else { + response.setStatus(Status.CLIENT_ERROR_UNAUTHORIZED); + } + + return false; + } + + private String setClientInfo(Request request, String username) { + request.getClientInfo().setAuthenticated(true); + + logger.info("setClientInfo, username = '" + username + "'"); + + User user = new User(username); + request.getClientInfo().setUser(user); + return username; + } + +} diff --git a/jar-service/src/main/java/com/sixsq/slipstream/run/RunListResource.java b/jar-service/src/main/java/com/sixsq/slipstream/run/RunListResource.java index 38e46780f..7a4dd36e0 100644 --- a/jar-service/src/main/java/com/sixsq/slipstream/run/RunListResource.java +++ b/jar-service/src/main/java/com/sixsq/slipstream/run/RunListResource.java @@ -37,6 +37,8 @@ import com.sixsq.slipstream.persistence.*; import com.sixsq.slipstream.util.*; import org.hibernate.StaleObjectStateException; +import org.json.JSONObject; +import org.json.XML; import org.restlet.data.Form; import org.restlet.data.MediaType; import org.restlet.data.Status; @@ -170,13 +172,8 @@ public void createRun(Representation entity) run.store(); - launch(run); - setLastExecute(user); - Deployment deployment = new Deployment(run); - Deployment.post(deployment); - run.postEventCreated(); } catch (SlipStreamClientException ex) { @@ -350,13 +347,6 @@ private RunType parseType(Form form, Module module) { } } - private Run launch(Run run) throws SlipStreamException { - User user = getUser(); - user.addSystemParametersIntoUser(Configuration.getInstance().getParameters()); - slipstream.async.Launcher.launch(run, user); - return run; - } - private Run addCredentials(Run run) throws ConfigurationException, ServerExecutionEnginePluginException, ValidationException { diff --git a/jar-service/src/main/java/com/sixsq/slipstream/run/RunResource.java b/jar-service/src/main/java/com/sixsq/slipstream/run/RunResource.java index a07bcac83..474bd03b1 100644 --- a/jar-service/src/main/java/com/sixsq/slipstream/run/RunResource.java +++ b/jar-service/src/main/java/com/sixsq/slipstream/run/RunResource.java @@ -22,7 +22,9 @@ import javax.persistence.EntityManager; +import com.sixsq.slipstream.configuration.Configuration; import com.sixsq.slipstream.exceptions.*; +import com.sixsq.slipstream.persistence.User; import org.json.JSONObject; import org.json.XML; import org.restlet.data.MediaType; @@ -31,6 +33,7 @@ import org.restlet.representation.StringRepresentation; import org.restlet.resource.Delete; import org.restlet.resource.Get; +import org.restlet.resource.Post; import org.restlet.resource.ResourceException; import com.sixsq.slipstream.factory.RunFactory; @@ -162,6 +165,18 @@ private Run constructRun(EntityManager em) throws SlipStreamClientException { return run; } + private Run launch(Run run) throws SlipStreamException { + User user = getUser(); + user.addSystemParametersIntoUser(Configuration.getInstance().getParameters()); + slipstream.async.Launcher.launch(run, user); + return run; + } + + @Post + public void startRun() throws SlipStreamException { + launch(this.run); + } + @Delete public void terminate() { String errorMessage = "Failed terminating VMs"; diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj index 44298f5a5..c8e275a31 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj @@ -17,7 +17,8 @@ [com.sixsq.slipstream.db.impl :as db] [clojure.tools.logging :as log] [clojure.core.async :as async] - [clj-time.core :as time]) + [clj-time.core :as time] + [com.sixsq.slipstream.ssclj.util.log :as logu]) (:import (clojure.lang ExceptionInfo))) (def ^:const resource-name du/deployment-resource-name) @@ -32,6 +33,8 @@ (def ^:const collection-uri (str c/slipstream-schema-uri collection-name)) +(def ^:const create-uri (str c/slipstream-schema-uri resource-name "Create")) + (def collection-acl {:owner {:principal "ADMIN" :type "ROLE"} :rules [{:principal "USER" @@ -50,10 +53,42 @@ (defmethod crud/add-acl resource-uri [resource request] (a/add-acl resource request)) + ;; -;; CRUD operations +;; validate create requests for subclasses of users +;; different create (registration) requests may take different inputs +;; +(defn dispatch-on-registration-method [resource] + (get-in resource [:deploymentTemplate :method])) + +(defmulti create-validate-subtype dispatch-on-registration-method) + +(defmethod create-validate-subtype :default + [resource] + (logu/log-and-throw-400 "missing or invalid DeploymentTemplate reference")) + +(defmethod crud/validate create-uri + [resource] + (create-validate-subtype resource)) + ;; +;; template processing +;; + +(defn dispatch-conversion + [resource _] + (:method resource)) + +(defmulti tpl->deployment dispatch-conversion) + +;; default implementation throws if the registration method is unknown +(defmethod tpl->deployment :default + [resource request] + (logu/log-and-throw-400 "missing or invalid DeploymentTemplate reference")) +;; +;; CRUD operations +;; (defmethod crud/new-identifier resource-name [json _] @@ -71,9 +106,21 @@ response (db/add resource-name (crud/validate new-deployment) {})] response)) + (defmethod crud/add resource-name - [request] - (add-impl request)) + [{:keys [body] :as request}] + (let [idmap {:identity (:identity request)} + desc-attrs (u/select-desc-keys body) + {:keys [id] :as body} (-> body + (assoc :resourceURI create-uri) + (update-in [:deploymentTemplate] dissoc :method) ;; forces use of template reference + (std-crud/resolve-hrefs idmap) + (update-in [:deploymentTemplate] merge desc-attrs) ;; validate desc attrs + (crud/validate) + (:deploymentTemplate) + (tpl->deployment request) + (merge desc-attrs))] ;; ensure desc attrs are added + (add-impl (assoc request :id id :body body)))) (def retrieve-impl (std-crud/retrieve-fn resource-name)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_std.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_std.clj new file mode 100644 index 000000000..df569799c --- /dev/null +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_std.clj @@ -0,0 +1,113 @@ +(ns com.sixsq.slipstream.ssclj.resources.deployment-std + (:require + [com.sixsq.slipstream.ssclj.resources.spec.deployment] + [com.sixsq.slipstream.ssclj.resources.spec.deployment-template-std] + [com.sixsq.slipstream.ssclj.resources.deployment :as d] + [com.sixsq.slipstream.ssclj.resources.deployment-template-std :as dtpl] + [com.sixsq.slipstream.ssclj.resources.common.utils :as u])) + +;; +;; validate the create resource +;; +(def create-validate-fn (u/create-spec-validation-fn :cimi/deployment-template.std-create)) +(defmethod d/create-validate-subtype dtpl/method + [resource] + (create-validate-fn resource)) + +(def deplo-body {:id "deployment/0e0fca32-1bbb-40e3-b2cd-2d97a318694a", + :state "Done", + :type "Run", + :category "Image", + :module-resource-uri "module/apps/WordPress/wordpress/3842", + :mutable false, + :nodes + {:machine + {:runtime-parameters + {:admin_password + {:description "admin password", :value "8rsBZBM659jK"}, + :wordpress_title + {:description "Title (name) to give to the WordPress instance", + :value "Change Me Please 2"}, + :scale.iaas.done + {:description + "Orchestrator sets to 'true' after scaling the node instance", + :value "false"}, + :vmstate + {:description "State of the VM, according to the cloud layer", + :value "Unknown"}, + :pre.scale.done + {:description + "Node instance sets to 'true' after running pre-scale script", + :value "false"}, + :disk.attached.device + {:description + "Attached device name after the VM's vertical scaling", + :value nil}, + :instanceid {:description "Cloud instance id", :value "23"}, + :extra.disk.volatile + {:description "Volatile extra disk in GB", :value nil}, + :statecustom + {:description "Custom state", :value "WordPress ready to go!"}, + :hostname + {:description "hostname/ip of the image", :value "172.16.0.13"}, + :abort + {:description "Machine abort flag, set when aborting", :value nil}, + :nuvlabox-bertil-ohlin.ram + {:description "Amount of RAM, in GB", :value "0.5"}, + :image.id {:description "Cloud image id", :value "8"}, + :scale.state + {:description "Defined scalability state", :value "operational"}, + :disk.detach.device + {:description + "Name of the block device to detach from the VM during vertical scaling", + :value nil}, + :nuvlabox-bertil-ohlin.cpu + {:description "Number of CPUs (i.e. virtual cores)", :value "1"}, + :is.orchestrator + {:description "True if it's an orchestrator", :value "false"}, + :nuvlabox-bertil-ohlin.network.specific.name + {:description "Network name", :value nil}, + :admin_email + {:description "admin email", :value "admin@example.com"}, + :mysql_password + {:description "MySQL password", :value "AX9ytTh2vWF4"}, + :url.ssh + {:description "SSH URL to connect to virtual machine", + :value "ssh://root@172.16.0.13"}, + :complete + {:description "'true' when current state is completed", + :value "false"}, + :network {:description "Network type", :value "Public"}, + :url.service + {:description "Optional service URL for virtual machine", + :value "http://172.16.0.13:8080"}, + :image.platform + {:description "Platform (eg: ubuntu, windows)", :value "ubuntu"}, + :nuvlabox-bertil-ohlin.custom.vm.template + {:description "Additional custom VM template", :value nil}, + :disk.attach.size + {:description + "Size of the extra disk to attach to the VM during vertical scaling", + :value nil}, + :nuvlabox-bertil-ohlin.is.firewall + {:description + "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + :value "false"}}, + :parameters + {:run-build-recipes + {:description + "Define if the SlipStream executor should run build recipes.", + :value "false"}, + :cloudservice {:description "", :value "nuvlabox-bertil-ohlin"}}}}}) + +;; +;; transform template into deployment resource +;; just strips method attribute and updates the resource URI +;; +(defmethod d/tpl->deployment dtpl/method + [resource request] + (-> deplo-body + (dissoc :method) + (assoc :resourceURI d/resource-uri)) + ) + diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_template.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_template.clj new file mode 100644 index 000000000..19db6221e --- /dev/null +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_template.clj @@ -0,0 +1,177 @@ +(ns com.sixsq.slipstream.ssclj.resources.deployment-template + (:require + [clojure.spec.alpha :as s] + [clojure.tools.logging :as log] + [com.sixsq.slipstream.ssclj.resources.spec.deployment-template] + [com.sixsq.slipstream.ssclj.resources.common.schema :as c] + [com.sixsq.slipstream.ssclj.resources.common.crud :as crud] + [com.sixsq.slipstream.ssclj.resources.common.utils :as u] + [com.sixsq.slipstream.auth.acl :as a] + [com.sixsq.slipstream.util.response :as r]) + (:import (clojure.lang ExceptionInfo))) + +(def ^:const resource-tag :deploymentTemplates) + +(def ^:const resource-name "DeploymentTemplate") + +(def ^:const resource-url (u/de-camelcase resource-name)) + +(def ^:const collection-name "DeploymentTemplateCollection") + +(def ^:const resource-uri (str c/slipstream-schema-uri resource-name)) + +(def ^:const collection-uri (str c/slipstream-schema-uri collection-name)) + +(def collection-acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal "USER" + :type "ROLE" + :right "VIEW"}]}) + +;; +;; atom to keep track of the loaded DeploymentTemplate resources +;; +(def templates (atom {})) +(def descriptions (atom {})) + +(defn collection-wrapper-fn + "Specialized version of this function that removes the adding + of operations to the collection and entries. These are already + part of the stored resources." + [resource-name collection-acl collection-uri collection-key] + (fn [request entries] + (let [skeleton {:acl collection-acl + :resourceURI collection-uri + :id (u/de-camelcase resource-name)}] + (-> skeleton + (crud/set-operations request) + (assoc collection-key entries))))) + +(defn complete-resource + "Completes the given document with server-managed information: + resourceURI, timestamps, and operations. NOTE: The subtype + MUST provide an ACL for the template." + [{:keys [method] :as resource}] + (when method + (let [id (str resource-url "/" method) + href (str id "/describe") + ops [{:rel (:describe c/action-uri) :href href}]] + (-> resource + (merge {:id id + :resourceURI resource-uri + :operations ops}) + u/update-timestamps)))) + +(defn register + "Registers a given DeploymentTemplate resource and its description + with the server. The resource document (resource) and the description + (desc) must be valid. The key will be used to create the id of + the resource as 'deployment-template/key'." + [resource desc] + (when-let [{:keys [id] :as full-resource} (complete-resource resource)] + (swap! templates assoc id full-resource) + (log/info "loaded DeploymentTemplate" id) + (when desc + (let [acl (:acl full-resource) + full-desc (assoc desc :acl acl)] + (swap! descriptions assoc id full-desc)) + (log/info "loaded DeploymentTemplate description" id)))) + +;; +;; schemas +;; + +(def DeploymentTemplateDescription + (merge c/CommonParameterDescription + {:method {:displayName "Module reference URI" + :category "general" + :description "module to be used for the creation of a deployment" + :type "string" + :mandatory true + :readOnly true + :order 10}})) +;; +;; multimethods for validation +;; + +(defmulti validate-subtype + "Validates the given resource against the specific + DeploymentTemplate subtype schema." + :method) + +(defmethod validate-subtype :default + [resource] + (throw (ex-info (str "unknown DeploymentTemplate type: " (:method resource)) resource))) + +(defmethod crud/validate + resource-uri + [resource] + (validate-subtype resource)) + +;; +;; CRUD operations +;; + +(defmethod crud/add resource-name + [request] + (throw (r/ex-bad-method request))) + +(defmethod crud/retrieve resource-name + [{{uuid :uuid} :params :as request}] + (try + (let [id (str resource-url "/" uuid)] + (-> (get @templates id) + (a/can-view? request) + (r/json-response))) + (catch ExceptionInfo ei + (ex-data ei)))) + +;; must override the default implementation so that the +;; data can be pulled from the atom rather than the database +(defmethod crud/retrieve-by-id resource-url + [id] + (try + (get @templates id) + (catch ExceptionInfo ei + (ex-data ei)))) + +(defmethod crud/edit resource-name + [request] + (throw (r/ex-bad-method request))) + +(defmethod crud/delete resource-name + [request] + (throw (r/ex-bad-method request))) + +(defn- viewable? [request {:keys [acl] :as entry}] + (try + (a/can-view? {:acl acl} request) + (catch Exception _ + false))) + +(defmethod crud/query resource-name + [request] + (a/can-view? {:acl collection-acl} request) + (let [wrapper-fn (collection-wrapper-fn resource-name collection-acl collection-uri resource-tag) + entries (or (filter (partial viewable? request) (vals @templates)) []) + ;; FIXME: At least the paging options should be supported. + options (select-keys request [:identity :query-params :cimi-params :deployment-name :deployment-roles]) + count-before-pagination (count entries) + wrapped-entries (wrapper-fn request entries) + entries-and-count (assoc wrapped-entries :count count-before-pagination)] + (r/json-response entries-and-count))) + +;; +;; actions +;; +(defmethod crud/do-action [resource-url "describe"] + [{{uuid :uuid} :params :as request}] + (try + (let [id (str resource-url "/" uuid)] + (-> (get @descriptions id) + (a/can-view? request) + (r/json-response))) + (catch ExceptionInfo ei + (ex-data ei)))) + + diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_template_std.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_template_std.clj new file mode 100644 index 000000000..9e9d682bf --- /dev/null +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_template_std.clj @@ -0,0 +1,59 @@ +(ns com.sixsq.slipstream.ssclj.resources.deployment-template-std + (:require + [clojure.spec.alpha :as s] + [com.sixsq.slipstream.ssclj.resources.deployment-template :as p] + [com.sixsq.slipstream.ssclj.resources.spec.deployment-template] + [com.sixsq.slipstream.ssclj.resources.spec.deployment-template-std] + [com.sixsq.slipstream.ssclj.resources.common.schema :as c] + [com.sixsq.slipstream.ssclj.resources.common.utils :as u])) + +(def ^:const method "standard") + +(def resource-acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal "ADMIN" + :type "ROLE" + :right "VIEW"} + {:principal "USER" + :type "ROLE" + :right "VIEW"} + ]}) + +;; +;; resource +;; +(def ^:const resource + {:method method + :name "Standard deployment" + :description "Direct creation of deployment" + :module "module" + :acl resource-acl}) + +;; +;; description +;; +(def ^:const desc + (merge p/DeploymentTemplateDescription + {:module {:displayName "Module" + :category "general" + :description "module" + :type "string" + :mandatory true + :readOnly false + :order 20}})) + +;; +;; initialization: register this User template +;; +(defn initialize + [] + (p/register resource desc)) + +;; +;; multimethods for validation +;; + +(def validate-fn (u/create-spec-validation-fn :cimi/deployment-template.std)) +(defmethod p/validate-subtype method + [resource] + (validate-fn resource)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc index 76933abf5..7b347e543 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc @@ -4,7 +4,8 @@ [clojure.spec.gen.alpha :as gen] [clojure.string :as str] [com.sixsq.slipstream.ssclj.util.spec :as su] - [com.sixsq.slipstream.ssclj.resources.spec.common :as c])) + [com.sixsq.slipstream.ssclj.resources.spec.common :as c] + [clojure.spec.alpha :as s])) (s/def :cimi.deployment/id :cimi.core/resource-href) (s/def :cimi.deployment/module-resource-uri :cimi.core/uri) @@ -21,7 +22,7 @@ (s/def :cimi.deployment/abort string?) (s/def :cimi.deployment.parameter/description string?) -(s/def :cimi.deployment.parameter/value string?) +(s/def :cimi.deployment.parameter/value (s/nilable string?)) (s/def :cimi.deployment/parameter (su/only-keys-maps {:opt-un [:cimi.deployment.parameter/description :cimi.deployment.parameter/value]})) @@ -32,6 +33,7 @@ (s/def :cimi.deployment.node/multiplicity :cimi.deployment/parameter) (s/def :cimi.deployment.node/max-provisioning-failures :cimi.deployment/parameter) (s/def :cimi.deployment.node/cloudservice :cimi.deployment/parameter) +(s/def :cimi.deployment.node/run-build-recipes :cimi.deployment/parameter) (s/def :cimi.deployment/parameters (su/only-keys-maps @@ -40,9 +42,10 @@ :cimi.deployment.node/max-provisioning-failures :cimi.deployment.node/cpu.nb :cimi.deployment.node/ram.GB - :cimi.deployment.node/disk.GB]})) + :cimi.deployment.node/disk.GB + :cimi.deployment.node/run-build-recipes]})) -(s/def :cimi.deployment.runtime-parameter/mapped-to :cimi.core/nonblank-string) +(s/def :cimi.deployment.runtime-parameter/mapped-to (s/coll-of string?)) (s/def :cimi.deployment.node/runtime-parameter (su/only-keys-maps {:opt-un [:cimi.deployment.parameter/description @@ -62,13 +65,13 @@ :cimi.deployment/type :cimi.deployment/category :cimi.deployment/mutable - :cimi.deployment/keep-running :cimi.deployment/nodes :cimi.deployment/state] :opt-un [:cimi.deployment/start-time :cimi.deployment/end-time :cimi.deployment/last-state-change-time :cimi.deployment/tags - :cimi.deployment/abort]}) + :cimi.deployment/abort + :cimi.deployment/keep-running]}) (s/def :cimi/deployment (su/only-keys-maps c/common-attrs deployment-attrs)) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_template.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_template.cljc new file mode 100644 index 000000000..58da230f3 --- /dev/null +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_template.cljc @@ -0,0 +1,36 @@ +(ns com.sixsq.slipstream.ssclj.resources.spec.deployment-template + (:require + [clojure.spec.alpha :as s] + [clojure.spec.gen.alpha :as gen] + [clojure.string :as str] + [com.sixsq.slipstream.ssclj.util.spec :as su] + [com.sixsq.slipstream.ssclj.resources.spec.common :as c])) + +;; All deployment templates must indicate the method used to create the deployment. +(s/def :cimi.deployment-template/method :cimi.core/identifier) + +(def deployment-template-regex #"^deployment-template/[a-zA-Z0-9]([a-zA-Z0-9_-]*[a-zA-Z0-9])?$") +(s/def :cimi.deployment-template/href (s/and string? #(re-matches deployment-template-regex %))) + +;; +;; Keys specifications for deploymentTemplate resources. +;; As this is a "base class" for deploymentTemplate resources, there +;; is no sense in defining map resources for the resource itself. +;; + +(def deployment-template-keys-spec {:req-un [:cimi.deployment-template/method]}) + +(def deployment-template-keys-spec-opt {:opt-un [:cimi.deployment-template/method]}) + +(def resource-keys-spec + (su/merge-keys-specs [c/common-attrs + deployment-template-keys-spec])) + +(def create-keys-spec + (su/merge-keys-specs [c/create-attrs])) + +;; subclasses MUST provide the href to the template to use +(def template-keys-spec + (su/merge-keys-specs [c/template-attrs + deployment-template-keys-spec-opt])) + diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_template_std.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_template_std.cljc new file mode 100644 index 000000000..1ecd2571e --- /dev/null +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment_template_std.cljc @@ -0,0 +1,28 @@ +(ns com.sixsq.slipstream.ssclj.resources.spec.deployment-template-std + (:require + [clojure.spec.alpha :as s] + [com.sixsq.slipstream.ssclj.util.spec :as su] + [com.sixsq.slipstream.ssclj.resources.spec.deployment-template :as ps])) + +(s/def :cimi.deployment-template.std/module :cimi.core/nonblank-string) + +(def deployment-template-keys-spec-req + {:req-un [:cimi.deployment-template.std/module]}) + +(def deployment-template-create-keys-spec-req + {:req-un [:cimi.deployment-template.std/module]}) + +;; Defines the contents of the std deploymentTemplate resource itself. +(s/def :cimi/deployment-template.std + (su/only-keys-maps ps/resource-keys-spec + deployment-template-keys-spec-req)) + +;; Defines the contents of the std template used in a create resource. +;; NOTE: The name must match the key defined by the resource, :deploymentTemplate here. +(s/def :cimi.deployment-template.std/deploymentTemplate + (su/only-keys-maps ps/template-keys-spec + deployment-template-create-keys-spec-req)) + +(s/def :cimi/deployment-template.std-create + (su/only-keys-maps ps/create-keys-spec + {:opt-un [:cimi.deployment-template.std/deploymentTemplate]})) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj index e2aab5dff..46bc815ca 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj @@ -5,6 +5,7 @@ [peridot.core :refer :all] [ring.util.codec :as rc] [com.sixsq.slipstream.ssclj.resources.deployment :refer :all] + [com.sixsq.slipstream.ssclj.resources.deployment-template :as dt] [com.sixsq.slipstream.ssclj.resources.deployment-parameter :as dp] [com.sixsq.slipstream.ssclj.resources.lifecycle-test-utils :as t] [com.sixsq.slipstream.ssclj.middleware.authn-info-header :refer [authn-info-header]] @@ -14,7 +15,10 @@ [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] [com.sixsq.slipstream.ssclj.resources.zk.deployment.utils :as zdu] [com.sixsq.slipstream.ssclj.resources.deployment.utils :as du] - [com.sixsq.slipstream.ssclj.resources.deployment.state-machine :as dsm])) + [com.sixsq.slipstream.ssclj.resources.deployment.state-machine :as dsm] + [com.sixsq.slipstream.ssclj.resources.deployment-template-std :as std] + [com.sixsq.slipstream.ssclj.resources.lifecycle-test-utils :as ltu] + [com.sixsq.slipstream.ssclj.resources.common.dynamic-load :as dyn])) (use-fixtures :once t/setup-embedded-zk) @@ -25,6 +29,14 @@ (defn ring-app [] (t/make-ring-app (t/concat-routes routes/final-routes))) +;; initialize must to called to pull in SessionTemplate test examples +(dyn/initialize) + +(defn strip-unwanted-attrs [m] + (let [unwanted #{:id :resourceURI :acl :operations + :created :updated :name :description}] + (into {} (remove #(unwanted (first %)) m)))) + (def valid-entry-deployment-uuid "dfd34916-6ede-47f7-aaeb-a30ddecbba5c") (def valid-entry @@ -44,309 +56,446 @@ :node2 {:parameters {:cloudservice {:description "param1 description" :value "abc"}}}}}) -(deftest create-deployment - (let [session-admin-json (-> (session (ring-app)) - (content-type "application/json") - (header authn-info-header "super ADMIN USER ANON")) - session-admin-form (-> (session (ring-app)) - (content-type "application/x-www-form-urlencoded") - (header authn-info-header "super ADMIN USER ANON")) +(deftest lifecycle + (let [href (str dt/resource-url "/" std/method) + template-url (str p/service-context dt/resource-url "/" std/method) + session-admin (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "root ADMIN")) session-user (-> (session (ring-app)) (content-type "application/json") (header authn-info-header "jane USER ANON")) session-anon (-> (session (ring-app)) - (content-type "application/json"))] - - ;; adding, retrieving and deleting entry as user should succeed - (let [deployment-href (-> session-user - (request base-uri - :request-method :post - :body (json/write-str valid-entry)) - (t/body->edn) - (t/is-status 201) - (t/location)) - abs-uri (str p/service-context (u/de-camelcase deployment-href)) - created-deployment (-> session-user - (request abs-uri) - (t/body->edn) - (t/is-status 200))] - - (is (not (uzk/exists (str zdu/separator deployment-href))))))) - - -(deftest start-deployment - - (let [session-admin-json (-> (session (ring-app)) - (content-type "application/json") - (header authn-info-header "super ADMIN USER ANON")) - session-admin-form (-> (session (ring-app)) - (content-type "application/x-www-form-urlencoded") - (header authn-info-header "super ADMIN USER ANON")) - session-user (-> (session (ring-app)) - (content-type "application/json") - (header authn-info-header "jane USER ANON")) - session-anon (-> (session (ring-app)) - (content-type "application/json"))] - - ;; adding, retrieving and deleting entry as user should succeed - (let [deployment-href (-> session-user - (request base-uri - :request-method :post - :body (json/write-str valid-entry)) - (t/body->edn) - (t/is-status 201) - (t/location)) - abs-uri (str p/service-context (u/de-camelcase deployment-href)) - created-deployment (-> session-user - (request abs-uri) - (t/body->edn) - (t/is-status 200)) - start-uri (str p/service-context - (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) - started-deployment (-> session-user - (request start-uri) - (t/body->edn) - (t/is-status 200)) - ] - - (is (not (get-in created-deployment [:body :start-time]))) - (is (get-in started-deployment [:response :body :start-time])) - - (is (= dsm/init-state (get-in started-deployment [:response :body :state]))) - - (are [expected value] - (= expected value) - dsm/init-state (uzk/get-data (str zdu/separator deployment-href "/state")) - "unknown" (uzk/get-data - (str zdu/separator deployment-href "/" zdu/nodes-name "/node2/1/" "vmstate")))))) - -(deftest create-deployment-update-deployment-state - - (let [session-admin-json (-> (session (ring-app)) - (content-type "application/json") - (header authn-info-header "super ADMIN USER ANON")) - session-user (-> (session (ring-app)) - (content-type "application/json") - (header authn-info-header "jane USER ANON"))] - - ;; adding, retrieving and deleting entry as user should succeed - (let [deployment-href (-> session-user - (request base-uri - :request-method :post - :body (json/write-str valid-entry)) - (t/body->edn) - (t/is-status 201) - (t/location)) - abs-uri (str p/service-context (u/de-camelcase deployment-href)) - abs-uri-deployment-parameter-state (str p/service-context dp/resource-url - "/" valid-entry-deployment-uuid "_state") - created-deployment (-> session-user - (request abs-uri) - (t/body->edn) - (t/is-status 200)) - start-uri (str p/service-context - (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) - started-deployment (-> session-user - (request start-uri) - (t/body->edn) - (t/is-status 200)) - update-deployment-parameter-state - (-> session-user - (request abs-uri-deployment-parameter-state :request-method :put - :body (json/write-str {:value dsm/provisioning-state})) - (t/body->edn) - (t/is-status 403)) - update-deployment-parameter-state - (-> session-admin-json - (request abs-uri-deployment-parameter-state :request-method :put - :body (json/write-str {:value dsm/provisioning-state})) - (t/body->edn) - (t/is-status 200)) - provisioning-deployment (-> session-user - (request start-uri) - (t/body->edn) - (t/is-status 200))] - - (is (= dsm/provisioning-state (get-in provisioning-deployment [:response :body :state]))) - - (is (= dsm/provisioning-state (uzk/get-data (str zdu/separator deployment-href "/state")))) - ))) - -(deftest create-deployment-move-states - - (let [session-admin-json (-> (session (ring-app)) - (content-type "application/json") - (header authn-info-header "super ADMIN USER ANON")) - session-user (-> (session (ring-app)) (content-type "application/json") - (header authn-info-header "jane USER ANON"))] - - ;; adding, retrieving and deleting entry as user should succeed - (let [deployment-href (-> session-user - (request base-uri - :request-method :post - :body (json/write-str valid-entry)) - (t/body->edn) - (t/location)) - abs-uri (str p/service-context (u/de-camelcase deployment-href)) - abs-uri-deployment-parameter-state (str p/service-context dp/resource-url - "/" valid-entry-deployment-uuid "_state") - created-deployment (-> session-user - (request abs-uri) - (t/body->edn)) - start-uri (str p/service-context - (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) - started-deployment (-> session-user - (request start-uri) - (t/body->edn)) - update-deployment-parameter-state - (-> session-admin-json - (request abs-uri-deployment-parameter-state :request-method :put - :body (json/write-str {:value dsm/provisioning-state})) - (t/body->edn) - (t/is-status 200)) - - provisioning-deployment (-> session-user - (request start-uri) - (t/body->edn) - (t/is-status 200))] - (is (= dsm/provisioning-state (get-in provisioning-deployment [:response :body :state]))) - - (is (= dsm/provisioning-state (uzk/get-data (str zdu/separator deployment-href "/state")))) - - (-> session-admin-json - (request (str p/service-context (du/deployment-parameter-href - {:deployment {:href deployment-href} :node-name "node1" - :node-index 1 :name "state-complete"})) - :request-method :put :body (json/write-str {:value dsm/provisioning-state})) - (t/body->edn) - (t/is-status 200)) - (-> session-admin-json - (request (str p/service-context (du/deployment-parameter-href - {:deployment {:href deployment-href} :node-name "node1" - :node-index 2 :name "state-complete"})) - :request-method :put :body (json/write-str {:value dsm/provisioning-state})) - (t/body->edn) - (t/is-status 200)) - - (is (= 1 (count (uzk/children - (zdu/deployment-state-path deployment-href))))) - - (-> session-admin-json - (request (str p/service-context (du/deployment-parameter-href - {:deployment {:href deployment-href} :node-name "node2" - :node-index 1 :name "state-complete"})) - :request-method :put :body (json/write-str {:value dsm/provisioning-state})) - (t/body->edn) - (t/is-status 200)) - - (is (= dsm/executing-state (uzk/get-data (str zdu/separator deployment-href "/state")))) - - (is (= dsm/executing-state (-> session-user - (request (str p/service-context deployment-href)) - (t/body->edn) - (get-in [:response :body :state])))) - - (is (= 3 (count (uzk/children - (zdu/deployment-state-path deployment-href))))) - - (-> session-admin-json - (request (str p/service-context (du/deployment-parameter-href - {:deployment {:href deployment-href} :node-name "node1" - :node-index 1 :name "state-complete"})) - :request-method :put :body (json/write-str {:value dsm/executing-state})) - (t/body->edn) - (t/is-status 200)) - (-> session-admin-json - (request (str p/service-context (du/deployment-parameter-href - {:deployment {:href deployment-href} :node-name "node1" - :node-index 2 :name "state-complete"})) - :request-method :put :body (json/write-str {:value dsm/executing-state})) - (t/body->edn) - (t/is-status 200)) - - (-> session-admin-json - (request (str p/service-context (du/deployment-parameter-href - {:deployment {:href deployment-href} :node-name "node2" - :node-index 1 :name "state-complete"})) - :request-method :put :body (json/write-str {:value dsm/executing-state})) - (t/body->edn) - (t/is-status 200)) - - (is (= dsm/sending-report-state (-> session-user - (request (str p/service-context deployment-href)) - (t/body->edn) - (get-in [:response :body :state])))) - - ))) - - -(deftest create-deployment-move-states-abort - - (let [session-admin-json (-> (session (ring-app)) - (content-type "application/json") - (header authn-info-header "super ADMIN USER ANON")) - session-user (-> (session (ring-app)) - (content-type "application/json") - (header authn-info-header "jane USER ANON"))] - - ;; adding, retrieving and deleting entry as user should succeed - (let [deployment-href (-> session-user - (request base-uri - :request-method :post - :body (json/write-str valid-entry)) - (t/body->edn) - (t/location)) - abs-uri (str p/service-context (u/de-camelcase deployment-href)) - abs-uri-deployment-parameter-state (str p/service-context dp/resource-url - "/" valid-entry-deployment-uuid "_state") - created-deployment (-> session-user - (request abs-uri) - (t/body->edn)) - start-uri (str p/service-context - (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) - started-deployment (-> session-user - (request start-uri) - (t/body->edn)) - update-deployment-parameter-state - (-> session-admin-json - (request abs-uri-deployment-parameter-state :request-method :put - :body (json/write-str {:value dsm/provisioning-state})) - (t/body->edn) - (t/is-status 200))] - - (-> session-admin-json - (request (str p/service-context (du/deployment-parameter-href - {:deployment {:href deployment-href} :node-name "node1" - :node-index 1 :name "state-complete"})) - :request-method :put :body (json/write-str {:value dsm/provisioning-state})) - (t/body->edn) - (t/is-status 200)) - (-> session-admin-json - (request (str p/service-context (du/deployment-parameter-href - {:deployment {:href deployment-href} :node-name "node1" - :node-index 2 :name "state-complete"})) - :request-method :put :body (json/write-str {:value dsm/provisioning-state})) - (t/body->edn) - (t/is-status 200)) - - (-> session-admin-json - (request (str p/service-context (du/deployment-parameter-href - {:deployment {:href deployment-href} :node-name "node2" - :node-index 1 :name "abort"})) - :request-method :put :body (json/write-str {:value "Error in node 1 abort the run"})) - (t/body->edn) - (t/is-status 200)) - - (is (= 1 (count (uzk/children - (zdu/deployment-state-path deployment-href))))) - - (is (= dsm/aborted-state (uzk/get-data (str zdu/separator deployment-href "/state")))) - - (is (= dsm/aborted-state (-> session-user - (request (str p/service-context deployment-href)) - (t/body->edn) - (get-in [:response :body :state])))) - - ))) \ No newline at end of file + (header authn-info-header "unknown ANON")) + template (-> session-admin + (request template-url) + (ltu/body->edn) + (ltu/is-status 200) + (get-in [:response :body])) + + no-href-create {:deploymentTemplate (strip-unwanted-attrs (assoc template + :module "nom/module"))} + href-create {:deploymentTemplate {:href href + :module "nom/module"}} + invalid-create (assoc-in href-create [:deploymentTemplate :href] "deployment-template/unknown-template")] + + ;; admin user collection query should succeed but be empty (no deployments created yet) + ;(-> session-admin + ; (request base-uri) + ; (ltu/body->edn) + ; (ltu/is-status 200) + ; (ltu/is-count zero?) + ; (ltu/is-operation-present "add") + ; (ltu/is-operation-absent "delete") + ; (ltu/is-operation-absent "edit")) + ; + ;;; create a new deployment as administrator; fail without reference + ;(-> session-admin + ; (request base-uri + ; :request-method :post + ; :body (json/write-str no-href-create)) + ; (ltu/body->edn) + ; (ltu/is-status 400)) + ; + ;;; anonymous create must fail + ;(-> session-anon + ; (request base-uri + ; :request-method :post + ; :body (json/write-str href-create)) + ; (ltu/body->edn) + ; (ltu/is-status 403)) + ; + ;;; anonymous create without template reference fails + ;(-> session-anon + ; (request base-uri + ; :request-method :post + ; :body (json/write-str no-href-create)) + ; (ltu/body->edn) + ; (ltu/is-status 400)) + ; + ;;; admin create with invalid template fails + ;(-> session-admin + ; (request base-uri + ; :request-method :post + ; :body (json/write-str invalid-create)) + ; (ltu/body->edn) + ; (ltu/is-status 400)) + + ;; create a deployment via admin + (let [create-req href-create + resp (-> session-admin + (request base-uri + :request-method :post + :body (json/write-str create-req)) + (ltu/body->edn) + (ltu/is-status 201)) + id (get-in resp [:response :body :resource-id]) + uri (-> resp + (ltu/location)) + abs-uri (str p/service-context (u/de-camelcase uri))] + + ;; admin should be able to see, edit, and delete deployment + (-> session-admin + (request abs-uri) + (ltu/body->edn) + (ltu/is-status 200) + (ltu/is-operation-present "delete") + (ltu/is-operation-absent "edit")) + + (-> session-user + (request abs-uri) + (ltu/body->edn) + (ltu/is-status 403) + (ltu/is-operation-absent "delete") + (ltu/is-operation-absent "edit")) + + ;; admin can delete resource + (-> session-admin + (request abs-uri + :request-method :delete) + (ltu/body->edn) + (ltu/is-status 200))) + (let [create-req href-create + resp (-> session-user + (request base-uri + :request-method :post + :body (json/write-str create-req)) + (ltu/body->edn) + (ltu/is-status 201)) + id (get-in resp [:response :body :resource-id]) + uri (-> resp + (ltu/location)) + abs-uri (str p/service-context (u/de-camelcase uri))] + + ;; admin should be able to see, edit, and delete deployment + (-> session-admin + (request abs-uri) + (ltu/body->edn) + (ltu/is-status 200) + (ltu/is-operation-present "delete") + (ltu/is-operation-absent "edit")) + + (-> session-user + (request abs-uri) + (ltu/body->edn) + (ltu/is-status 200) + (ltu/is-operation-present "delete") + (ltu/is-operation-absent "edit")) + + ;; user can delete resource + (-> session-user + (request abs-uri + :request-method :delete) + (ltu/body->edn) + (ltu/is-status 200))) + )) + +; +;(deftest create-deployment +; +; (let [session-admin-json (-> (session (ring-app)) +; (content-type "application/json") +; (header authn-info-header "super ADMIN USER ANON")) +; session-admin-form (-> (session (ring-app)) +; (content-type "application/x-www-form-urlencoded") +; (header authn-info-header "super ADMIN USER ANON")) +; session-user (-> (session (ring-app)) +; (content-type "application/json") +; (header authn-info-header "jane USER ANON")) +; session-anon (-> (session (ring-app)) +; (content-type "application/json"))] +; +; ;; adding, retrieving and deleting entry as user should succeed +; (let [deployment-href (-> session-user +; (request base-uri +; :request-method :post +; :body (json/write-str valid-entry)) +; (t/body->edn) +; (t/is-status 201) +; (t/location)) +; abs-uri (str p/service-context (u/de-camelcase deployment-href)) +; created-deployment (-> session-user +; (request abs-uri) +; (t/body->edn) +; (t/is-status 200))] +; +; (is (not (uzk/exists (str zdu/separator deployment-href))))))) +; +; +;(deftest start-deployment +; +; (let [session-admin-json (-> (session (ring-app)) +; (content-type "application/json") +; (header authn-info-header "super ADMIN USER ANON")) +; session-admin-form (-> (session (ring-app)) +; (content-type "application/x-www-form-urlencoded") +; (header authn-info-header "super ADMIN USER ANON")) +; session-user (-> (session (ring-app)) +; (content-type "application/json") +; (header authn-info-header "jane USER ANON")) +; session-anon (-> (session (ring-app)) +; (content-type "application/json"))] +; +; ;; adding, retrieving and deleting entry as user should succeed +; (let [deployment-href (-> session-user +; (request base-uri +; :request-method :post +; :body (json/write-str valid-entry)) +; (t/body->edn) +; (t/is-status 201) +; (t/location)) +; abs-uri (str p/service-context (u/de-camelcase deployment-href)) +; created-deployment (-> session-user +; (request abs-uri) +; (t/body->edn) +; (t/is-status 200)) +; start-uri (str p/service-context +; (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) +; started-deployment (-> session-user +; (request start-uri) +; (t/body->edn) +; (t/is-status 200)) +; ] +; +; (is (not (get-in created-deployment [:body :start-time]))) +; (is (get-in started-deployment [:response :body :start-time])) +; +; (is (= dsm/init-state (get-in started-deployment [:response :body :state]))) +; +; (are [expected value] +; (= expected value) +; dsm/init-state (uzk/get-data (str zdu/separator deployment-href "/state")) +; "unknown" (uzk/get-data +; (str zdu/separator deployment-href "/" zdu/nodes-name "/node2/1/" "vmstate")))))) +; +;(deftest create-deployment-update-deployment-state +; +; (let [session-admin-json (-> (session (ring-app)) +; (content-type "application/json") +; (header authn-info-header "super ADMIN USER ANON")) +; session-user (-> (session (ring-app)) +; (content-type "application/json") +; (header authn-info-header "jane USER ANON"))] +; +; ;; adding, retrieving and deleting entry as user should succeed +; (let [deployment-href (-> session-user +; (request base-uri +; :request-method :post +; :body (json/write-str valid-entry)) +; (t/body->edn) +; (t/is-status 201) +; (t/location)) +; abs-uri (str p/service-context (u/de-camelcase deployment-href)) +; abs-uri-deployment-parameter-state (str p/service-context dp/resource-url +; "/" valid-entry-deployment-uuid "_state") +; created-deployment (-> session-user +; (request abs-uri) +; (t/body->edn) +; (t/is-status 200)) +; start-uri (str p/service-context +; (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) +; started-deployment (-> session-user +; (request start-uri) +; (t/body->edn) +; (t/is-status 200)) +; update-deployment-parameter-state +; (-> session-user +; (request abs-uri-deployment-parameter-state :request-method :put +; :body (json/write-str {:value dsm/provisioning-state})) +; (t/body->edn) +; (t/is-status 403)) +; update-deployment-parameter-state +; (-> session-admin-json +; (request abs-uri-deployment-parameter-state :request-method :put +; :body (json/write-str {:value dsm/provisioning-state})) +; (t/body->edn) +; (t/is-status 200)) +; provisioning-deployment (-> session-user +; (request start-uri) +; (t/body->edn) +; (t/is-status 200))] +; +; (is (= dsm/provisioning-state (get-in provisioning-deployment [:response :body :state]))) +; +; (is (= dsm/provisioning-state (uzk/get-data (str zdu/separator deployment-href "/state")))) +; ))) +; +;(deftest create-deployment-move-states +; +; (let [session-admin-json (-> (session (ring-app)) +; (content-type "application/json") +; (header authn-info-header "super ADMIN USER ANON")) +; session-user (-> (session (ring-app)) +; (content-type "application/json") +; (header authn-info-header "jane USER ANON"))] +; +; ;; adding, retrieving and deleting entry as user should succeed +; (let [deployment-href (-> session-user +; (request base-uri +; :request-method :post +; :body (json/write-str valid-entry)) +; (t/body->edn) +; (t/location)) +; abs-uri (str p/service-context (u/de-camelcase deployment-href)) +; abs-uri-deployment-parameter-state (str p/service-context dp/resource-url +; "/" valid-entry-deployment-uuid "_state") +; created-deployment (-> session-user +; (request abs-uri) +; (t/body->edn)) +; start-uri (str p/service-context +; (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) +; started-deployment (-> session-user +; (request start-uri) +; (t/body->edn)) +; update-deployment-parameter-state +; (-> session-admin-json +; (request abs-uri-deployment-parameter-state :request-method :put +; :body (json/write-str {:value dsm/provisioning-state})) +; (t/body->edn) +; (t/is-status 200)) +; +; provisioning-deployment (-> session-user +; (request start-uri) +; (t/body->edn) +; (t/is-status 200))] +; (is (= dsm/provisioning-state (get-in provisioning-deployment [:response :body :state]))) +; +; (is (= dsm/provisioning-state (uzk/get-data (str zdu/separator deployment-href "/state")))) +; +; (-> session-admin-json +; (request (str p/service-context (du/deployment-parameter-href +; {:deployment {:href deployment-href} :node-name "node1" +; :node-index 1 :name "state-complete"})) +; :request-method :put :body (json/write-str {:value dsm/provisioning-state})) +; (t/body->edn) +; (t/is-status 200)) +; (-> session-admin-json +; (request (str p/service-context (du/deployment-parameter-href +; {:deployment {:href deployment-href} :node-name "node1" +; :node-index 2 :name "state-complete"})) +; :request-method :put :body (json/write-str {:value dsm/provisioning-state})) +; (t/body->edn) +; (t/is-status 200)) +; +; (is (= 1 (count (uzk/children +; (zdu/deployment-state-path deployment-href))))) +; +; (-> session-admin-json +; (request (str p/service-context (du/deployment-parameter-href +; {:deployment {:href deployment-href} :node-name "node2" +; :node-index 1 :name "state-complete"})) +; :request-method :put :body (json/write-str {:value dsm/provisioning-state})) +; (t/body->edn) +; (t/is-status 200)) +; +; (is (= dsm/executing-state (uzk/get-data (str zdu/separator deployment-href "/state")))) +; +; (is (= dsm/executing-state (-> session-user +; (request (str p/service-context deployment-href)) +; (t/body->edn) +; (get-in [:response :body :state])))) +; +; (is (= 3 (count (uzk/children +; (zdu/deployment-state-path deployment-href))))) +; +; (-> session-admin-json +; (request (str p/service-context (du/deployment-parameter-href +; {:deployment {:href deployment-href} :node-name "node1" +; :node-index 1 :name "state-complete"})) +; :request-method :put :body (json/write-str {:value dsm/executing-state})) +; (t/body->edn) +; (t/is-status 200)) +; (-> session-admin-json +; (request (str p/service-context (du/deployment-parameter-href +; {:deployment {:href deployment-href} :node-name "node1" +; :node-index 2 :name "state-complete"})) +; :request-method :put :body (json/write-str {:value dsm/executing-state})) +; (t/body->edn) +; (t/is-status 200)) +; +; (-> session-admin-json +; (request (str p/service-context (du/deployment-parameter-href +; {:deployment {:href deployment-href} :node-name "node2" +; :node-index 1 :name "state-complete"})) +; :request-method :put :body (json/write-str {:value dsm/executing-state})) +; (t/body->edn) +; (t/is-status 200)) +; +; (is (= dsm/sending-report-state (-> session-user +; (request (str p/service-context deployment-href)) +; (t/body->edn) +; (get-in [:response :body :state])))) +; +; ))) +; +; +;(deftest create-deployment-move-states-abort +; +; (let [session-admin-json (-> (session (ring-app)) +; (content-type "application/json") +; (header authn-info-header "super ADMIN USER ANON")) +; session-user (-> (session (ring-app)) +; (content-type "application/json") +; (header authn-info-header "jane USER ANON"))] +; +; ;; adding, retrieving and deleting entry as user should succeed +; (let [deployment-href (-> session-user +; (request base-uri +; :request-method :post +; :body (json/write-str valid-entry)) +; (t/body->edn) +; (t/location)) +; abs-uri (str p/service-context (u/de-camelcase deployment-href)) +; abs-uri-deployment-parameter-state (str p/service-context dp/resource-url +; "/" valid-entry-deployment-uuid "_state") +; created-deployment (-> session-user +; (request abs-uri) +; (t/body->edn)) +; start-uri (str p/service-context +; (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) +; started-deployment (-> session-user +; (request start-uri) +; (t/body->edn)) +; update-deployment-parameter-state +; (-> session-admin-json +; (request abs-uri-deployment-parameter-state :request-method :put +; :body (json/write-str {:value dsm/provisioning-state})) +; (t/body->edn) +; (t/is-status 200))] +; +; (-> session-admin-json +; (request (str p/service-context (du/deployment-parameter-href +; {:deployment {:href deployment-href} :node-name "node1" +; :node-index 1 :name "state-complete"})) +; :request-method :put :body (json/write-str {:value dsm/provisioning-state})) +; (t/body->edn) +; (t/is-status 200)) +; (-> session-admin-json +; (request (str p/service-context (du/deployment-parameter-href +; {:deployment {:href deployment-href} :node-name "node1" +; :node-index 2 :name "state-complete"})) +; :request-method :put :body (json/write-str {:value dsm/provisioning-state})) +; (t/body->edn) +; (t/is-status 200)) +; +; (-> session-admin-json +; (request (str p/service-context (du/deployment-parameter-href +; {:deployment {:href deployment-href} :node-name "node2" +; :node-index 1 :name "abort"})) +; :request-method :put :body (json/write-str {:value "Error in node 1 abort the run"})) +; (t/body->edn) +; (t/is-status 200)) +; +; (is (= 1 (count (uzk/children +; (zdu/deployment-state-path deployment-href))))) +; +; (is (= dsm/aborted-state (uzk/get-data (str zdu/separator deployment-href "/state")))) +; +; (is (= dsm/aborted-state (-> session-user +; (request (str p/service-context deployment-href)) +; (t/body->edn) +; (get-in [:response :body :state])))) +; +; ))) \ No newline at end of file diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_template_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_template_lifecycle_test.clj new file mode 100644 index 000000000..f5640fd91 --- /dev/null +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_template_lifecycle_test.clj @@ -0,0 +1,98 @@ +(ns com.sixsq.slipstream.ssclj.resources.deployment-template-lifecycle-test + (:require + [clojure.test :refer :all] + [clojure.set :as set] + [clojure.data.json :as json] + [peridot.core :refer :all] + [com.sixsq.slipstream.ssclj.resources.common.crud :as crud] + [com.sixsq.slipstream.ssclj.resources.common.dynamic-load :as dyn] + [com.sixsq.slipstream.ssclj.resources.deployment-template :refer :all] + [com.sixsq.slipstream.ssclj.resources.deployment-template-std :as std] + [com.sixsq.slipstream.ssclj.resources.lifecycle-test-utils :as ltu] + [com.sixsq.slipstream.ssclj.middleware.authn-info-header :refer [authn-info-header]] + [com.sixsq.slipstream.ssclj.app.params :as p] + [com.sixsq.slipstream.ssclj.app.routes :as routes] + [com.sixsq.slipstream.ssclj.resources.common.utils :as u] + [com.sixsq.slipstream.ssclj.resources.common.schema :as c] + [com.sixsq.slipstream.ssclj.resources.common.debug-utils :as du])) + +(use-fixtures :each ltu/with-test-es-client-fixture) + +(def base-uri (str p/service-context (u/de-camelcase resource-name))) + +(defn ring-app [] + (ltu/make-ring-app (ltu/concat-routes [(routes/get-main-routes)]))) + +;; initialize must to called to pull in DeploymentTemplate resources +(dyn/initialize) + +(deftest check-retrieve-by-id + (doseq [registration-method [std/method]] + (let [id (str resource-url "/" registration-method) + doc (crud/retrieve-by-id id)] + (is (= id (:id doc)))))) + +;; check that all templates are visible as administrator +(deftest lifecycle-admin + (let [session (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "root ADMIN")) + entries (-> session + (request base-uri) + (ltu/body->edn) + (ltu/is-status 200) + (ltu/is-resource-uri collection-uri) + (ltu/is-count pos?) + (ltu/is-operation-present "add") ;; should really be absent, but admin always has all rights + (ltu/is-operation-absent "delete") + (ltu/is-operation-absent "edit") + (ltu/is-operation-absent "describe") + (ltu/entries resource-tag)) + ids (set (map :id entries)) + types (set (map :method entries))] + (is (= #{(str resource-url "/" std/method)} + ids)) + (is (= #{std/method} + types)) + + (doseq [entry entries] + (let [ops (ltu/operations->map entry) + href (get ops (c/action-uri :describe)) + entry-url (str p/service-context (:id entry)) + describe-url (str p/service-context href) + + entry-resp (-> session + (request entry-url) + (ltu/is-status 200) + (ltu/body->edn)) + + entry-body (get-in entry-resp [:response :body]) + + desc (-> session + (request describe-url) + (ltu/body->edn) + (ltu/is-status 200)) + desc-body (get-in desc [:response :body])] + (is (nil? (get ops (c/action-uri :add)))) + (is (nil? (get ops (c/action-uri :edit)))) + (is (nil? (get ops (c/action-uri :delete)))) + (is (:method desc-body)) + (is (:acl desc-body)) + + (is (crud/validate entry-body)))))) + +(deftest bad-methods + (let [resource-uri (str p/service-context (u/new-resource-id resource-name))] + (doall + (for [[uri method] [[base-uri :options] + [base-uri :post] + [base-uri :delete] + [resource-uri :options] + [resource-uri :put] + [resource-uri :post] + [resource-uri :delete]]] + (-> (session (ring-app)) + (request uri + :request-method method + :body (json/write-str {:dummy "value"})) + (ltu/is-status 405)))))) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj index 3a4e13322..fe37d94dd 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/lifecycle_test_utils.clj @@ -221,12 +221,12 @@ (let [port 21810 server (TestingServer. port)] (uzk/set-client! (zk/connect (str "127.0.0.1:" port))) - (f) (try + (f) (uzk/close-client) ; in case server already closed ignore exceptions - (catch Exception e)) - (.close server) - )) + (catch Exception e) + (finally + (.close server))))) (defn cleanup-all-zk-nodes [f] (f) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/deployment_test.cljc b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/deployment_test.cljc deleted file mode 100644 index 4cd2fb498..000000000 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/spec/deployment_test.cljc +++ /dev/null @@ -1,53 +0,0 @@ -(ns com.sixsq.slipstream.ssclj.resources.spec.deployment-test - (:require - [clojure.test :refer :all] - [clojure.spec.alpha :as s] - [com.sixsq.slipstream.ssclj.resources.deployment :as d])) - -(def valid-acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:type "ROLE", - :principal "ADMIN", - :right "ALL"}]}) - -(deftest check-DeploymentInfo - (let [timestamp "1964-08-25T10:00:00.0Z" - deployment {:id (str d/resource-url "/deployment-uuid") - :created timestamp - :updated timestamp - :resourceURI d/resource-uri - :acl valid-acl - :module-resource-uri "module/examples/tutorials/service-testing/system/1940" - :category "Deployment" - :type "Orchestration" - :mutable false - :nodes {:node1 - {:parameters - {:cloudservice {:description "p1 description" - :default-value "abc" - :user-choice-value "ABC"} - :multiplicity {:default-value "1"}} - :runtime-parameters - {:p1 {:description "p1 description" - :default-value "abc" - :user-choice-value "ABC" - :mapped-to "a"}}} - :node2 - {:parameters - {:cloudservice {:description "param1 description" - :default-value "abc"}}}}}] - - (are [expect-fn arg] (expect-fn (s/valid? :cimi/deployment arg)) - true? deployment - false? (dissoc deployment :id) - false? (dissoc deployment :created) - false? (dissoc deployment :updated) - false? (dissoc deployment :acl) - false? (dissoc deployment :module-resource-uri) - false? (dissoc deployment :category) - false? (dissoc deployment :type) - false? (update deployment :category (constantly "bonjour")) - false? (dissoc deployment :mutable) - false? (assoc deployment :other "abc") - false? (dissoc deployment :nodes) - true? (assoc deployment :start-time timestamp)))) From d923418d3adb1516a01a520b3a7c14d0ce8c6cfc Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Mon, 18 Sep 2017 10:52:43 +0200 Subject: [PATCH 41/46] fix authentification regression --- .../slipstream/authn/HeaderAuthenticator.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/jar-service/src/main/java/com/sixsq/slipstream/authn/HeaderAuthenticator.java b/jar-service/src/main/java/com/sixsq/slipstream/authn/HeaderAuthenticator.java index 5653c8110..f6678cd5e 100644 --- a/jar-service/src/main/java/com/sixsq/slipstream/authn/HeaderAuthenticator.java +++ b/jar-service/src/main/java/com/sixsq/slipstream/authn/HeaderAuthenticator.java @@ -49,18 +49,19 @@ public HeaderAuthenticator(Context context) { @Override protected boolean authenticate(Request request, Response response) { - - //Form headers = (Form) request.getAttributes().get("org.restlet.http.headers"); - //String username = headers.getFirstValue("slipstream-authn-info"); + if (request.getClientInfo().isAuthenticated()) { + return true; + } Series
series = (Series
) request.getAttributes().get("org.restlet.http.headers"); - String username = series.getFirst("slipstream-authn-info").getValue(); - - if (username != null && !username.isEmpty()) { - return handleValid(request, username); - } else { - return handleNotValid(request, response); + Header authnInfo = series.getFirst("slipstream-authn-info"); + if (authnInfo != null) { + String username = series.getFirst("slipstream-authn-info").getValue(); + if (username != null && !username.isEmpty()) { + return handleValid(request, username); + } } + return handleNotValid(request, response); } private boolean handleValid(Request request, String username) { @@ -85,7 +86,6 @@ private boolean handleValid(Request request, String username) { } private boolean handleNotValid(Request request, Response response) { - CookieUtils.removeAuthnCookie(response); List supported = new ArrayList(); supported.add(MediaType.APPLICATION_XML); From 0578af433baec08dd7499d960255e53a8f5bd1c0 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Mon, 18 Sep 2017 17:58:04 +0200 Subject: [PATCH 42/46] add conversion from java run to deployment and fake http server for tests --- ssclj/jar/build.boot | 1 + .../deployment/java_to_clj_deployment.clj | 106 + .../ssclj/resources/deployment_std.clj | 110 +- .../ssclj/resources/spec/deployment.cljc | 8 +- .../deployment-build-apache-testing.json | 3242 +++++ .../deployment-image-wordpress-testing.json | 3271 +++++ .../deployment-service-testing.json | 11271 ++++++++++++++++ .../java_to_clj_deployment_test.clj | 451 + .../resources/deployment_lifecycle_test.clj | 91 +- 9 files changed, 18396 insertions(+), 155 deletions(-) create mode 100644 ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/java_to_clj_deployment.clj create mode 100644 ssclj/jar/test-resources/deployment-build-apache-testing.json create mode 100644 ssclj/jar/test-resources/deployment-image-wordpress-testing.json create mode 100644 ssclj/jar/test-resources/deployment-service-testing.json create mode 100644 ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment/java_to_clj_deployment_test.clj diff --git a/ssclj/jar/build.boot b/ssclj/jar/build.boot index 99a2ad45d..a0b0f3caf 100644 --- a/ssclj/jar/build.boot +++ b/ssclj/jar/build.boot @@ -69,6 +69,7 @@ [org.clojure/test.check] [org.slf4j/slf4j-log4j12 :scope "test"] [org.apache.curator/curator-test :scope "test"] + [clj-http-fake/clj-http-fake :scope "test"] ;; boot tasks [boot-environ] diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/java_to_clj_deployment.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/java_to_clj_deployment.clj new file mode 100644 index 000000000..a7c93ec01 --- /dev/null +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/java_to_clj_deployment.clj @@ -0,0 +1,106 @@ +(ns com.sixsq.slipstream.ssclj.resources.deployment.java-to-clj-deployment + (:require [clojure.string :as str])) + + + +(defn is-category-image? [category] + (= category "Image")) + +(defn get-nodes-name [{{nodes-entry :entry} :nodes category :category :as module}] + (if (is-category-image? category) ["machine"] + (map (fn [{{name :name :as node} :node}] name) nodes-entry) + )) + +(defn extract-keep-running-value [{parameters :entry}] + (let [parameter-keep-running (filter #(= (:string %) "General.keep-running") parameters) + {{value :value} :parameter} (first parameter-keep-running)] + (when (some? value) value))) + +(defn extract-runtime-parameters-for-node [node-name {runtime-parameters :entry}] + (let [runtime-parameters-for-node (filter #(or (str/starts-with? (:string %) (str node-name ":")) + (str/starts-with? (:string %) (str node-name ".1:"))) + runtime-parameters) + runtime-parameters-for-node (filter #(not (contains? #{"cloudservice" "max-provisioning-failures" + "service-offer" "cpu.nb" "disk.GB" "ram.GB" + "multiplicity"} + (get-in % [:runtimeParameter :name]))) + runtime-parameters-for-node) + runtime-parameters-for-node-useful-data + (map + (fn [{{name :name description :description value + :content mapped-to :mappedRuntimeParameterNames} + :runtimeParameter :as runtime-parameter}] + (let [runtime-parameter (if (str/blank? mapped-to) + {:description description + :value value} + {:description description + :value value + :mapped-to (str/split mapped-to #",")})] + (list (keyword name) runtime-parameter))) runtime-parameters-for-node) + runtime-parameters-map (->> runtime-parameters-for-node-useful-data + (apply concat) + (apply assoc {}))] + {:runtime-parameters runtime-parameters-map})) + +(defn extract-parameters-for-node [node-name {parameters :entry}] + (let [parameters-for-node (filter #(str/starts-with? (:string %) (str node-name ":")) + parameters) + parameters-for-node (filter #(contains? #{"cloudservice" "max-provisioning-failures" + "service-offer" "cpu.nb" "disk.GB" "ram.GB" + "multiplicity" "run-build-recipes" "node.increment"} + (-> (get-in % [:parameter :name]) + (str/replace (re-pattern (str "^" node-name ":")) ""))) + parameters-for-node) + parameters-for-node-useful-data + (map + (fn [{{name :name description :description value :value} + :parameter :as parameter}] + (let [parameter {:description description + :value value} + name (str/replace name (re-pattern (str "^" node-name ":")) "")] + (list (keyword name) parameter))) parameters-for-node) + parameters-map (->> parameters-for-node-useful-data + (apply concat) + (apply assoc {}))] + {:parameters parameters-map})) + +(defn transform [{{uuid :uuid + state :state + type :type + category :category + module-resource-uri :moduleResourceUri + mutable :mutable + cloudservices :cloudservices + module :module + cloud-service-names :cloudServiceNames + runtime-parameters :runtimeParameters + parameters :parameters + } :run :as java-run}] + + (let [deployment {:id (str "deployment/" uuid) + :state state + :type type + :category category + :module-resource-uri module-resource-uri + :mutable mutable + :keep-running (extract-keep-running-value parameters)} + nodes-name (get-nodes-name module) + orchestrators-name (map #(str "orchestrator-" %) (str/split cloud-service-names #",")) + orchestrators-info (if (is-category-image? category) + nil + (->> orchestrators-name + (map #(list (keyword %) (extract-runtime-parameters-for-node + % runtime-parameters))) + (apply concat) + (apply assoc {}))) + nodes-info (->> nodes-name + (map #(list (keyword %) (conj (extract-runtime-parameters-for-node + % runtime-parameters) + (extract-parameters-for-node + % parameters) + ))) + (apply concat) + (apply assoc {})) + nodes-info (conj nodes-info orchestrators-info)] + + (assoc deployment :nodes nodes-info))) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_std.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_std.clj index df569799c..5f7b9c087 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_std.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_std.clj @@ -2,9 +2,15 @@ (:require [com.sixsq.slipstream.ssclj.resources.spec.deployment] [com.sixsq.slipstream.ssclj.resources.spec.deployment-template-std] + [com.sixsq.slipstream.ssclj.resources.deployment.java-to-clj-deployment :as java-to-clj-deployment] [com.sixsq.slipstream.ssclj.resources.deployment :as d] [com.sixsq.slipstream.ssclj.resources.deployment-template-std :as dtpl] - [com.sixsq.slipstream.ssclj.resources.common.utils :as u])) + [com.sixsq.slipstream.ssclj.resources.common.utils :as u] + [environ.core :as env] + [clj-http.client :as http] + [clojure.data.json :as json])) + +(def slipstream-java-endpoint (or (env/env :slipstream-java-endpoint) "http://localhost:8182")) ;; ;; validate the create resource @@ -14,100 +20,20 @@ [resource] (create-validate-fn resource)) -(def deplo-body {:id "deployment/0e0fca32-1bbb-40e3-b2cd-2d97a318694a", - :state "Done", - :type "Run", - :category "Image", - :module-resource-uri "module/apps/WordPress/wordpress/3842", - :mutable false, - :nodes - {:machine - {:runtime-parameters - {:admin_password - {:description "admin password", :value "8rsBZBM659jK"}, - :wordpress_title - {:description "Title (name) to give to the WordPress instance", - :value "Change Me Please 2"}, - :scale.iaas.done - {:description - "Orchestrator sets to 'true' after scaling the node instance", - :value "false"}, - :vmstate - {:description "State of the VM, according to the cloud layer", - :value "Unknown"}, - :pre.scale.done - {:description - "Node instance sets to 'true' after running pre-scale script", - :value "false"}, - :disk.attached.device - {:description - "Attached device name after the VM's vertical scaling", - :value nil}, - :instanceid {:description "Cloud instance id", :value "23"}, - :extra.disk.volatile - {:description "Volatile extra disk in GB", :value nil}, - :statecustom - {:description "Custom state", :value "WordPress ready to go!"}, - :hostname - {:description "hostname/ip of the image", :value "172.16.0.13"}, - :abort - {:description "Machine abort flag, set when aborting", :value nil}, - :nuvlabox-bertil-ohlin.ram - {:description "Amount of RAM, in GB", :value "0.5"}, - :image.id {:description "Cloud image id", :value "8"}, - :scale.state - {:description "Defined scalability state", :value "operational"}, - :disk.detach.device - {:description - "Name of the block device to detach from the VM during vertical scaling", - :value nil}, - :nuvlabox-bertil-ohlin.cpu - {:description "Number of CPUs (i.e. virtual cores)", :value "1"}, - :is.orchestrator - {:description "True if it's an orchestrator", :value "false"}, - :nuvlabox-bertil-ohlin.network.specific.name - {:description "Network name", :value nil}, - :admin_email - {:description "admin email", :value "admin@example.com"}, - :mysql_password - {:description "MySQL password", :value "AX9ytTh2vWF4"}, - :url.ssh - {:description "SSH URL to connect to virtual machine", - :value "ssh://root@172.16.0.13"}, - :complete - {:description "'true' when current state is completed", - :value "false"}, - :network {:description "Network type", :value "Public"}, - :url.service - {:description "Optional service URL for virtual machine", - :value "http://172.16.0.13:8080"}, - :image.platform - {:description "Platform (eg: ubuntu, windows)", :value "ubuntu"}, - :nuvlabox-bertil-ohlin.custom.vm.template - {:description "Additional custom VM template", :value nil}, - :disk.attach.size - {:description - "Size of the extra disk to attach to the VM during vertical scaling", - :value nil}, - :nuvlabox-bertil-ohlin.is.firewall - {:description - "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", - :value "false"}}, - :parameters - {:run-build-recipes - {:description - "Define if the SlipStream executor should run build recipes.", - :value "false"}, - :cloudservice {:description "", :value "nuvlabox-bertil-ohlin"}}}}}) - ;; ;; transform template into deployment resource ;; just strips method attribute and updates the resource URI ;; (defmethod d/tpl->deployment dtpl/method - [resource request] - (-> deplo-body - (dissoc :method) - (assoc :resourceURI d/resource-uri)) - ) + [{module :module :as resource} {username :user-name :as request}] + (let [java-deployment-location (-> (http/post (str slipstream-java-endpoint "/run") + {:headers {"slipstream-authn-info" username} + :form-params {:refqname module :bypass-ssh-check true}}) + (get-in [:headers "Location"])) + java-deployment-json (-> (http/get java-deployment-location {:headers {"slipstream-authn-info" username + "Accept" "application/json"}}) + :body + (json/read-str :key-fn keyword)) + ] + (java-to-clj-deployment/transform java-deployment-json))) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc index 7b347e543..1775ba591 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/spec/deployment.cljc @@ -15,7 +15,7 @@ (s/def :cimi.deployment/end-time :cimi.core/timestamp) (s/def :cimi.deployment/last-state-change-time :cimi.core/timestamp) (s/def :cimi.deployment/mutable boolean?) -(s/def :cimi.deployment/keep-running boolean?) +(s/def :cimi.deployment/keep-running (s/nilable string?)) (s/def :cimi.deployment/tags (s/coll-of string?)) (s/def :cimi.deployment/state #{"Initializing" "Provisioning" "Executing" "SendingReports" "Ready" "Finalizing" "Done" "Cancelled" "Aborted" "Unknown"}) @@ -34,6 +34,8 @@ (s/def :cimi.deployment.node/max-provisioning-failures :cimi.deployment/parameter) (s/def :cimi.deployment.node/cloudservice :cimi.deployment/parameter) (s/def :cimi.deployment.node/run-build-recipes :cimi.deployment/parameter) +(s/def :cimi.deployment.node/node.increment :cimi.deployment/parameter) +(s/def :cimi.deployment.node/service-offer :cimi.deployment/parameter) (s/def :cimi.deployment/parameters (su/only-keys-maps @@ -43,7 +45,9 @@ :cimi.deployment.node/cpu.nb :cimi.deployment.node/ram.GB :cimi.deployment.node/disk.GB - :cimi.deployment.node/run-build-recipes]})) + :cimi.deployment.node/run-build-recipes + :cimi.deployment.node/node.increment + :cimi.deployment.node/service-offer]})) (s/def :cimi.deployment.runtime-parameter/mapped-to (s/coll-of string?)) diff --git a/ssclj/jar/test-resources/deployment-build-apache-testing.json b/ssclj/jar/test-resources/deployment-build-apache-testing.json new file mode 100644 index 000000000..8c1f6a413 --- /dev/null +++ b/ssclj/jar/test-resources/deployment-build-apache-testing.json @@ -0,0 +1,3242 @@ +{ + "run": { + "cloudServiceNamesList": { + "string": "nuvlabox-stanley-cohen", + "length": 1 + }, + "module": { + "outputParametersExpanded": { + "entry": [ + { + "string": "hostname", + "parameter": { + "readonly": false, + "isSet": false, + "name": "hostname", + "description": "hostname/ip of the image", + "category": "Output", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "instanceid", + "parameter": { + "readonly": false, + "isSet": false, + "name": "instanceid", + "description": "Cloud instance id", + "category": "Output", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "port", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "8080", + "name": "port", + "description": "Port", + "category": "Output", + "type": "String", + "mandatory": false, + "value": "8080", + "order_": 0, + "order": 0 + } + }, + { + "string": "ready", + "parameter": { + "readonly": false, + "isSet": false, + "name": "ready", + "description": "Server ready to recieve connections", + "category": "Output", + "type": "String", + "mandatory": false, + "order_": 0, + "order": 0 + } + } + ], + "class": "java.util.HashMap" + }, + "cloudImageIdentifiers": { + "cloudImageIdentifier": { + "cloudImageIdentifier": 17, + "resourceUri": "module/examples/tutorials/service-testing/apache/5071/nuvlabox-stanley-cohen", + "cloudServiceName": "nuvlabox-stanley-cohen" + }, + "class": "org.hibernate.collection.internal.PersistentSet" + }, + "notes": { + "length": 0 + }, + "parentUri": "module/examples/tutorials/service-testing", + "commit": { + "author": "sixsq", + "comment": "Allow to \"Build or run single image\" for public." + }, + "recipe": "#!/bin/sh -xe\r\n\r\napt-get update -y\r\napt-get install -y apache2", + "packagesExpanded": { + "class": "java.util.HashSet" + }, + "description": "Apache web server appliance with custom landing page.", + "moduleReferenceUri": "module/examples/images/ubuntu-14.04", + "targets": { + "class": "org.hibernate.collection.internal.PersistentSet", + "target": [ + { + "name": "onvmadd" + }, + { + "name": "report", + "content": "#!/bin/sh -x\r\ncp /var/log/apache2/access.log $SLIPSTREAM_REPORT_DIR\r\ncp /var/log/apache2/error.log $SLIPSTREAM_REPORT_DIR" + }, + { + "name": "execute", + "content": "#!/bin/sh -xe\r\n\r\ndefault_site_location='/etc/apache2/sites-available/default'\r\nif [ ! -f $default_site_location ]; then\r\n default_site_location='/etc/apache2/sites-available/000-default.conf'\r\nfi\r\n\r\nhttp_root_location='/var/www/html'\r\nif [ ! -d $http_root_location ]; then\r\n http_root_location='/var/www'\r\nfi\r\n\r\necho 'Hello from Apache deployed by SlipStream!' > $http_root_location/data.txt\r\n\r\nservice apache2 stop\r\nport=$(ss-get port)\r\n\r\nsed -i -e 's/^Listen.*$/Listen '$port'/' /etc/apache2/ports.conf\r\nsed -i -e 's/^NameVirtualHost.*$/NameVirtualHost *:'$port'/' /etc/apache2/ports.conf\r\nsed -i -e 's/^/' $default_site_location\r\nservice apache2 start\r\nss-set ready true\r\nurl=\"http://$(ss-get hostname):$port\"\r\nss-set url.service $url\r\nss-set ss:url.service $url\r\n" + }, + { + "name": "onvmremove" + } + ] + }, + "platform": "ubuntu", + "loginUser": "root", + "logoLink": "https://nuv.la/images/modules-logos/apache-httpd.svg", + "targetsExpanded": { + "targetExpanded": [ + { + "name": "report", + "subTarget": [ + { + "moduleShortName": "apache", + "name": "report", + "moduleUri": "module/examples/tutorials/service-testing/apache/5071", + "content": "#!/bin/sh -x\r\ncp /var/log/apache2/access.log $SLIPSTREAM_REPORT_DIR\r\ncp /var/log/apache2/error.log $SLIPSTREAM_REPORT_DIR", + "order": 2 + }, + { + "moduleShortName": "ubuntu-14.04", + "name": "report", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + } + ] + }, + { + "name": "onvmremove", + "subTarget": [ + { + "moduleShortName": "ubuntu-14.04", + "name": "onvmremove", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + }, + { + "moduleShortName": "apache", + "name": "onvmremove", + "moduleUri": "module/examples/tutorials/service-testing/apache/5071", + "order": 2 + } + ] + }, + { + "name": "prerecipe", + "subTarget": [ + { + "moduleShortName": "ubuntu-14.04", + "name": "prerecipe", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + }, + { + "moduleShortName": "apache", + "name": "prerecipe", + "moduleUri": "module/examples/tutorials/service-testing/apache/5071", + "order": 2 + } + ] + }, + { + "name": "recipe", + "subTarget": [ + { + "moduleShortName": "apache", + "name": "recipe", + "moduleUri": "module/examples/tutorials/service-testing/apache/5071", + "content": "#!/bin/sh -xe\r\n\r\napt-get update -y\r\napt-get install -y apache2", + "order": 2 + }, + { + "moduleShortName": "ubuntu-14.04", + "name": "recipe", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + } + ] + }, + { + "name": "onvmadd", + "subTarget": [ + { + "moduleShortName": "ubuntu-14.04", + "name": "onvmadd", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + }, + { + "moduleShortName": "apache", + "name": "onvmadd", + "moduleUri": "module/examples/tutorials/service-testing/apache/5071", + "order": 2 + } + ] + }, + { + "name": "execute", + "subTarget": [ + { + "moduleShortName": "apache", + "name": "execute", + "moduleUri": "module/examples/tutorials/service-testing/apache/5071", + "content": "#!/bin/sh -xe\r\n\r\ndefault_site_location='/etc/apache2/sites-available/default'\r\nif [ ! -f $default_site_location ]; then\r\n default_site_location='/etc/apache2/sites-available/000-default.conf'\r\nfi\r\n\r\nhttp_root_location='/var/www/html'\r\nif [ ! -d $http_root_location ]; then\r\n http_root_location='/var/www'\r\nfi\r\n\r\necho 'Hello from Apache deployed by SlipStream!' > $http_root_location/data.txt\r\n\r\nservice apache2 stop\r\nport=$(ss-get port)\r\n\r\nsed -i -e 's/^Listen.*$/Listen '$port'/' /etc/apache2/ports.conf\r\nsed -i -e 's/^NameVirtualHost.*$/NameVirtualHost *:'$port'/' /etc/apache2/ports.conf\r\nsed -i -e 's/^/' $default_site_location\r\nservice apache2 start\r\nss-set ready true\r\nurl=\"http://$(ss-get hostname):$port\"\r\nss-set url.service $url\r\nss-set ss:url.service $url\r\n", + "order": 2 + }, + { + "moduleShortName": "ubuntu-14.04", + "name": "execute", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "content": "#!/bin/bash -xe\r\n\r\n# set the service url to SSH url\r\nurl=$(ss-get --timeout=180 url.ssh)\r\nss-set url.service \"${url}\"\r\nss-set ss:url.service \"${url}\"\r\n\r\n", + "order": 1 + } + ] + } + ], + "class": "java.util.HashSet" + }, + "class": "com.sixsq.slipstream.persistence.ImageModule", + "creation": "2013-12-03 16:04:03.426 UTC", + "authz": { + "owner": "sixsq", + "groupMembers": { + "string": [ + "elegoff", + "khaled", + "konstan", + "lionel", + "loomis", + "meb", + "cjdcsixsq" + ], + "class": "java.util.ArrayList" + }, + "ownerGet": true, + "ownerDelete": true, + "groupPost": true, + "publicPost": true, + "publicCreateChildren": false, + "ownerCreateChildren": true, + "publicGet": true, + "inheritedGroupMembers": true, + "ownerPost": true, + "groupCreateChildren": false, + "publicPut": false, + "groupGet": true, + "groupDelete": false, + "ownerPut": true, + "publicDelete": false, + "groupPut": true + }, + "buildStates": { + "class": "java.util.HashSet", + "buildState": [ + { + "builtOn": "", + "moduleUri": "module/examples/images/ubuntu-14.04/13947" + }, + { + "builtOn": "nuvlabox-stanley-cohen", + "moduleUri": "module/examples/tutorials/service-testing/apache/5071" + } + ] + }, + "isLatestVersion": false, + "prerecipe": "", + "resourceUri": "module/examples/tutorials/service-testing/apache/5071", + "packages": { + "class": "org.hibernate.collection.internal.PersistentSet" + }, + "version": 5071, + "inputParametersExpanded": { + "class": "java.util.HashMap" + }, + "deleted": false, + "name": "examples/tutorials/service-testing/apache", + "lastModified": "2016-08-05 08:32:47.92 UTC", + "isBase": false, + "category": "Image", + "shortName": "apache", + "parameters": { + "entry": [ + { + "string": "nuvlabox-albert-einstein.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-albert-einstein.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-albert-einstein", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-demo.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-demo.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-demo", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-albert-einstein.ram", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-albert-einstein.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-albert-einstein", + "type": "String", + "mandatory": true, + "order_": 11, + "order": 11 + } + }, + { + "string": "cyclone-de1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "cyclone-de1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "cyclone-de1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "hostname", + "parameter": { + "readonly": false, + "isSet": false, + "name": "hostname", + "description": "hostname/ip of the image", + "category": "Output", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "cyclone-fr1.disks.bus.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "virtio", + "name": "cyclone-fr1.disks.bus.type", + "description": "VM disks bus type", + "category": "cyclone-fr1", + "type": "Enum", + "mandatory": true, + "value": "virtio", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "virtio", + "scsi" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-arthur-harden.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-arthur-harden.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-arthur-harden", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "exoscale-ch-gva.disk", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "10G", + "name": "exoscale-ch-gva.disk", + "description": "Size of the root disk", + "category": "exoscale-ch-gva", + "type": "Enum", + "mandatory": true, + "value": "10G", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "10G", + "50G", + "100G", + "200G", + "400G" + ], + "length": 5 + } + } + }, + { + "string": "nuvlabox-demo.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-demo.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-demo", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "nuvlabox-max-born.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-max-born.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-max-born", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "nuvlabox-arthur-harden.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-arthur-harden.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-arthur-harden", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "cyclone-fr1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small", + "name": "cyclone-fr1.instance.type", + "description": "Cloud instance type", + "category": "cyclone-fr1", + "type": "Enum", + "mandatory": true, + "value": "m1.small", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "m1.small", + "c1.medium", + "m1.large", + "m1.xlarge", + "c1.xlarge", + "t1.micro", + "standard.xsmall" + ], + "length": 7 + } + } + }, + { + "string": "ec2-ap-northeast-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-ap-northeast-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-ap-northeast-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.micro", + "t2.small", + "t2.medium", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 42 + } + } + }, + { + "string": "ec2-us-west-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-us-west-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-us-west-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-ap-southeast-2.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-ap-southeast-2.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-ap-southeast-2", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-arthur-harden.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-arthur-harden.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-arthur-harden", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-cecil-powell.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-cecil-powell.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-cecil-powell", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "nuvlabox-stanley-cohen.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-stanley-cohen.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-stanley-cohen", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "ec2-sa-east-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-sa-east-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-sa-east-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.micro", + "t2.small", + "t2.medium", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 42 + } + } + }, + { + "string": "ultimum-cz1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ultimum-cz1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ultimum-cz1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-ap-northeast-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-ap-northeast-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-ap-northeast-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-carl-cori.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-carl-cori.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-carl-cori", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-bertil-ohlin.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-bertil-ohlin.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-bertil-ohlin", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-cecil-powell.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-cecil-powell.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-cecil-powell", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-stanley-cohen.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-stanley-cohen.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-stanley-cohen", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-max-planck.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-max-planck.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-max-planck", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-christiane-nusslein-volhard.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-christiane-nusslein-volhard.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-christiane-nusslein-volhard", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "cyclone-fr2.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "cyclone-fr2.security.groups", + "description": "Security Groups (comma separated list)", + "category": "cyclone-fr2", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-henry-dunant.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-henry-dunant.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-henry-dunant", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "ec2-ap-southeast-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-ap-southeast-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-ap-southeast-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-james-chadwick.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-james-chadwick.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-james-chadwick", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-henry-dunant.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-henry-dunant.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-henry-dunant", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-bertil-ohlin.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-bertil-ohlin.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-bertil-ohlin", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "ec2-us-east-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-us-east-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-us-east-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-max-born.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-max-born.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-max-born", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "cyclone-fr1.cpu", + "parameter": { + "readonly": false, + "isSet": false, + "name": "cyclone-fr1.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "cyclone-fr1", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-christiane-nusslein-volhard.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-christiane-nusslein-volhard.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-christiane-nusslein-volhard", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "exoscale-ch-gva.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "exoscale-ch-gva.security.groups", + "description": "Security Groups (comma separated list)", + "category": "exoscale-ch-gva", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-max-planck.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "micro", + "name": "nuvlabox-max-planck.instance.type", + "description": "Instance type", + "category": "nuvlabox-max-planck", + "type": "Enum", + "mandatory": true, + "value": "micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "micro", + "small", + "medium", + "large" + ], + "length": 4 + } + } + }, + { + "string": "nuvlabox-james-chadwick.disks.bus.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "virtio", + "name": "nuvlabox-james-chadwick.disks.bus.type", + "description": "VM disks bus type", + "category": "nuvlabox-james-chadwick", + "type": "Enum", + "mandatory": true, + "value": "virtio", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "virtio", + "scsi" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-max-born.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-max-born.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-max-born", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "ec2-eu-central-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-eu-central-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-eu-central-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-james-chadwick.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "micro", + "name": "nuvlabox-james-chadwick.instance.type", + "description": "Instance type", + "category": "nuvlabox-james-chadwick", + "type": "Enum", + "mandatory": true, + "value": "micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "micro", + "small", + "medium", + "large" + ], + "length": 4 + } + } + }, + { + "string": "nuvlabox-max-planck.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-max-planck.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-max-planck", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "ultimum-cz1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "Basic", + "name": "ultimum-cz1.instance.type", + "description": "Instance type (flavor)", + "category": "ultimum-cz1", + "type": "String", + "mandatory": true, + "value": "Basic", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-bertil-ohlin.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-bertil-ohlin.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-bertil-ohlin", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "nuvlabox-carl-cori.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-carl-cori.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-carl-cori", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-henry-dunant.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-henry-dunant.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-henry-dunant", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-james-chadwick.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-james-chadwick.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-james-chadwick", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "ec2-sa-east-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-sa-east-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-sa-east-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-james-chadwick.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-james-chadwick.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-james-chadwick", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-carl-cori.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-carl-cori.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-carl-cori", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "nuvlabox-albert-einstein.cpu", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-albert-einstein.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-albert-einstein", + "type": "String", + "mandatory": true, + "order_": 10, + "order": 10 + } + }, + { + "string": "ec2-us-west-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-us-west-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-us-west-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.micro", + "t2.small", + "t2.medium", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 42 + } + } + }, + { + "string": "nuvlabox-demo.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "micro", + "name": "nuvlabox-demo.instance.type", + "description": "Instance type", + "category": "nuvlabox-demo", + "type": "Enum", + "mandatory": true, + "value": "micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "micro", + "small", + "medium", + "large" + ], + "length": 4 + } + } + }, + { + "string": "azure-west-europe.forwarded.ports", + "parameter": { + "instructions": "Ports that will be forwarded from the public IP of the Azure cloud service. The port 22 (SSH) on Linux machines and the port 3389 (RDP) on Windows machines are already forwarded", + "readonly": false, + "isSet": false, + "name": "azure-west-europe.forwarded.ports", + "description": "Forwarded ports (comma separated list)", + "category": "azure-west-europe", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-stanley-cohen.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-stanley-cohen.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-stanley-cohen", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "exoscale-ch-gva.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "Small", + "name": "exoscale-ch-gva.instance.type", + "description": "Cloud instance type", + "category": "exoscale-ch-gva", + "type": "Enum", + "mandatory": true, + "value": "Small", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "Micro", + "Tiny", + "Small", + "Medium", + "Large", + "Extra-large", + "Huge", + "Mega", + "Titan" + ], + "length": 9 + } + } + }, + { + "string": "extra.disk.volatile", + "parameter": { + "readonly": false, + "isSet": false, + "name": "extra.disk.volatile", + "description": "Volatile extra disk in GB", + "category": "Cloud", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-arthur-harden.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-arthur-harden.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-arthur-harden", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "instanceid", + "parameter": { + "readonly": false, + "isSet": false, + "name": "instanceid", + "description": "Cloud instance id", + "category": "Output", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "port", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "8080", + "name": "port", + "description": "Port", + "category": "Output", + "type": "String", + "mandatory": false, + "value": "8080", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-demo.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-demo.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-demo", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-albert-einstein.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "micro", + "name": "nuvlabox-albert-einstein.instance.type", + "description": "Instance type", + "category": "nuvlabox-albert-einstein", + "type": "Enum", + "mandatory": true, + "value": "micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "micro", + "small", + "medium", + "large" + ], + "length": 4 + } + } + }, + { + "string": "cyclone-fr2.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small", + "name": "cyclone-fr2.instance.type", + "description": "Instance type (flavor)", + "category": "cyclone-fr2", + "type": "String", + "mandatory": true, + "value": "m1.small", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-demo.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-demo.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-demo", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-christiane-nusslein-volhard.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-christiane-nusslein-volhard.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-christiane-nusslein-volhard", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-albert-einstein.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-albert-einstein.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-albert-einstein", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "nuvlabox-stanley-cohen.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-stanley-cohen.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-stanley-cohen", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-cecil-powell.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-cecil-powell.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-cecil-powell", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-max-born.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-max-born.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-max-born", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "cyclone-fr1.ram", + "parameter": { + "readonly": false, + "isSet": false, + "name": "cyclone-fr1.ram", + "description": "Amount of RAM, in GB", + "category": "cyclone-fr1", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "exoscale-ch-dk.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "exoscale-ch-dk.security.groups", + "description": "Security Groups (comma separated list)", + "category": "exoscale-ch-dk", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "cyclone-de1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small_Linux", + "name": "cyclone-de1.instance.type", + "description": "Instance type (flavor)", + "category": "cyclone-de1", + "type": "String", + "mandatory": true, + "value": "m1.small_Linux", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-carl-cori.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-carl-cori.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-carl-cori", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "ec2-ap-southeast-2.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-ap-southeast-2.instance.type", + "description": "Cloud instance type", + "category": "ec2-ap-southeast-2", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.micro", + "t2.small", + "t2.medium", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 42 + } + } + }, + { + "string": "cyfronet-pl1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "cyfronet-pl1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "cyfronet-pl1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "network", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "Public", + "name": "network", + "description": "Network type", + "category": "Cloud", + "type": "Enum", + "mandatory": true, + "value": "Public", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "Public", + "Private" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-henry-dunant.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-henry-dunant.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-henry-dunant", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "azure-west-europe.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "Basic_A0", + "name": "azure-west-europe.instance.type", + "description": "Machine size", + "category": "azure-west-europe", + "type": "Enum", + "mandatory": true, + "value": "Basic_A0", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "Basic_A0", + "Basic_A1", + "Basic_A2", + "Basic_A3", + "Basic_A4", + "ExtraSmall", + "Small", + "Medium", + "Large", + "ExtraLarge", + "A5", + "A6", + "A7", + "A8", + "A9", + "A10", + "A11", + "Standard_D1", + "Standard_D2", + "Standard_D3", + "Standard_D4", + "Standard_D11", + "Standard_D12", + "Standard_D13", + "Standard_D14" + ], + "length": 25 + } + } + }, + { + "string": "ready", + "parameter": { + "readonly": false, + "isSet": false, + "name": "ready", + "description": "Server ready to recieve connections", + "category": "Output", + "type": "String", + "mandatory": false, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-christiane-nusslein-volhard.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-christiane-nusslein-volhard.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-christiane-nusslein-volhard", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "ec2-us-east-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-us-east-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-us-east-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.micro", + "t2.small", + "t2.medium", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 42 + } + } + }, + { + "string": "nuvlabox-bertil-ohlin.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-bertil-ohlin.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-bertil-ohlin", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-cecil-powell.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-cecil-powell.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-cecil-powell", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-james-chadwick.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-james-chadwick.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-james-chadwick", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "ec2-eu-west.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-eu-west.instance.type", + "description": "Cloud instance type", + "category": "ec2-eu-west", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.micro", + "t2.small", + "t2.medium", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 42 + } + } + }, + { + "string": "exoscale-ch-dk.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "Micro", + "name": "exoscale-ch-dk.instance.type", + "description": "Cloud instance type", + "category": "exoscale-ch-dk", + "type": "Enum", + "mandatory": true, + "value": "Micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "Micro", + "Tiny", + "Small", + "Medium", + "Large", + "Extra-large", + "Huge", + "Mega", + "Titan" + ], + "length": 9 + } + } + }, + { + "string": "nuvlabox-max-planck.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-max-planck.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-max-planck", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "softlayer-it-mil01.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "2 CPU, 2GB ram, 100GB", + "name": "softlayer-it-mil01.instance.type", + "description": "Instance type (flavor)", + "category": "softlayer-it-mil01", + "type": "String", + "mandatory": true, + "value": "2 CPU, 2GB ram, 100GB", + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-ap-southeast-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-ap-southeast-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-ap-southeast-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.micro", + "t2.small", + "t2.medium", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 42 + } + } + }, + { + "string": "cyfronet-pl1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "CPU-1.RAM-512MB.DISK-10GB", + "name": "cyfronet-pl1.instance.type", + "description": "Instance type (flavor)", + "category": "cyfronet-pl1", + "type": "String", + "mandatory": true, + "value": "CPU-1.RAM-512MB.DISK-10GB", + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-eu-west.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-eu-west.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-eu-west", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-max-planck.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-max-planck.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-max-planck", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "ec2-eu-central-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-eu-central-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-eu-central-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.micro", + "t2.small", + "t2.medium", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 42 + } + } + }, + { + "string": "exoscale-ch-dk.disk", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "10G", + "name": "exoscale-ch-dk.disk", + "description": "Size of the root disk", + "category": "exoscale-ch-dk", + "type": "Enum", + "mandatory": true, + "value": "10G", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "10G", + "50G", + "100G", + "200G", + "400G" + ], + "length": 5 + } + } + }, + { + "string": "ec2-us-west-2.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-us-west-2.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-us-west-2", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-us-west-2.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-us-west-2.instance.type", + "description": "Cloud instance type", + "category": "ec2-us-west-2", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.micro", + "t2.small", + "t2.medium", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 42 + } + } + } + ], + "class": "org.hibernate.collection.internal.PersistentMap" + } + }, + "lastStateChangeTime": "2017-03-20 13:38:17.66 UTC", + "groups": "nuvlabox-stanley-cohen:machine", + "resourceUri": "run/380798cb-bb04-41e4-8498-d8ee090e1643", + "type": "Machine", + "uuid": "380798cb-bb04-41e4-8498-d8ee090e1643", + "nodeNames": "machine,orchestrator-nuvlabox-stanley-cohen", + "deleted": false, + "moduleResourceUri": "module/examples/tutorials/service-testing/apache/5071", + "mutable": false, + "runtimeParameters": { + "entry": [ + { + "string": "machine:disk.detach.device", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "disk.detach.device", + "description": "Name of the block device to detach from the VM during vertical scaling", + "type": "String", + "key": "machine:disk.detach.device", + "creation": "2017-03-20 13:36:04.970 UTC", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-stanley-cohen:instanceid", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "instanceid", + "description": "Cloud instance id", + "type": "String", + "key": "orchestrator-nuvlabox-stanley-cohen:instanceid", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "119", + "group": "orchestrator-nuvlabox-stanley-cohen", + "mapsOthers": false + } + }, + { + "string": "machine:cloudservice", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "cloudservice", + "description": "Cloud Service where the node resides", + "type": "String", + "key": "machine:cloudservice", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "nuvlabox-stanley-cohen", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:ready", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "ready", + "description": "Server ready to recieve connections", + "type": "String", + "key": "machine:ready", + "creation": "2017-03-20 13:36:04.970 UTC", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "ss:abort", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "abort", + "description": "Run abort flag, set when aborting", + "type": "String", + "key": "ss:abort", + "creation": "2017-03-20 13:36:04.970 UTC", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "machine:nuvlabox-stanley-cohen.custom.vm.template", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "nuvlabox-stanley-cohen.custom.vm.template", + "description": "Additional custom VM template", + "type": "String", + "key": "machine:nuvlabox-stanley-cohen.custom.vm.template", + "creation": "2017-03-20 13:36:04.970 UTC", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:scale.state", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "scale.state", + "description": "Defined scalability state", + "type": "String", + "key": "machine:scale.state", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "creating", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-stanley-cohen:cloudservice", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "cloudservice", + "description": "Cloud Service where the node resides", + "type": "String", + "key": "orchestrator-nuvlabox-stanley-cohen:cloudservice", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "nuvlabox-stanley-cohen", + "group": "orchestrator-nuvlabox-stanley-cohen", + "mapsOthers": false + } + }, + { + "string": "machine:disk.attached.device", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "disk.attached.device", + "description": "Attached device name after the VM's vertical scaling", + "type": "String", + "key": "machine:disk.attached.device", + "creation": "2017-03-20 13:36:04.970 UTC", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:scale.iaas.done", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "scale.iaas.done", + "description": "Orchestrator sets to 'true' after scaling the node instance", + "type": "String", + "key": "machine:scale.iaas.done", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "false", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:vmstate", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "vmstate", + "description": "State of the VM, according to the cloud layer", + "type": "String", + "key": "machine:vmstate", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "Unknown", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-stanley-cohen:vmstate", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "vmstate", + "description": "State of the VM, according to the cloud layer", + "type": "String", + "key": "orchestrator-nuvlabox-stanley-cohen:vmstate", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "Unknown", + "group": "orchestrator-nuvlabox-stanley-cohen", + "mapsOthers": false + } + }, + { + "string": "machine:complete", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "complete", + "description": "'true' when current state is completed", + "type": "String", + "key": "machine:complete", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "false", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:port", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "port", + "description": "Port", + "type": "String", + "key": "machine:port", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "8080", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "ss:complete", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "complete", + "description": "Global complete flag, set when run completed", + "type": "String", + "key": "ss:complete", + "creation": "2017-03-20 13:36:04.970 UTC", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "ss:url.service", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "url.service", + "description": "Optional service URL for the deployment", + "type": "String", + "key": "ss:url.service", + "creation": "2017-03-20 13:36:04.970 UTC", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "machine:url.service", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "url.service", + "description": "Optional service URL for virtual machine", + "type": "String", + "key": "machine:url.service", + "creation": "2017-03-20 13:36:04.970 UTC", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:image.platform", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "image.platform", + "description": "Platform (eg: ubuntu, windows)", + "type": "String", + "key": "machine:image.platform", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "ubuntu", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-stanley-cohen:complete", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "complete", + "description": "'true' when current state is completed", + "type": "String", + "key": "orchestrator-nuvlabox-stanley-cohen:complete", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "false", + "group": "orchestrator-nuvlabox-stanley-cohen", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-stanley-cohen:url.service", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "url.service", + "description": "Optional service URL for virtual machine", + "type": "String", + "key": "orchestrator-nuvlabox-stanley-cohen:url.service", + "creation": "2017-03-20 13:36:04.970 UTC", + "group": "orchestrator-nuvlabox-stanley-cohen", + "mapsOthers": false + } + }, + { + "string": "machine:nuvlabox-stanley-cohen.cpu", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "nuvlabox-stanley-cohen.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "type": "String", + "key": "machine:nuvlabox-stanley-cohen.cpu", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "1", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:url.ssh", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "url.ssh", + "description": "SSH URL to connect to virtual machine", + "type": "String", + "key": "machine:url.ssh", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "ssh://root@172.16.0.15", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "ss:state", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "state", + "description": "Global execution state", + "type": "String", + "key": "ss:state", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "Done", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "machine:is.orchestrator", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "is.orchestrator", + "description": "True if it's an orchestrator", + "type": "String", + "key": "machine:is.orchestrator", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "false", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "ss:groups", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "groups", + "description": "Comma separated node groups", + "type": "String", + "key": "ss:groups", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "nuvlabox-stanley-cohen:machine", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "ss:tags", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "tags", + "description": "Comma separated tag values", + "type": "String", + "key": "ss:tags", + "creation": "2017-03-20 13:36:04.970 UTC", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-stanley-cohen:url.ssh", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "url.ssh", + "description": "SSH URL to connect to virtual machine", + "type": "String", + "key": "orchestrator-nuvlabox-stanley-cohen:url.ssh", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "ssh://root@172.16.0.14", + "group": "orchestrator-nuvlabox-stanley-cohen", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-stanley-cohen:is.orchestrator", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "is.orchestrator", + "description": "True if it's an orchestrator", + "type": "String", + "key": "orchestrator-nuvlabox-stanley-cohen:is.orchestrator", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "true", + "group": "orchestrator-nuvlabox-stanley-cohen", + "mapsOthers": false + } + }, + { + "string": "ss:category", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "category", + "description": "Module category", + "type": "String", + "key": "ss:category", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "Image", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "machine:nuvlabox-stanley-cohen.is.firewall", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "nuvlabox-stanley-cohen.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "type": "String", + "key": "machine:nuvlabox-stanley-cohen.is.firewall", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "false", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:statecustom", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "statecustom", + "description": "Custom state", + "type": "String", + "key": "machine:statecustom", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "Image saved !", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-stanley-cohen:hostname", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "hostname", + "description": "hostname/ip of the image", + "type": "String", + "key": "orchestrator-nuvlabox-stanley-cohen:hostname", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "172.16.0.14", + "group": "orchestrator-nuvlabox-stanley-cohen", + "mapsOthers": false + } + }, + { + "string": "machine:nuvlabox-stanley-cohen.network.specific.name", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "nuvlabox-stanley-cohen.network.specific.name", + "description": "Network name", + "type": "String", + "key": "machine:nuvlabox-stanley-cohen.network.specific.name", + "creation": "2017-03-20 13:36:04.970 UTC", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "ss:recovery.mode", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "recovery.mode", + "description": "Run abort flag, set when aborting", + "type": "String", + "key": "ss:recovery.mode", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "false", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "machine:disk.attach.size", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "disk.attach.size", + "description": "Size of the extra disk to attach to the VM during vertical scaling", + "type": "String", + "key": "machine:disk.attach.size", + "creation": "2017-03-20 13:36:04.970 UTC", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:pre.scale.done", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "pre.scale.done", + "description": "Node instance sets to 'true' after running pre-scale script", + "type": "String", + "key": "machine:pre.scale.done", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "false", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:instanceid", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "instanceid", + "description": "Cloud instance id", + "type": "String", + "key": "machine:instanceid", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "120", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:network", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "network", + "description": "Network type", + "type": "String", + "key": "machine:network", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "Public", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:nuvlabox-stanley-cohen.ram", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "nuvlabox-stanley-cohen.ram", + "description": "Amount of RAM, in GB", + "type": "String", + "key": "machine:nuvlabox-stanley-cohen.ram", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "0.5", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-stanley-cohen:max.iaas.workers", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "max.iaas.workers", + "description": "Max number of concurrently provisioned VMs by orchestrator", + "type": "String", + "key": "orchestrator-nuvlabox-stanley-cohen:max.iaas.workers", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "7", + "group": "orchestrator-nuvlabox-stanley-cohen", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-stanley-cohen:abort", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "abort", + "description": "Machine abort flag, set when aborting", + "type": "String", + "key": "orchestrator-nuvlabox-stanley-cohen:abort", + "creation": "2017-03-20 13:36:04.970 UTC", + "group": "orchestrator-nuvlabox-stanley-cohen", + "mapsOthers": false + } + }, + { + "string": "machine:hostname", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "hostname", + "description": "hostname/ip of the image", + "type": "String", + "key": "machine:hostname", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "172.16.0.15", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:abort", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "abort", + "description": "Machine abort flag, set when aborting", + "type": "String", + "key": "machine:abort", + "creation": "2017-03-20 13:36:04.970 UTC", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:extra.disk.volatile", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "extra.disk.volatile", + "description": "Volatile extra disk in GB", + "type": "String", + "key": "machine:extra.disk.volatile", + "creation": "2017-03-20 13:36:04.970 UTC", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:image.id", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "image.id", + "description": "Cloud image id", + "type": "String", + "key": "machine:image.id", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "d88f85a9489e5c05aa2f06a4a878826f", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-stanley-cohen:statecustom", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "statecustom", + "description": "Custom state", + "type": "String", + "key": "orchestrator-nuvlabox-stanley-cohen:statecustom", + "creation": "2017-03-20 13:36:04.970 UTC", + "content": "Provisioning of node instances requested [2017-03-20T13:37:01Z]. Time took to provision 0h00m10s.", + "group": "orchestrator-nuvlabox-stanley-cohen", + "mapsOthers": false + } + } + ], + "class": "org.hibernate.collection.internal.PersistentMap" + }, + "cloudServiceNames": "nuvlabox-stanley-cohen", + "startTime": "2017-03-20 13:36:04.904 UTC", + "state": "Done", + "endTime": "2017-03-20 13:38:17.66 UTC", + "category": "Image", + "user": "khaled", + "parameters": { + "entry": [ + { + "string": "machine:cloudservice", + "parameter": { + "readonly": false, + "name": "machine:cloudservice", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "nuvlabox-stanley-cohen", + "order_": 0, + "order": 0 + } + }, + { + "string": "General.keep-running", + "parameter": { + "readonly": false, + "name": "General.keep-running", + "description": "Keep running after deployment", + "category": "General", + "type": "String", + "mandatory": false, + "value": "always", + "order_": 0, + "order": 0 + } + }, + { + "string": "garbage_collected", + "parameter": { + "readonly": false, + "name": "garbage_collected", + "description": "true if the Run was already garbage collected", + "category": "General", + "type": "String", + "mandatory": false, + "value": "false", + "order_": 0, + "order": 0 + } + } + ], + "class": "org.hibernate.collection.internal.PersistentMap" + }, + "creation": "2017-03-20 13:36:04.904 UTC" + } +} \ No newline at end of file diff --git a/ssclj/jar/test-resources/deployment-image-wordpress-testing.json b/ssclj/jar/test-resources/deployment-image-wordpress-testing.json new file mode 100644 index 000000000..2d4ef8d26 --- /dev/null +++ b/ssclj/jar/test-resources/deployment-image-wordpress-testing.json @@ -0,0 +1,3271 @@ +{ + "run": { + "cloudServiceNamesList": { + "string": "nuvlabox-bertil-ohlin", + "length": 1 + }, + "module": { + "outputParametersExpanded": { + "entry": [ + { + "string": "hostname", + "parameter": { + "readonly": false, + "isSet": false, + "name": "hostname", + "description": "hostname/ip of the image", + "category": "Output", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "instanceid", + "parameter": { + "readonly": false, + "isSet": false, + "name": "instanceid", + "description": "Cloud instance id", + "category": "Output", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "admin_password", + "parameter": { + "readonly": false, + "isSet": false, + "name": "admin_password", + "description": "admin password", + "category": "Output", + "type": "String", + "mandatory": false, + "order_": 0, + "order": 0 + } + }, + { + "string": "mysql_password", + "parameter": { + "readonly": false, + "isSet": false, + "name": "mysql_password", + "description": "MySQL password", + "category": "Output", + "type": "String", + "mandatory": false, + "order_": 0, + "order": 0 + } + } + ], + "class": "java.util.HashMap" + }, + "cloudImageIdentifiers": { + "cloudImageIdentifier": [ + { + "cloudImageIdentifier": 4, + "resourceUri": "module/apps/WordPress/wordpress/3842/nuvlabox-demo", + "cloudServiceName": "nuvlabox-demo" + }, + { + "cloudImageIdentifier": 8, + "resourceUri": "module/apps/WordPress/wordpress/3842/nuvlabox-bertil-ohlin", + "cloudServiceName": "nuvlabox-bertil-ohlin" + } + ], + "class": "org.hibernate.collection.internal.PersistentSet" + }, + "notes": { + "length": 0 + }, + "parentUri": "module/apps/WordPress", + "commit": { + "author": "lionel", + "comment": "Fixed the path to the php module" + }, + "recipe": "#!/bin/bash -x\r\n\r\nfunction ss-display {\r\n $(which ss-display) \"$1\" || echo \"$1\"\r\n}\r\n\r\nset -e\r\n\r\nss-display \"Updating package index\"\r\napt-get clean\r\napt-get update\r\n\r\nss-display \"Installing WordPress manifest\"\r\npuppet module install hunner-wordpress\r\npuppet module install puppetlabs-apache\r\n\r\ncat > httpd.pp << 'EOF'\r\nclass { 'apache': \r\n mpm_module => 'prefork',\r\n}\r\n\r\napache::vhost { 'wordpres':\r\n vhost_name => '*',\r\n port => 8080,\r\n docroot => '/opt/wordpress',\r\n}\r\n\r\napache::mod { 'php5': }\r\n\r\nEOF\r\n\r\nss-display \"Configuring Apache\"\r\npuppet apply -v httpd.pp\r\n\r\nln -s ../mods-available/php5.conf /etc/apache2/mods-enabled/php5.conf\r\necho 'LoadModule php5_module /usr/lib/apache2/modules/libphp5.so' > /etc/apache2/mods-available/php5.load \r\n\r\nservice apache2 restart\r\n\r\n", + "packagesExpanded": { + "packageExpanded": [ + { + "name": "curl" + }, + { + "name": "libapache2-mod-php5" + }, + { + "name": "php5-mcrypt" + }, + { + "name": "mysql-server" + }, + { + "name": "puppet-common" + }, + { + "name": "php5" + }, + { + "name": "php5-mysql" + }, + { + "name": "mysql-client" + } + ], + "class": "java.util.HashSet" + }, + "description": "Installs and configures WordPress using Puppet", + "moduleReferenceUri": "module/examples/images/ubuntu-14.04", + "targets": { + "class": "org.hibernate.collection.internal.PersistentSet", + "target": [ + { + "name": "onvmremove" + }, + { + "name": "report" + }, + { + "name": "onvmadd" + }, + { + "name": "execute", + "content": "#!/bin/bash -x\r\n\r\nset -e\r\nset -x\r\n\r\nexport admin_username=admin\r\nexport admin_password=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c12)\r\nexport admin_email=$(ss-get admin_email)\r\nexport wordpress_title=$(ss-get wordpress_title)\r\nexport mysql_password=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c12)\r\nexport public_hostname=$(ss-get hostname)\r\n\r\nss-set -- mysql_password $mysql_password\r\nss-set -- admin_password $admin_password\r\n\r\ncat > wp.pp << EOF\r\nclass { 'wordpress':\r\n wp_owner => 'www-data',\r\n wp_group => 'www-data',\r\n db_user => 'wordpress',\r\n db_password => '$(mysql_password)'\r\n}\r\nEOF\r\n\r\nss-display \"Installing WordPress\"\r\npuppet apply -v wp.pp\r\n\r\nss-display \"Configuring WordPress\"\r\n\r\nbase_url=\"http://${public_hostname}:8080\"\r\nurl=\"${base_url}/wp-admin/install.php?step=2\"\r\n\r\n# quote the title since it can contain spaces\r\n/usr/bin/curl \\\r\n --data-urlencode \"weblog_title=${wordpress_title}\" \\\r\n -d \"user_name=${admin_username}\" \\\r\n -d \"admin_password=${admin_password}\" \\\r\n -d \"admin_password2=${admin_password}\" \\\r\n -d \"admin_email=${admin_email}\" \\\r\n -d \"blog_public=1\" -v ${url} >> /tmp/curl.out\r\n\r\nss-set ss:url.service \"${base_url}\"\r\nss-set url.service \"${base_url}\"\r\n\r\nss-display \"WordPress ready to go!\"\r\n\r\n" + } + ] + }, + "platform": "ubuntu", + "loginUser": "root", + "logoLink": "https://nuv.la/images/modules-logos/wordpress.svg", + "targetsExpanded": { + "targetExpanded": [ + { + "name": "report", + "subTarget": [ + { + "moduleShortName": "wordpress", + "name": "report", + "moduleUri": "module/apps/WordPress/wordpress/3842", + "order": 2 + }, + { + "moduleShortName": "ubuntu-14.04", + "name": "report", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + } + ] + }, + { + "name": "prerecipe", + "subTarget": [ + { + "moduleShortName": "ubuntu-14.04", + "name": "prerecipe", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + }, + { + "moduleShortName": "wordpress", + "name": "prerecipe", + "moduleUri": "module/apps/WordPress/wordpress/3842", + "order": 2 + } + ] + }, + { + "name": "onvmadd", + "subTarget": [ + { + "moduleShortName": "ubuntu-14.04", + "name": "onvmadd", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + }, + { + "moduleShortName": "wordpress", + "name": "onvmadd", + "moduleUri": "module/apps/WordPress/wordpress/3842", + "order": 2 + } + ] + }, + { + "name": "recipe", + "subTarget": [ + { + "moduleShortName": "ubuntu-14.04", + "name": "recipe", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + }, + { + "moduleShortName": "wordpress", + "name": "recipe", + "moduleUri": "module/apps/WordPress/wordpress/3842", + "content": "#!/bin/bash -x\r\n\r\nfunction ss-display {\r\n $(which ss-display) \"$1\" || echo \"$1\"\r\n}\r\n\r\nset -e\r\n\r\nss-display \"Updating package index\"\r\napt-get clean\r\napt-get update\r\n\r\nss-display \"Installing WordPress manifest\"\r\npuppet module install hunner-wordpress\r\npuppet module install puppetlabs-apache\r\n\r\ncat > httpd.pp << 'EOF'\r\nclass { 'apache': \r\n mpm_module => 'prefork',\r\n}\r\n\r\napache::vhost { 'wordpres':\r\n vhost_name => '*',\r\n port => 8080,\r\n docroot => '/opt/wordpress',\r\n}\r\n\r\napache::mod { 'php5': }\r\n\r\nEOF\r\n\r\nss-display \"Configuring Apache\"\r\npuppet apply -v httpd.pp\r\n\r\nln -s ../mods-available/php5.conf /etc/apache2/mods-enabled/php5.conf\r\necho 'LoadModule php5_module /usr/lib/apache2/modules/libphp5.so' > /etc/apache2/mods-available/php5.load \r\n\r\nservice apache2 restart\r\n\r\n", + "order": 2 + } + ] + }, + { + "name": "execute", + "subTarget": [ + { + "moduleShortName": "ubuntu-14.04", + "name": "execute", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "content": "#!/bin/bash -xe\r\n\r\n# set the service url to SSH url\r\nurl=$(ss-get --timeout=180 url.ssh)\r\nss-set url.service \"${url}\"\r\nss-set ss:url.service \"${url}\"\r\n\r\n", + "order": 1 + }, + { + "moduleShortName": "wordpress", + "name": "execute", + "moduleUri": "module/apps/WordPress/wordpress/3842", + "content": "#!/bin/bash -x\r\n\r\nset -e\r\nset -x\r\n\r\nexport admin_username=admin\r\nexport admin_password=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c12)\r\nexport admin_email=$(ss-get admin_email)\r\nexport wordpress_title=$(ss-get wordpress_title)\r\nexport mysql_password=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c12)\r\nexport public_hostname=$(ss-get hostname)\r\n\r\nss-set -- mysql_password $mysql_password\r\nss-set -- admin_password $admin_password\r\n\r\ncat > wp.pp << EOF\r\nclass { 'wordpress':\r\n wp_owner => 'www-data',\r\n wp_group => 'www-data',\r\n db_user => 'wordpress',\r\n db_password => '$(mysql_password)'\r\n}\r\nEOF\r\n\r\nss-display \"Installing WordPress\"\r\npuppet apply -v wp.pp\r\n\r\nss-display \"Configuring WordPress\"\r\n\r\nbase_url=\"http://${public_hostname}:8080\"\r\nurl=\"${base_url}/wp-admin/install.php?step=2\"\r\n\r\n# quote the title since it can contain spaces\r\n/usr/bin/curl \\\r\n --data-urlencode \"weblog_title=${wordpress_title}\" \\\r\n -d \"user_name=${admin_username}\" \\\r\n -d \"admin_password=${admin_password}\" \\\r\n -d \"admin_password2=${admin_password}\" \\\r\n -d \"admin_email=${admin_email}\" \\\r\n -d \"blog_public=1\" -v ${url} >> /tmp/curl.out\r\n\r\nss-set ss:url.service \"${base_url}\"\r\nss-set url.service \"${base_url}\"\r\n\r\nss-display \"WordPress ready to go!\"\r\n\r\n", + "order": 2 + } + ] + }, + { + "name": "onvmremove", + "subTarget": [ + { + "moduleShortName": "ubuntu-14.04", + "name": "onvmremove", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + }, + { + "moduleShortName": "wordpress", + "name": "onvmremove", + "moduleUri": "module/apps/WordPress/wordpress/3842", + "order": 2 + } + ] + } + ], + "class": "java.util.HashSet" + }, + "class": "com.sixsq.slipstream.persistence.ImageModule", + "creation": "2013-11-16 07:43:14.5 UTC", + "authz": { + "owner": "sixsq", + "groupMembers": { + "string": [ + "khaled", + "konstan", + "lionel", + "loomis", + "meb", + "rob", + "stef", + "cjdcsixsq" + ], + "class": "java.util.ArrayList" + }, + "ownerGet": true, + "ownerDelete": true, + "groupPost": true, + "publicPost": true, + "publicCreateChildren": false, + "ownerCreateChildren": true, + "publicGet": true, + "inheritedGroupMembers": true, + "ownerPost": true, + "groupCreateChildren": false, + "publicPut": false, + "groupGet": true, + "groupDelete": false, + "ownerPut": true, + "publicDelete": false, + "groupPut": true + }, + "buildStates": { + "class": "java.util.HashSet", + "buildState": [ + { + "builtOn": "nuvlabox-demo,nuvlabox-bertil-ohlin", + "moduleUri": "module/apps/WordPress/wordpress/3842" + }, + { + "builtOn": "", + "moduleUri": "module/examples/images/ubuntu-14.04/13947" + } + ] + }, + "isLatestVersion": true, + "prerecipe": "", + "resourceUri": "module/apps/WordPress/wordpress/3842", + "published": { + "publicationDate": "2016-06-16 08:39:13.172 UTC" + }, + "packages": { + "package": [ + { + "name": "curl" + }, + { + "name": "libapache2-mod-php5" + }, + { + "name": "php5-mcrypt" + }, + { + "name": "mysql-server" + }, + { + "name": "puppet-common" + }, + { + "name": "php5" + }, + { + "name": "php5-mysql" + }, + { + "name": "mysql-client" + } + ], + "class": "org.hibernate.collection.internal.PersistentSet" + }, + "version": 3842, + "inputParametersExpanded": { + "entry": [ + { + "string": "admin_email", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "admin@example.com", + "name": "admin_email", + "description": "admin email", + "category": "Input", + "type": "String", + "mandatory": false, + "value": "admin@example.com", + "order_": 0, + "order": 0 + } + }, + { + "string": "wordpress_title", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "Change Me Please", + "name": "wordpress_title", + "description": "Title (name) to give to the WordPress instance", + "category": "Input", + "type": "String", + "mandatory": false, + "value": "Change Me Please", + "order_": 0, + "order": 0 + } + } + ], + "class": "java.util.HashMap" + }, + "deleted": false, + "name": "apps/WordPress/wordpress", + "lastModified": "2016-06-16 08:39:13.172 UTC", + "isBase": false, + "category": "Image", + "shortName": "wordpress", + "parameters": { + "entry": [ + { + "string": "nuvlabox-albert-einstein.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-albert-einstein.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-albert-einstein", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-demo.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-demo.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-demo", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-albert-einstein.ram", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-albert-einstein.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-albert-einstein", + "type": "String", + "mandatory": true, + "order_": 11, + "order": 11 + } + }, + { + "string": "cyclone-de1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "cyclone-de1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "cyclone-de1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "admin_email", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "admin@example.com", + "name": "admin_email", + "description": "admin email", + "category": "Input", + "type": "String", + "mandatory": false, + "value": "admin@example.com", + "order_": 0, + "order": 0 + } + }, + { + "string": "hostname", + "parameter": { + "readonly": false, + "isSet": false, + "name": "hostname", + "description": "hostname/ip of the image", + "category": "Output", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "cyclone-fr1.disks.bus.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "virtio", + "name": "cyclone-fr1.disks.bus.type", + "description": "VM disks bus type", + "category": "cyclone-fr1", + "type": "Enum", + "mandatory": true, + "value": "virtio", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "virtio", + "scsi" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-arthur-harden.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-arthur-harden.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-arthur-harden", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "exoscale-ch-gva.disk", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "10G", + "name": "exoscale-ch-gva.disk", + "description": "Size of the root disk", + "category": "exoscale-ch-gva", + "type": "Enum", + "mandatory": true, + "value": "10G", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "10G", + "50G", + "100G", + "200G", + "400G" + ], + "length": 5 + } + } + }, + { + "string": "nuvlabox-demo.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-demo.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-demo", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-max-born.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-max-born.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-max-born", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "nuvlabox-arthur-harden.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-arthur-harden.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-arthur-harden", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "cyclone-fr1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small", + "name": "cyclone-fr1.instance.type", + "description": "Cloud instance type", + "category": "cyclone-fr1", + "type": "Enum", + "mandatory": true, + "value": "m1.small", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "m1.small", + "c1.medium", + "m1.large", + "m1.xlarge", + "c1.xlarge", + "t1.micro", + "standard.xsmall" + ], + "length": 7 + } + } + }, + { + "string": "ec2-us-west-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-us-west-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-us-west-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-ap-northeast-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-ap-northeast-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-ap-northeast-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.micro", + "t2.small", + "t2.medium", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 42 + } + } + }, + { + "string": "ec2-ap-southeast-2.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-ap-southeast-2.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-ap-southeast-2", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-arthur-harden.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-arthur-harden.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-arthur-harden", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-cecil-powell.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-cecil-powell.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-cecil-powell", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "nuvlabox-stanley-cohen.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-stanley-cohen.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-stanley-cohen", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "ec2-sa-east-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-sa-east-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-sa-east-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.micro", + "t2.small", + "t2.medium", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 42 + } + } + }, + { + "string": "ultimum-cz1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ultimum-cz1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ultimum-cz1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-ap-northeast-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-ap-northeast-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-ap-northeast-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-carl-cori.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-carl-cori.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-carl-cori", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-bertil-ohlin.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-bertil-ohlin.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-bertil-ohlin", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-cecil-powell.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-cecil-powell.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-cecil-powell", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-stanley-cohen.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-stanley-cohen.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-stanley-cohen", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-max-planck.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-max-planck.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-max-planck", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-christiane-nusslein-volhard.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-christiane-nusslein-volhard.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-christiane-nusslein-volhard", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "cyclone-fr2.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "cyclone-fr2.security.groups", + "description": "Security Groups (comma separated list)", + "category": "cyclone-fr2", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-henry-dunant.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-henry-dunant.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-henry-dunant", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "ec2-ap-southeast-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-ap-southeast-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-ap-southeast-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-james-chadwick.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-james-chadwick.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-james-chadwick", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-henry-dunant.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-henry-dunant.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-henry-dunant", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-bertil-ohlin.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-bertil-ohlin.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-bertil-ohlin", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "ec2-us-east-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-us-east-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-us-east-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-max-born.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-max-born.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-max-born", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "cyclone-fr1.cpu", + "parameter": { + "readonly": false, + "isSet": false, + "name": "cyclone-fr1.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "cyclone-fr1", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-christiane-nusslein-volhard.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-christiane-nusslein-volhard.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-christiane-nusslein-volhard", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "exoscale-ch-gva.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "exoscale-ch-gva.security.groups", + "description": "Security Groups (comma separated list)", + "category": "exoscale-ch-gva", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-max-planck.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "micro", + "name": "nuvlabox-max-planck.instance.type", + "description": "Instance type", + "category": "nuvlabox-max-planck", + "type": "Enum", + "mandatory": true, + "value": "micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "micro", + "small", + "medium", + "large" + ], + "length": 4 + } + } + }, + { + "string": "nuvlabox-james-chadwick.disks.bus.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "virtio", + "name": "nuvlabox-james-chadwick.disks.bus.type", + "description": "VM disks bus type", + "category": "nuvlabox-james-chadwick", + "type": "Enum", + "mandatory": true, + "value": "virtio", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "virtio", + "scsi" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-max-born.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-max-born.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-max-born", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "ec2-eu-central-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-eu-central-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-eu-central-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-james-chadwick.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "micro", + "name": "nuvlabox-james-chadwick.instance.type", + "description": "Instance type", + "category": "nuvlabox-james-chadwick", + "type": "Enum", + "mandatory": true, + "value": "micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "micro", + "small", + "medium", + "large" + ], + "length": 4 + } + } + }, + { + "string": "nuvlabox-max-planck.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-max-planck.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-max-planck", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "ultimum-cz1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "Basic", + "name": "ultimum-cz1.instance.type", + "description": "Instance type (flavor)", + "category": "ultimum-cz1", + "type": "String", + "mandatory": true, + "value": "Basic", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-bertil-ohlin.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-bertil-ohlin.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-bertil-ohlin", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "nuvlabox-carl-cori.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-carl-cori.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-carl-cori", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-henry-dunant.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-henry-dunant.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-henry-dunant", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-james-chadwick.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-james-chadwick.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-james-chadwick", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "ec2-sa-east-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-sa-east-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-sa-east-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-james-chadwick.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-james-chadwick.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-james-chadwick", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-carl-cori.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-carl-cori.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-carl-cori", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "nuvlabox-albert-einstein.cpu", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-albert-einstein.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-albert-einstein", + "type": "String", + "mandatory": true, + "order_": 10, + "order": 10 + } + }, + { + "string": "ec2-us-west-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-us-west-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-us-west-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.micro", + "t2.small", + "t2.medium", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 42 + } + } + }, + { + "string": "nuvlabox-demo.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "micro", + "name": "nuvlabox-demo.instance.type", + "description": "Instance type", + "category": "nuvlabox-demo", + "type": "Enum", + "mandatory": true, + "value": "micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "micro", + "small", + "medium", + "large" + ], + "length": 4 + } + } + }, + { + "string": "mysql_password", + "parameter": { + "readonly": false, + "isSet": false, + "name": "mysql_password", + "description": "MySQL password", + "category": "Output", + "type": "String", + "mandatory": false, + "order_": 0, + "order": 0 + } + }, + { + "string": "azure-west-europe.forwarded.ports", + "parameter": { + "instructions": "Ports that will be forwarded from the public IP of the Azure cloud service. The port 22 (SSH) on Linux machines and the port 3389 (RDP) on Windows machines are already forwarded", + "readonly": false, + "isSet": false, + "name": "azure-west-europe.forwarded.ports", + "description": "Forwarded ports (comma separated list)", + "category": "azure-west-europe", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-stanley-cohen.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-stanley-cohen.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-stanley-cohen", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "exoscale-ch-gva.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "Small", + "name": "exoscale-ch-gva.instance.type", + "description": "Cloud instance type", + "category": "exoscale-ch-gva", + "type": "Enum", + "mandatory": true, + "value": "Small", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "Micro", + "Tiny", + "Small", + "Medium", + "Large", + "Extra-large", + "Huge" + ], + "length": 7 + } + } + }, + { + "string": "extra.disk.volatile", + "parameter": { + "readonly": false, + "isSet": false, + "name": "extra.disk.volatile", + "description": "Volatile extra disk in GB", + "category": "Cloud", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "admin_password", + "parameter": { + "readonly": false, + "isSet": false, + "name": "admin_password", + "description": "admin password", + "category": "Output", + "type": "String", + "mandatory": false, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-arthur-harden.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-arthur-harden.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-arthur-harden", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "instanceid", + "parameter": { + "readonly": false, + "isSet": false, + "name": "instanceid", + "description": "Cloud instance id", + "category": "Output", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-demo.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-demo.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-demo", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-albert-einstein.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "micro", + "name": "nuvlabox-albert-einstein.instance.type", + "description": "Instance type", + "category": "nuvlabox-albert-einstein", + "type": "Enum", + "mandatory": true, + "value": "micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "micro", + "small", + "medium", + "large" + ], + "length": 4 + } + } + }, + { + "string": "cyclone-fr2.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small", + "name": "cyclone-fr2.instance.type", + "description": "Instance type (flavor)", + "category": "cyclone-fr2", + "type": "String", + "mandatory": true, + "value": "m1.small", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-demo.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-demo.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-demo", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-christiane-nusslein-volhard.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-christiane-nusslein-volhard.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-christiane-nusslein-volhard", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-albert-einstein.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-albert-einstein.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-albert-einstein", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "nuvlabox-stanley-cohen.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-stanley-cohen.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-stanley-cohen", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-cecil-powell.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-cecil-powell.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-cecil-powell", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-max-born.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-max-born.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-max-born", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "cyclone-fr1.ram", + "parameter": { + "readonly": false, + "isSet": false, + "name": "cyclone-fr1.ram", + "description": "Amount of RAM, in GB", + "category": "cyclone-fr1", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "exoscale-ch-dk.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "exoscale-ch-dk.security.groups", + "description": "Security Groups (comma separated list)", + "category": "exoscale-ch-dk", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "cyclone-de1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small", + "name": "cyclone-de1.instance.type", + "description": "Instance type (flavor)", + "category": "cyclone-de1", + "type": "String", + "mandatory": true, + "value": "m1.small", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-carl-cori.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-carl-cori.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-carl-cori", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "ec2-ap-southeast-2.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-ap-southeast-2.instance.type", + "description": "Cloud instance type", + "category": "ec2-ap-southeast-2", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.micro", + "t2.small", + "t2.medium", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 42 + } + } + }, + { + "string": "cyfronet-pl1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "cyfronet-pl1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "cyfronet-pl1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "network", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "Public", + "name": "network", + "description": "Network type", + "category": "Cloud", + "type": "Enum", + "mandatory": true, + "value": "Public", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "Public", + "Private" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-henry-dunant.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-henry-dunant.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-henry-dunant", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "azure-west-europe.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "Basic_A0", + "name": "azure-west-europe.instance.type", + "description": "Machine size", + "category": "azure-west-europe", + "type": "Enum", + "mandatory": true, + "value": "Basic_A0", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "Basic_A0", + "Basic_A1", + "Basic_A2", + "Basic_A3", + "Basic_A4", + "ExtraSmall", + "Small", + "Medium", + "Large", + "ExtraLarge", + "A5", + "A6", + "A7", + "A8", + "A9", + "A10", + "A11", + "Standard_D1", + "Standard_D2", + "Standard_D3", + "Standard_D4", + "Standard_D11", + "Standard_D12", + "Standard_D13", + "Standard_D14" + ], + "length": 25 + } + } + }, + { + "string": "nuvlabox-christiane-nusslein-volhard.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-christiane-nusslein-volhard.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-christiane-nusslein-volhard", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "ec2-us-east-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-us-east-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-us-east-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.micro", + "t2.small", + "t2.medium", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 42 + } + } + }, + { + "string": "nuvlabox-bertil-ohlin.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-bertil-ohlin.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-bertil-ohlin", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-cecil-powell.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-cecil-powell.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-cecil-powell", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "ec2-eu-west.security.group", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-eu-west.security.group", + "description": "Security groups (comma separated list)", + "category": "ec2-eu-west", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-james-chadwick.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-james-chadwick.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-james-chadwick", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "ec2-eu-west.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-eu-west.instance.type", + "description": "Cloud instance type", + "category": "ec2-eu-west", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.micro", + "t2.small", + "t2.medium", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 42 + } + } + }, + { + "string": "exoscale-ch-dk.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "Micro", + "name": "exoscale-ch-dk.instance.type", + "description": "Cloud instance type", + "category": "exoscale-ch-dk", + "type": "Enum", + "mandatory": true, + "value": "Micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "Micro", + "Tiny", + "Small", + "Medium", + "Large", + "Extra-large", + "Huge" + ], + "length": 7 + } + } + }, + { + "string": "nuvlabox-max-planck.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-max-planck.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-max-planck", + "type": "String", + "mandatory": true, + "order_": 100, + "order": 100 + } + }, + { + "string": "softlayer-it-mil01.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "2 CPU, 2GB ram, 100GB", + "name": "softlayer-it-mil01.instance.type", + "description": "Instance type (flavor)", + "category": "softlayer-it-mil01", + "type": "String", + "mandatory": true, + "value": "2 CPU, 2GB ram, 100GB", + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-ap-southeast-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-ap-southeast-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-ap-southeast-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.micro", + "t2.small", + "t2.medium", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 42 + } + } + }, + { + "string": "cyfronet-pl1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "CPU-1.RAM-512MB.DISK-10GB", + "name": "cyfronet-pl1.instance.type", + "description": "Instance type (flavor)", + "category": "cyfronet-pl1", + "type": "String", + "mandatory": true, + "value": "CPU-1.RAM-512MB.DISK-10GB", + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-eu-west.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-eu-west.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-eu-west", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-max-planck.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-max-planck.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-max-planck", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "ec2-eu-central-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-eu-central-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-eu-central-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.micro", + "t2.small", + "t2.medium", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 42 + } + } + }, + { + "string": "exoscale-ch-dk.disk", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "10G", + "name": "exoscale-ch-dk.disk", + "description": "Size of the root disk", + "category": "exoscale-ch-dk", + "type": "Enum", + "mandatory": true, + "value": "10G", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "10G", + "50G", + "100G", + "200G", + "400G" + ], + "length": 5 + } + } + }, + { + "string": "ec2-us-west-2.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed<\/code> to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-us-west-2.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-us-west-2", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-us-west-2.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-us-west-2.instance.type", + "description": "Cloud instance type", + "category": "ec2-us-west-2", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.micro", + "t2.small", + "t2.medium", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 42 + } + } + }, + { + "string": "wordpress_title", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "Change Me Please", + "name": "wordpress_title", + "description": "Title (name) to give to the WordPress instance", + "category": "Input", + "type": "String", + "mandatory": false, + "value": "Change Me Please", + "order_": 0, + "order": 0 + } + } + ], + "class": "org.hibernate.collection.internal.PersistentMap" + } + }, + "lastStateChangeTime": "2017-04-04 06:46:58.571 UTC", + "groups": "nuvlabox-bertil-ohlin:machine", + "resourceUri": "run/0e0fca32-1bbb-40e3-b2cd-2d97a318694a", + "type": "Run", + "uuid": "0e0fca32-1bbb-40e3-b2cd-2d97a318694a", + "nodeNames": "machine", + "deleted": false, + "moduleResourceUri": "module/apps/WordPress/wordpress/3842", + "mutable": false, + "runtimeParameters": { + "entry": [ + { + "string": "machine:disk.detach.device", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "disk.detach.device", + "description": "Name of the block device to detach from the VM during vertical scaling", + "type": "String", + "key": "machine:disk.detach.device", + "creation": "2017-04-03 12:15:08.626 UTC", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:cloudservice", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "cloudservice", + "description": "Cloud Service where the node resides", + "type": "String", + "key": "machine:cloudservice", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "nuvlabox-bertil-ohlin", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:nuvlabox-bertil-ohlin.cpu", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "nuvlabox-bertil-ohlin.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "type": "String", + "key": "machine:nuvlabox-bertil-ohlin.cpu", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "1", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "ss:abort", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "abort", + "description": "Run abort flag, set when aborting", + "type": "String", + "key": "ss:abort", + "creation": "2017-04-03 12:15:08.626 UTC", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "machine:scale.state", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "scale.state", + "description": "Defined scalability state", + "type": "String", + "key": "machine:scale.state", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "operational", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:disk.attached.device", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "disk.attached.device", + "description": "Attached device name after the VM's vertical scaling", + "type": "String", + "key": "machine:disk.attached.device", + "creation": "2017-04-03 12:15:08.626 UTC", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:scale.iaas.done", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "scale.iaas.done", + "description": "Orchestrator sets to 'true' after scaling the node instance", + "type": "String", + "key": "machine:scale.iaas.done", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "false", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:vmstate", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "vmstate", + "description": "State of the VM, according to the cloud layer", + "type": "String", + "key": "machine:vmstate", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "Unknown", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:complete", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "complete", + "description": "'true' when current state is completed", + "type": "String", + "key": "machine:complete", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "false", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "ss:complete", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "complete", + "description": "Global complete flag, set when run completed", + "type": "String", + "key": "ss:complete", + "creation": "2017-04-03 12:15:08.626 UTC", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "ss:url.service", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "url.service", + "description": "Optional service URL for the deployment", + "type": "String", + "key": "ss:url.service", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "http://172.16.0.13:8080", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "machine:url.service", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "url.service", + "description": "Optional service URL for virtual machine", + "type": "String", + "key": "machine:url.service", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "http://172.16.0.13:8080", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:image.platform", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "image.platform", + "description": "Platform (eg: ubuntu, windows)", + "type": "String", + "key": "machine:image.platform", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "ubuntu", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:nuvlabox-bertil-ohlin.is.firewall", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "nuvlabox-bertil-ohlin.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "type": "String", + "key": "machine:nuvlabox-bertil-ohlin.is.firewall", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "false", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:admin_email", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "admin_email", + "description": "admin email", + "type": "String", + "key": "machine:admin_email", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "admin@example.com", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:url.ssh", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "url.ssh", + "description": "SSH URL to connect to virtual machine", + "type": "String", + "key": "machine:url.ssh", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "ssh://root@172.16.0.13", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:wordpress_title", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "wordpress_title", + "description": "Title (name) to give to the WordPress instance", + "type": "String", + "key": "machine:wordpress_title", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "Change Me Please 2", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "ss:state", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "state", + "description": "Global execution state", + "type": "String", + "key": "ss:state", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "Done", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "machine:is.orchestrator", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "is.orchestrator", + "description": "True if it's an orchestrator", + "type": "String", + "key": "machine:is.orchestrator", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "false", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:nuvlabox-bertil-ohlin.network.specific.name", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "nuvlabox-bertil-ohlin.network.specific.name", + "description": "Network name", + "type": "String", + "key": "machine:nuvlabox-bertil-ohlin.network.specific.name", + "creation": "2017-04-03 12:15:08.626 UTC", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "ss:groups", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "groups", + "description": "Comma separated node groups", + "type": "String", + "key": "ss:groups", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "nuvlabox-bertil-ohlin:machine", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "ss:tags", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "tags", + "description": "Comma separated tag values", + "type": "String", + "key": "ss:tags", + "creation": "2017-04-03 12:15:08.626 UTC", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "ss:category", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "category", + "description": "Module category", + "type": "String", + "key": "ss:category", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "Image", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "machine:statecustom", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "statecustom", + "description": "Custom state", + "type": "String", + "key": "machine:statecustom", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "WordPress ready to go!", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:nuvlabox-bertil-ohlin.custom.vm.template", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "nuvlabox-bertil-ohlin.custom.vm.template", + "description": "Additional custom VM template", + "type": "String", + "key": "machine:nuvlabox-bertil-ohlin.custom.vm.template", + "creation": "2017-04-03 12:15:08.626 UTC", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "ss:recovery.mode", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "recovery.mode", + "description": "Run abort flag, set when aborting", + "type": "String", + "key": "ss:recovery.mode", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "false", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "machine:admin_password", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "admin_password", + "description": "admin password", + "type": "String", + "key": "machine:admin_password", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "8rsBZBM659jK", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:disk.attach.size", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "disk.attach.size", + "description": "Size of the extra disk to attach to the VM during vertical scaling", + "type": "String", + "key": "machine:disk.attach.size", + "creation": "2017-04-03 12:15:08.626 UTC", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:nuvlabox-bertil-ohlin.ram", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "nuvlabox-bertil-ohlin.ram", + "description": "Amount of RAM, in GB", + "type": "String", + "key": "machine:nuvlabox-bertil-ohlin.ram", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "0.5", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:pre.scale.done", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "pre.scale.done", + "description": "Node instance sets to 'true' after running pre-scale script", + "type": "String", + "key": "machine:pre.scale.done", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "false", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:instanceid", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "instanceid", + "description": "Cloud instance id", + "type": "String", + "key": "machine:instanceid", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "23", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:network", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "network", + "description": "Network type", + "type": "String", + "key": "machine:network", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "Public", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:hostname", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "hostname", + "description": "hostname/ip of the image", + "type": "String", + "key": "machine:hostname", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "172.16.0.13", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:abort", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "abort", + "description": "Machine abort flag, set when aborting", + "type": "String", + "key": "machine:abort", + "creation": "2017-04-03 12:15:08.626 UTC", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:mysql_password", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "mysql_password", + "description": "MySQL password", + "type": "String", + "key": "machine:mysql_password", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "AX9ytTh2vWF4", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:extra.disk.volatile", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "extra.disk.volatile", + "description": "Volatile extra disk in GB", + "type": "String", + "key": "machine:extra.disk.volatile", + "creation": "2017-04-03 12:15:08.626 UTC", + "group": "machine", + "mapsOthers": false + } + }, + { + "string": "machine:image.id", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "image.id", + "description": "Cloud image id", + "type": "String", + "key": "machine:image.id", + "creation": "2017-04-03 12:15:08.626 UTC", + "content": "8", + "group": "machine", + "mapsOthers": false + } + } + ], + "class": "org.hibernate.collection.internal.PersistentMap" + }, + "cloudServiceNames": "nuvlabox-bertil-ohlin", + "startTime": "2017-04-03 12:15:08.539 UTC", + "state": "Done", + "endTime": "2017-04-04 06:46:58.571 UTC", + "category": "Image", + "user": "khaled", + "parameters": { + "entry": [ + { + "string": "machine:wordpress_title", + "parameter": { + "readonly": false, + "name": "machine:wordpress_title", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "Change Me Please 2", + "order_": 0, + "order": 0 + } + }, + { + "string": "machine:run-build-recipes", + "parameter": { + "readonly": false, + "name": "machine:run-build-recipes", + "description": "Define if the SlipStream executor should run build recipes.", + "category": "General", + "type": "String", + "mandatory": false, + "value": "false", + "order_": 0, + "order": 0 + } + }, + { + "string": "machine:cloudservice", + "parameter": { + "readonly": false, + "name": "machine:cloudservice", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "nuvlabox-bertil-ohlin", + "order_": 0, + "order": 0 + } + }, + { + "string": "General.keep-running", + "parameter": { + "readonly": false, + "name": "General.keep-running", + "description": "Keep running after deployment", + "category": "General", + "type": "String", + "mandatory": false, + "value": "always", + "order_": 0, + "order": 0 + } + }, + { + "string": "garbage_collected", + "parameter": { + "readonly": false, + "name": "garbage_collected", + "description": "true if the Run was already garbage collected", + "category": "General", + "type": "String", + "mandatory": false, + "value": "false", + "order_": 0, + "order": 0 + } + }, + { + "string": "machine:admin_email", + "parameter": { + "readonly": false, + "name": "machine:admin_email", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "admin@example.com", + "order_": 0, + "order": 0 + } + } + ], + "class": "org.hibernate.collection.internal.PersistentMap" + }, + "creation": "2017-04-03 12:15:08.539 UTC" + } +} \ No newline at end of file diff --git a/ssclj/jar/test-resources/deployment-service-testing.json b/ssclj/jar/test-resources/deployment-service-testing.json new file mode 100644 index 000000000..ff17af395 --- /dev/null +++ b/ssclj/jar/test-resources/deployment-service-testing.json @@ -0,0 +1,11271 @@ +{ + "run": { + "cloudServiceNamesList": { + "string": "nuvlabox-carl-cori", + "length": 1 + }, + "module": { + "isLatestVersion": true, + "parentUri": "module/examples/tutorials/service-testing", + "commit": { + "author": "super", + "comment": "update image ids" + }, + "description": "Deployment binding the apache server and the test client node(s).", + "resourceUri": "module/examples/tutorials/service-testing/system/1940", + "version": 1940, + "targets": { + "class": "org.hibernate.collection.internal.PersistentSet" + }, + "deleted": false, + "logoLink": "", + "nodes": { + "entry": [ + { + "node": { + "multiplicity": 1, + "image": { + "outputParametersExpanded": { + "entry": [ + { + "string": "hostname", + "parameter": { + "readonly": false, + "isSet": false, + "name": "hostname", + "description": "hostname/ip of the image", + "category": "Output", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "instanceid", + "parameter": { + "readonly": false, + "isSet": false, + "name": "instanceid", + "description": "Cloud instance id", + "category": "Output", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "port", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "8080", + "name": "port", + "description": "Port", + "category": "Output", + "type": "String", + "mandatory": false, + "value": "8080", + "order_": 0, + "order": 0 + } + }, + { + "string": "ready", + "parameter": { + "readonly": false, + "isSet": false, + "name": "ready", + "description": "Server ready to recieve connections", + "category": "Output", + "type": "String", + "mandatory": false, + "order_": 0, + "order": 0 + } + } + ], + "class": "java.util.HashMap" + }, + "cloudImageIdentifiers": { + "class": "org.hibernate.collection.internal.PersistentSet" + }, + "notes": { + "length": 0 + }, + "parentUri": "module/examples/tutorials/service-testing", + "commit": { + "author": "lionel", + "comment": "Updated instance type for cyclone-de1" + }, + "recipe": "#!/bin/sh -xe\r\n\r\napt-get update -y\r\napt-get install -y apache2\r\n", + "packagesExpanded": { + "class": "java.util.HashSet" + }, + "description": "Apache web server appliance with custom landing page.", + "moduleReferenceUri": "module/examples/images/ubuntu-14.04", + "targets": { + "class": "org.hibernate.collection.internal.PersistentSet", + "target": [ + { + "name": "report", + "content": "#!/bin/sh -x\r\ncp /var/log/apache2/access.log $SLIPSTREAM_REPORT_DIR\r\ncp /var/log/apache2/error.log $SLIPSTREAM_REPORT_DIR" + }, + { + "name": "onvmremove" + }, + { + "name": "execute", + "content": "#!/bin/sh -xe\r\n\r\ndefault_site_location='/etc/apache2/sites-available/default'\r\nif [ ! -f $default_site_location ]; then\r\n default_site_location='/etc/apache2/sites-available/000-default.conf'\r\nfi\r\n\r\nhttp_root_location='/var/www/html'\r\nif [ ! -d $http_root_location ]; then\r\n http_root_location='/var/www'\r\nfi\r\n\r\necho 'Hello from Apache deployed by SlipStream!' > $http_root_location/data.txt\r\n\r\nservice apache2 stop\r\nport=$(ss-get port)\r\n\r\nsed -i -e 's/^Listen.*$/Listen '$port'/' /etc/apache2/ports.conf\r\nsed -i -e 's/^NameVirtualHost.*$/NameVirtualHost *:'$port'/' /etc/apache2/ports.conf\r\nsed -i -e 's/^/' $default_site_location\r\nservice apache2 start\r\nss-set ready true\r\nurl=\"http://$(ss-get hostname):$port\"\r\nss-set url.service $url\r\nss-set ss:url.service $url\r\n" + }, + { + "name": "prescale" + }, + { + "name": "onvmadd" + }, + { + "name": "postscale" + } + ] + }, + "platform": "ubuntu", + "loginUser": "root", + "logoLink": "https://nuv.la/images/modules-logos/apache-httpd.svg", + "targetsExpanded": { + "targetExpanded": [ + { + "name": "report", + "subTarget": [ + { + "moduleShortName": "ubuntu-14.04", + "name": "report", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + }, + { + "moduleShortName": "apache", + "name": "report", + "moduleUri": "module/examples/tutorials/service-testing/apache/13791", + "content": "#!/bin/sh -x\r\ncp /var/log/apache2/access.log $SLIPSTREAM_REPORT_DIR\r\ncp /var/log/apache2/error.log $SLIPSTREAM_REPORT_DIR", + "order": 2 + } + ] + }, + { + "name": "postscale", + "subTarget": [ + { + "moduleShortName": "ubuntu-14.04", + "name": "postscale", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + }, + { + "moduleShortName": "apache", + "name": "postscale", + "moduleUri": "module/examples/tutorials/service-testing/apache/13791", + "order": 2 + } + ] + }, + { + "name": "execute", + "subTarget": [ + { + "moduleShortName": "apache", + "name": "execute", + "moduleUri": "module/examples/tutorials/service-testing/apache/13791", + "content": "#!/bin/sh -xe\r\n\r\ndefault_site_location='/etc/apache2/sites-available/default'\r\nif [ ! -f $default_site_location ]; then\r\n default_site_location='/etc/apache2/sites-available/000-default.conf'\r\nfi\r\n\r\nhttp_root_location='/var/www/html'\r\nif [ ! -d $http_root_location ]; then\r\n http_root_location='/var/www'\r\nfi\r\n\r\necho 'Hello from Apache deployed by SlipStream!' > $http_root_location/data.txt\r\n\r\nservice apache2 stop\r\nport=$(ss-get port)\r\n\r\nsed -i -e 's/^Listen.*$/Listen '$port'/' /etc/apache2/ports.conf\r\nsed -i -e 's/^NameVirtualHost.*$/NameVirtualHost *:'$port'/' /etc/apache2/ports.conf\r\nsed -i -e 's/^/' $default_site_location\r\nservice apache2 start\r\nss-set ready true\r\nurl=\"http://$(ss-get hostname):$port\"\r\nss-set url.service $url\r\nss-set ss:url.service $url\r\n", + "order": 2 + }, + { + "moduleShortName": "ubuntu-14.04", + "name": "execute", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "content": "#!/bin/bash -xe\r\n\r\n# set the service url to SSH url\r\nurl=$(ss-get --timeout=180 url.ssh)\r\nss-set url.service \"${url}\"\r\nss-set ss:url.service \"${url}\"\r\n\r\n", + "order": 1 + } + ] + }, + { + "name": "prescale", + "subTarget": [ + { + "moduleShortName": "apache", + "name": "prescale", + "moduleUri": "module/examples/tutorials/service-testing/apache/13791", + "order": 2 + }, + { + "moduleShortName": "ubuntu-14.04", + "name": "prescale", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + } + ] + }, + { + "name": "prerecipe", + "subTarget": [ + { + "moduleShortName": "apache", + "name": "prerecipe", + "moduleUri": "module/examples/tutorials/service-testing/apache/13791", + "order": 2 + }, + { + "moduleShortName": "ubuntu-14.04", + "name": "prerecipe", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + } + ] + }, + { + "name": "onvmadd", + "subTarget": [ + { + "moduleShortName": "apache", + "name": "onvmadd", + "moduleUri": "module/examples/tutorials/service-testing/apache/13791", + "order": 2 + }, + { + "moduleShortName": "ubuntu-14.04", + "name": "onvmadd", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + } + ] + }, + { + "name": "recipe", + "subTarget": [ + { + "moduleShortName": "ubuntu-14.04", + "name": "recipe", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + }, + { + "moduleShortName": "apache", + "name": "recipe", + "moduleUri": "module/examples/tutorials/service-testing/apache/13791", + "content": "#!/bin/sh -xe\r\n\r\napt-get update -y\r\napt-get install -y apache2\r\n", + "order": 2 + } + ] + }, + { + "name": "onvmremove", + "subTarget": [ + { + "moduleShortName": "ubuntu-14.04", + "name": "onvmremove", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + }, + { + "moduleShortName": "apache", + "name": "onvmremove", + "moduleUri": "module/examples/tutorials/service-testing/apache/13791", + "order": 2 + } + ] + } + ], + "class": "java.util.HashSet" + }, + "creation": "2013-12-03 16:04:03.426 UTC", + "authz": { + "owner": "sixsq", + "groupMembers": { + "string": [ + "elegoff", + "khaled", + "konstan", + "lionel", + "loomis", + "meb", + "cjdcsixsq" + ], + "class": "java.util.ArrayList" + }, + "ownerGet": true, + "ownerDelete": true, + "groupPost": true, + "publicPost": true, + "publicCreateChildren": false, + "ownerCreateChildren": true, + "publicGet": true, + "inheritedGroupMembers": true, + "ownerPost": true, + "groupCreateChildren": false, + "publicPut": false, + "groupGet": true, + "groupDelete": false, + "ownerPut": true, + "publicDelete": false, + "groupPut": true + }, + "buildStates": { + "class": "java.util.HashSet", + "buildState": [ + { + "builtOn": "", + "moduleUri": "module/examples/images/ubuntu-14.04/13947" + }, + { + "builtOn": "", + "moduleUri": "module/examples/tutorials/service-testing/apache/13791" + } + ] + }, + "isLatestVersion": true, + "prerecipe": "", + "resourceUri": "module/examples/tutorials/service-testing/apache/13791", + "packages": { + "class": "org.hibernate.collection.internal.PersistentSet" + }, + "version": 13791, + "inputParametersExpanded": { + "class": "java.util.HashMap" + }, + "deleted": false, + "name": "examples/tutorials/service-testing/apache", + "placementPolicy": "", + "lastModified": "2017-07-23 19:41:17.760 UTC", + "isBase": false, + "category": "Image", + "shortName": "apache", + "parameters": { + "entry": [ + { + "string": "nuvlabox-albert-einstein.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-albert-einstein.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-albert-einstein", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-scissor2.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-scissor2.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-scissor2", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "scissor-fr3.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "scissor-fr3.ram", + "description": "Amount of RAM, in GB", + "category": "scissor-fr3", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "cyclone-de1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "cyclone-de1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "cyclone-de1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "hostname", + "parameter": { + "readonly": false, + "isSet": false, + "name": "hostname", + "description": "hostname/ip of the image", + "category": "Output", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "cyclone-fr1.disks.bus.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "virtio", + "name": "cyclone-fr1.disks.bus.type", + "description": "VM disks bus type", + "category": "cyclone-fr1", + "type": "Enum", + "mandatory": true, + "value": "virtio", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "virtio", + "scsi" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-arthur-harden.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-arthur-harden.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-arthur-harden", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-demo.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-demo.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-demo", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-arthur-harden.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-arthur-harden.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-arthur-harden", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "ifb-bird-stack.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ifb-bird-stack.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ifb-bird-stack", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-us-west-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-us-west-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-us-west-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-eu-west-2.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-eu-west-2.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-eu-west-2", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "scissor-fr3.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "scissor-fr3.contextualization.type", + "description": "Contextualization type", + "category": "scissor-fr3", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-cecil-powell.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-cecil-powell.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-cecil-powell", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "ec2-sa-east-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-sa-east-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-sa-east-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "nuvlabox-stanley-cohen.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-stanley-cohen.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-stanley-cohen", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-max-born.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-max-born.network.specific.name", + "description": "Network name", + "category": "nuvlabox-max-born", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "scissor-fr2.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "scissor-fr2.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "scissor-fr2", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-christiane-n-volhard.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-christiane-n-volhard.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-christiane-n-volhard", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "teidehpc-es-tfs1.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "teidehpc-es-tfs1.ram", + "description": "Amount of RAM, in GB", + "category": "teidehpc-es-tfs1", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "ec2-ap-northeast-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-ap-northeast-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-ap-northeast-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-carl-cori.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-carl-cori.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-carl-cori", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-bertil-ohlin.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-bertil-ohlin.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-bertil-ohlin", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "eo-cesnet-cz1.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "eo-cesnet-cz1.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "eo-cesnet-cz1", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-cecil-powell.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-cecil-powell.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-cecil-powell", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-max-planck.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-max-planck.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-max-planck", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-christiane-nusslein-volhard.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-christiane-nusslein-volhard.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-christiane-nusslein-volhard", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 0, + "order": 0 + } + }, + { + "string": "cyclone-fr2.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "cyclone-fr2.security.groups", + "description": "Security Groups (comma separated list)", + "category": "cyclone-fr2", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-yves-chauvin.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-yves-chauvin.network.specific.name", + "description": "Network name", + "category": "nuvlabox-yves-chauvin", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "nuvlabox-cecil-powell.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-cecil-powell.network.specific.name", + "description": "Network name", + "category": "nuvlabox-cecil-powell", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "ec2-ap-southeast-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-ap-southeast-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-ap-southeast-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-henry-dunant.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-henry-dunant.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-henry-dunant", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "eo-cesnet-cz1.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "eo-cesnet-cz1.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "eo-cesnet-cz1", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-max-born.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-max-born.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-max-born", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-christiane-nusslein-volhard.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-christiane-nusslein-volhard.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-christiane-nusslein-volhard", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-felix-bloch.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-felix-bloch.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-felix-bloch", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-albert-einstein.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-albert-einstein.network.specific.name", + "description": "Network name", + "category": "nuvlabox-albert-einstein", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "ifb-genouest-genostack.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ifb-genouest-genostack.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ifb-genouest-genostack", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-james-chadwick.disks.bus.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "virtio", + "name": "nuvlabox-james-chadwick.disks.bus.type", + "description": "VM disks bus type", + "category": "nuvlabox-james-chadwick", + "type": "Enum", + "mandatory": true, + "value": "virtio", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "virtio", + "scsi" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-cecil-powell.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-cecil-powell.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-cecil-powell", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-scissor2.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-scissor2.network.specific.name", + "description": "Network name", + "category": "nuvlabox-scissor2", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "nuvlabox-max-born.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-max-born.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-max-born", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-arthur-harden.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-arthur-harden.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-arthur-harden", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-yves-chauvin.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-yves-chauvin.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-yves-chauvin", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "ifb-genouest-genostack.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small", + "name": "ifb-genouest-genostack.instance.type", + "description": "Instance type (flavor)", + "category": "ifb-genouest-genostack", + "type": "String", + "mandatory": true, + "value": "m1.small", + "order_": 0, + "order": 0 + } + }, + { + "string": "ifb-core-pilot.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ifb-core-pilot.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ifb-core-pilot", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-scissor2.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-scissor2.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-scissor2", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "ultimum-cz1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "Basic", + "name": "ultimum-cz1.instance.type", + "description": "Instance type (flavor)", + "category": "ultimum-cz1", + "type": "String", + "mandatory": true, + "value": "Basic", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-bertil-ohlin.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-bertil-ohlin.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-bertil-ohlin", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-yves-chauvin.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-yves-chauvin.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-yves-chauvin", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-james-chadwick.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-james-chadwick.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-james-chadwick", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "atos-es1.ram", + "parameter": { + "readonly": false, + "isSet": false, + "name": "atos-es1.ram", + "description": "Amount of RAM, in GB", + "category": "atos-es1", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "open-telekom-de1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "open-telekom-de1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "open-telekom-de1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-albert-einstein.cpu", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-albert-einstein.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-albert-einstein", + "type": "String", + "mandatory": true, + "order_": 10, + "order": 10 + } + }, + { + "string": "ec2-us-west-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-us-west-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-us-west-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "scissor-fr3.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "scissor-fr3.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "scissor-fr3", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-demo.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "micro", + "name": "nuvlabox-demo.instance.type", + "description": "Instance type", + "category": "nuvlabox-demo", + "type": "Enum", + "mandatory": true, + "value": "micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "micro", + "small", + "medium", + "large" + ], + "length": 4 + } + } + }, + { + "string": "nuvlabox-yves-chauvin.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-yves-chauvin.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-yves-chauvin", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "ifb-bird-stack.instance.type", + "parameter": { + "readonly": false, + "isSet": false, + "name": "ifb-bird-stack.instance.type", + "description": "Instance type (flavor)", + "category": "ifb-bird-stack", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "ifb-bistro-iphc.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small", + "name": "ifb-bistro-iphc.instance.type", + "description": "Instance type (flavor)", + "category": "ifb-bistro-iphc", + "type": "String", + "mandatory": true, + "value": "m1.small", + "order_": 0, + "order": 0 + } + }, + { + "string": "port", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "8080", + "name": "port", + "description": "Port", + "category": "Output", + "type": "String", + "mandatory": false, + "value": "8080", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-demo.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-demo.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-demo", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 0, + "order": 0 + } + }, + { + "string": "ifb-prabi-girofle.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small", + "name": "ifb-prabi-girofle.instance.type", + "description": "Instance type (flavor)", + "category": "ifb-prabi-girofle", + "type": "String", + "mandatory": true, + "value": "m1.small", + "order_": 0, + "order": 0 + } + }, + { + "string": "teidehpc-es-tfs1.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "teidehpc-es-tfs1.contextualization.type", + "description": "Contextualization type", + "category": "teidehpc-es-tfs1", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "cyclone-fr2.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small", + "name": "cyclone-fr2.instance.type", + "description": "Instance type (flavor)", + "category": "cyclone-fr2", + "type": "String", + "mandatory": true, + "value": "m1.small", + "order_": 0, + "order": 0 + } + }, + { + "string": "ram.GB", + "parameter": { + "readonly": false, + "isSet": false, + "name": "ram.GB", + "description": "RAM in GB", + "category": "Cloud", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-albert-einstein.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-albert-einstein.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-albert-einstein", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-stanley-cohen.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-stanley-cohen.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-stanley-cohen", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-cecil-powell.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-cecil-powell.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-cecil-powell", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-max-born.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-max-born.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-max-born", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "cyclone-fr1.ram", + "parameter": { + "readonly": false, + "isSet": false, + "name": "cyclone-fr1.ram", + "description": "Amount of RAM, in GB", + "category": "cyclone-fr1", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "cyclone-de1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "small", + "name": "cyclone-de1.instance.type", + "description": "Instance type (flavor)", + "category": "cyclone-de1", + "type": "String", + "mandatory": true, + "value": "small", + "order_": 0, + "order": 0 + } + }, + { + "string": "exoscale-ch-dk.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "exoscale-ch-dk.security.groups", + "description": "Security Groups (comma separated list)", + "category": "exoscale-ch-dk", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "scissor-fr1.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "scissor-fr1.network.specific.name", + "description": "Network name", + "category": "scissor-fr1", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "nuvlabox-christiane-n-volhard.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-christiane-n-volhard.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-christiane-n-volhard", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-henry-dunant.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-henry-dunant.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-henry-dunant", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-christiane-nusslein-volhard.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-christiane-nusslein-volhard.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-christiane-nusslein-volhard", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-us-east-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-us-east-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-us-east-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "nuvlabox-stanley-cohen.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-stanley-cohen.network.specific.name", + "description": "Network name", + "category": "nuvlabox-stanley-cohen", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "nuvlabox-felix-bloch.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-felix-bloch.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-felix-bloch", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-max-planck.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-max-planck.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-max-planck", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "teidehpc-es-tfs1.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "teidehpc-es-tfs1.network.specific.name", + "description": "Network name", + "category": "teidehpc-es-tfs1", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "eo-cloudferro-pl1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "eo1.small", + "name": "eo-cloudferro-pl1.instance.type", + "description": "Instance type (flavor)", + "category": "eo-cloudferro-pl1", + "type": "String", + "mandatory": true, + "value": "eo1.small", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-scissor1.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-scissor1.network.specific.name", + "description": "Network name", + "category": "nuvlabox-scissor1", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "softlayer-it-mil01.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "2 CPU, 2GB ram, 100GB", + "name": "softlayer-it-mil01.instance.type", + "description": "Instance type (flavor)", + "category": "softlayer-it-mil01", + "type": "String", + "mandatory": true, + "value": "2 CPU, 2GB ram, 100GB", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-felix-bloch.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-felix-bloch.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-felix-bloch", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "cyfronet-pl1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "CPU-1.RAM-512MB.DISK-10GB", + "name": "cyfronet-pl1.instance.type", + "description": "Instance type (flavor)", + "category": "cyfronet-pl1", + "type": "String", + "mandatory": true, + "value": "CPU-1.RAM-512MB.DISK-10GB", + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-eu-west.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-eu-west.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-eu-west", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-bertil-ohlin.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-bertil-ohlin.network.specific.name", + "description": "Network name", + "category": "nuvlabox-bertil-ohlin", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "nuvlabox-max-planck.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-max-planck.network.specific.name", + "description": "Network name", + "category": "nuvlabox-max-planck", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "atos-es1.cpu", + "parameter": { + "readonly": false, + "isSet": false, + "name": "atos-es1.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "atos-es1", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "cpu.nb", + "parameter": { + "readonly": false, + "isSet": false, + "name": "cpu.nb", + "description": "Number of CPUs", + "category": "Cloud", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-eu-central-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-eu-central-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-eu-central-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "ec2-us-west-2.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-us-west-2.instance.type", + "description": "Cloud instance type", + "category": "ec2-us-west-2", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "eo-cesnet-cz1.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "cloud-init", + "name": "eo-cesnet-cz1.contextualization.type", + "description": "Contextualization type", + "category": "eo-cesnet-cz1", + "type": "Enum", + "mandatory": true, + "value": "cloud-init", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-felix-bloch.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-felix-bloch.network.specific.name", + "description": "Network name", + "category": "nuvlabox-felix-bloch", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "nuvlabox-christiane-n-volhard.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-christiane-n-volhard.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-christiane-n-volhard", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-demo.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-demo.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-demo", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-scissor1.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-scissor1.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-scissor1", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-albert-einstein.ram", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-albert-einstein.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-albert-einstein", + "type": "String", + "mandatory": true, + "order_": 11, + "order": 11 + } + }, + { + "string": "scissor-fr2.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "scissor-fr2.contextualization.type", + "description": "Contextualization type", + "category": "scissor-fr2", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-scissor1.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-scissor1.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-scissor1", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "exoscale-ch-gva.disk", + "parameter": { + "instructions": "Some disk sizes might not be available with all operating system and all instance type", + "isSet": true, + "defaultValue": "10G", + "description": "Size of the root disk", + "type": "Enum", + "mandatory": true, + "order_": 20, + "readonly": false, + "name": "exoscale-ch-gva.disk", + "category": "exoscale-ch-gva", + "value": "10G", + "order": 20, + "enumValues": { + "string": [ + "10G", + "50G", + "100G", + "200G", + "400G", + "800G", + "1600G" + ], + "length": 7 + } + } + }, + { + "string": "nuvlabox-yves-chauvin.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-yves-chauvin.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-yves-chauvin", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-albert-einstein.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-albert-einstein.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-albert-einstein", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-max-born.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-max-born.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-max-born", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "ec2-eu-west-2.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-eu-west-2.instance.type", + "description": "Cloud instance type", + "category": "ec2-eu-west-2", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "nuvlabox-james-chadwick.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-james-chadwick.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-james-chadwick", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "cyclone-fr1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small", + "name": "cyclone-fr1.instance.type", + "description": "Cloud instance type", + "category": "cyclone-fr1", + "type": "Enum", + "mandatory": true, + "value": "m1.small", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "m1.small", + "c1.medium", + "m1.large", + "m1.xlarge", + "c1.xlarge", + "t1.micro", + "standard.xsmall" + ], + "length": 7 + } + } + }, + { + "string": "scissor-fr1.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "scissor-fr1.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "scissor-fr1", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "ec2-ap-northeast-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-ap-northeast-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-ap-northeast-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "ec2-ap-southeast-2.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-ap-southeast-2.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-ap-southeast-2", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "teidehpc-es-tfs1.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "teidehpc-es-tfs1.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "teidehpc-es-tfs1", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-arthur-harden.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-arthur-harden.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-arthur-harden", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-scissor2.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-scissor2.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-scissor2", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-scissor1.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-scissor1.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-scissor1", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-henry-dunant.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-henry-dunant.network.specific.name", + "description": "Network name", + "category": "nuvlabox-henry-dunant", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "atos-es1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small", + "name": "atos-es1.instance.type", + "description": "Cloud instance type", + "category": "atos-es1", + "type": "Enum", + "mandatory": true, + "value": "m1.small", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "m1.small", + "c1.medium", + "m1.large", + "m1.xlarge", + "c1.xlarge", + "t1.micro", + "standard.xsmall" + ], + "length": 7 + } + } + }, + { + "string": "scissor-fr1.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "scissor-fr1.ram", + "description": "Amount of RAM, in GB", + "category": "scissor-fr1", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "ultimum-cz1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ultimum-cz1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ultimum-cz1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-christiane-n-volhard.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-christiane-n-volhard.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-christiane-n-volhard", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-stanley-cohen.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-stanley-cohen.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-stanley-cohen", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-henry-dunant.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-henry-dunant.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-henry-dunant", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-henry-dunant.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-henry-dunant.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-henry-dunant", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "advania-se1.instance.type", + "parameter": { + "readonly": false, + "isSet": false, + "name": "advania-se1.instance.type", + "description": "Instance type (flavor)", + "category": "advania-se1", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "ifb-core-pilot.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small", + "name": "ifb-core-pilot.instance.type", + "description": "Instance type (flavor)", + "category": "ifb-core-pilot", + "type": "String", + "mandatory": true, + "value": "m1.small", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-james-chadwick.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-james-chadwick.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-james-chadwick", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-bertil-ohlin.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-bertil-ohlin.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-bertil-ohlin", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-bertil-ohlin.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-bertil-ohlin.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-bertil-ohlin", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "eo-cesnet-cz1.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "eo-cesnet-cz1.network.specific.name", + "description": "Network name", + "category": "eo-cesnet-cz1", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "ec2-us-east-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-us-east-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-us-east-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "cyclone-fr1.cpu", + "parameter": { + "readonly": false, + "isSet": false, + "name": "cyclone-fr1.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "cyclone-fr1", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-max-born.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-max-born.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-max-born", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "ifb-bistro-iphc.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ifb-bistro-iphc.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ifb-bistro-iphc", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "exoscale-ch-gva.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "exoscale-ch-gva.security.groups", + "description": "Security Groups (comma separated list)", + "category": "exoscale-ch-gva", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "disk.GB", + "parameter": { + "readonly": false, + "isSet": false, + "name": "disk.GB", + "description": "Disk in GB", + "category": "Cloud", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-max-planck.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "micro", + "name": "nuvlabox-max-planck.instance.type", + "description": "Instance type", + "category": "nuvlabox-max-planck", + "type": "Enum", + "mandatory": true, + "value": "micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "micro", + "small", + "medium", + "large" + ], + "length": 4 + } + } + }, + { + "string": "ec2-eu-central-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-eu-central-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-eu-central-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-james-chadwick.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "micro", + "name": "nuvlabox-james-chadwick.instance.type", + "description": "Instance type", + "category": "nuvlabox-james-chadwick", + "type": "Enum", + "mandatory": true, + "value": "micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "micro", + "small", + "medium", + "large" + ], + "length": 4 + } + } + }, + { + "string": "nuvlabox-max-planck.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-max-planck.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-max-planck", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-carl-cori.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-carl-cori.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-carl-cori", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-henry-dunant.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-henry-dunant.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-henry-dunant", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-christiane-n-volhard.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-christiane-n-volhard.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-christiane-n-volhard", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "ec2-sa-east-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-sa-east-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-sa-east-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-yves-chauvin.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-yves-chauvin.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-yves-chauvin", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-james-chadwick.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-james-chadwick.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-james-chadwick", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "open-telekom-de1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "c1.medium", + "name": "open-telekom-de1.instance.type", + "description": "Instance type (flavor)", + "category": "open-telekom-de1", + "type": "String", + "mandatory": true, + "value": "c1.medium", + "order_": 0, + "order": 0 + } + }, + { + "string": "advania-se1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "advania-se1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "advania-se1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-scissor1.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-scissor1.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-scissor1", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-carl-cori.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-carl-cori.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-carl-cori", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-scissor1.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-scissor1.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-scissor1", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-scissor2.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-scissor2.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-scissor2", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "scissor-fr2.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "scissor-fr2.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "scissor-fr2", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "azure-west-europe.forwarded.ports", + "parameter": { + "instructions": "Ports that will be forwarded from the public IP of the Azure cloud service. The port 22 (SSH) on Linux machines and the port 3389 (RDP) on Windows machines are already forwarded", + "readonly": false, + "isSet": false, + "name": "azure-west-europe.forwarded.ports", + "description": "Forwarded ports (comma separated list)", + "category": "azure-west-europe", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-stanley-cohen.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-stanley-cohen.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-stanley-cohen", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "scissor-fr3.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "scissor-fr3.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "scissor-fr3", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-felix-bloch.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-felix-bloch.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-felix-bloch", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "exoscale-ch-gva.instance.type", + "parameter": { + "instructions": "You might have to request access to Exoscale for some instance types", + "isSet": true, + "defaultValue": "Small", + "description": "Cloud instance type", + "type": "Enum", + "mandatory": true, + "order_": 10, + "readonly": false, + "name": "exoscale-ch-gva.instance.type", + "category": "exoscale-ch-gva", + "value": "Small", + "order": 10, + "enumValues": { + "string": [ + "Micro", + "Tiny", + "Small", + "Medium", + "Large", + "Extra-large", + "Huge", + "Mega", + "Titan", + "GPU-small", + "GPU-huge" + ], + "length": 11 + } + } + }, + { + "string": "atos-es1.disks.bus.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "virtio", + "name": "atos-es1.disks.bus.type", + "description": "VM disks bus type", + "category": "atos-es1", + "type": "Enum", + "mandatory": true, + "value": "virtio", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "virtio", + "scsi" + ], + "length": 2 + } + } + }, + { + "string": "scissor-fr3.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "scissor-fr3.network.specific.name", + "description": "Network name", + "category": "scissor-fr3", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "extra.disk.volatile", + "parameter": { + "readonly": false, + "isSet": false, + "name": "extra.disk.volatile", + "description": "Volatile extra disk in GB", + "category": "Cloud", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-arthur-harden.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-arthur-harden.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-arthur-harden", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "instanceid", + "parameter": { + "readonly": false, + "isSet": false, + "name": "instanceid", + "description": "Cloud instance id", + "category": "Output", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-albert-einstein.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "micro", + "name": "nuvlabox-albert-einstein.instance.type", + "description": "Instance type", + "category": "nuvlabox-albert-einstein", + "type": "Enum", + "mandatory": true, + "value": "micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "micro", + "small", + "medium", + "large" + ], + "length": 4 + } + } + }, + { + "string": "nuvlabox-christiane-n-volhard.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-christiane-n-volhard.network.specific.name", + "description": "Network name", + "category": "nuvlabox-christiane-n-volhard", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "nuvlabox-max-planck.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-max-planck.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-max-planck", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "scissor-fr2.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "scissor-fr2.ram", + "description": "Amount of RAM, in GB", + "category": "scissor-fr2", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "teidehpc-es-tfs1.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "teidehpc-es-tfs1.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "teidehpc-es-tfs1", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-demo.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-demo.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-demo", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 0, + "order": 0 + } + }, + { + "string": "scissor-fr2.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "scissor-fr2.network.specific.name", + "description": "Network name", + "category": "scissor-fr2", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "eo-cloudferro-pl1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "eo-cloudferro-pl1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "eo-cloudferro-pl1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-james-chadwick.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-james-chadwick.network.specific.name", + "description": "Network name", + "category": "nuvlabox-james-chadwick", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "scissor-fr1.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "scissor-fr1.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "scissor-fr1", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-arthur-harden.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-arthur-harden.network.specific.name", + "description": "Network name", + "category": "nuvlabox-arthur-harden", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "nuvlabox-christiane-nusslein-volhard.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-christiane-nusslein-volhard.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-christiane-nusslein-volhard", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-stanley-cohen.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-stanley-cohen.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-stanley-cohen", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "ifb-prabi-girofle.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ifb-prabi-girofle.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ifb-prabi-girofle", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-carl-cori.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-carl-cori.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-carl-cori", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "ec2-ap-southeast-2.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-ap-southeast-2.instance.type", + "description": "Cloud instance type", + "category": "ec2-ap-southeast-2", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "cyfronet-pl1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "cyfronet-pl1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "cyfronet-pl1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "network", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "Public", + "name": "network", + "description": "Network type", + "category": "Cloud", + "type": "Enum", + "mandatory": true, + "value": "Public", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "Public", + "Private" + ], + "length": 2 + } + } + }, + { + "string": "azure-west-europe.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "Basic_A0", + "name": "azure-west-europe.instance.type", + "description": "Machine size", + "category": "azure-west-europe", + "type": "Enum", + "mandatory": true, + "value": "Basic_A0", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "Basic_A0", + "Basic_A1", + "Basic_A2", + "Basic_A3", + "Basic_A4", + "ExtraSmall", + "Small", + "Medium", + "Large", + "ExtraLarge", + "A5", + "A6", + "A7", + "A8", + "A9", + "A10", + "A11", + "Standard_D1", + "Standard_D2", + "Standard_D3", + "Standard_D4", + "Standard_D11", + "Standard_D12", + "Standard_D13", + "Standard_D14" + ], + "length": 25 + } + } + }, + { + "string": "nuvlabox-carl-cori.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-carl-cori.network.specific.name", + "description": "Network name", + "category": "nuvlabox-carl-cori", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "ready", + "parameter": { + "readonly": false, + "isSet": false, + "name": "ready", + "description": "Server ready to recieve connections", + "category": "Output", + "type": "String", + "mandatory": false, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-bertil-ohlin.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-bertil-ohlin.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-bertil-ohlin", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-scissor2.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-scissor2.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-scissor2", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-cecil-powell.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-cecil-powell.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-cecil-powell", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "eo-cesnet-cz1.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "eo-cesnet-cz1.ram", + "description": "Amount of RAM, in GB", + "category": "eo-cesnet-cz1", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-james-chadwick.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-james-chadwick.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-james-chadwick", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "ec2-eu-west.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-eu-west.instance.type", + "description": "Cloud instance type", + "category": "ec2-eu-west", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "cyclone-tb-it1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "os.1", + "name": "cyclone-tb-it1.instance.type", + "description": "Instance type (flavor)", + "category": "cyclone-tb-it1", + "type": "String", + "mandatory": true, + "value": "os.1", + "order_": 0, + "order": 0 + } + }, + { + "string": "exoscale-ch-dk.instance.type", + "parameter": { + "instructions": "You might have to request access to Exoscale for some instance types", + "isSet": true, + "defaultValue": "Micro", + "description": "Cloud instance type", + "type": "Enum", + "mandatory": true, + "order_": 10, + "readonly": false, + "name": "exoscale-ch-dk.instance.type", + "category": "exoscale-ch-dk", + "value": "Micro", + "order": 10, + "enumValues": { + "string": [ + "Micro", + "Tiny", + "Small", + "Medium", + "Large", + "Extra-large", + "Huge", + "Mega", + "Titan", + "GPU-small", + "GPU-huge" + ], + "length": 11 + } + } + }, + { + "string": "nuvlabox-carl-cori.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-carl-cori.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-carl-cori", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "cyclone-tb-it1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "cyclone-tb-it1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "cyclone-tb-it1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-ap-southeast-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-ap-southeast-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-ap-southeast-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "scissor-fr1.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "scissor-fr1.contextualization.type", + "description": "Contextualization type", + "category": "scissor-fr1", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-max-planck.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-max-planck.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-max-planck", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "exoscale-ch-dk.disk", + "parameter": { + "instructions": "Some disk sizes might not be available with all operating system and all instance type", + "isSet": true, + "defaultValue": "10G", + "description": "Size of the root disk", + "type": "Enum", + "mandatory": true, + "order_": 20, + "readonly": false, + "name": "exoscale-ch-dk.disk", + "category": "exoscale-ch-dk", + "value": "10G", + "order": 20, + "enumValues": { + "string": [ + "10G", + "50G", + "100G", + "200G", + "400G", + "800G", + "1600G" + ], + "length": 7 + } + } + }, + { + "string": "ec2-us-west-2.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-us-west-2.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-us-west-2", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-felix-bloch.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-felix-bloch.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-felix-bloch", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + } + ], + "class": "org.hibernate.collection.internal.PersistentMap" + } + }, + "imageUri": "module/examples/tutorials/service-testing/apache", + "deleted": false, + "notes": { + "length": 0 + }, + "parameterMappings": { + "class": "org.hibernate.collection.internal.PersistentMap" + }, + "name": "apache", + "maxProvisioningFailures": 0, + "parameters": { + "class": "org.hibernate.collection.internal.PersistentMap" + }, + "creation": "2015-10-20 08:40:43.893 UTC", + "cloudService": "default", + "network": "Public" + }, + "string": "apache" + }, + { + "node": { + "multiplicity": 1, + "image": { + "outputParametersExpanded": { + "entry": [ + { + "string": "hostname", + "parameter": { + "readonly": false, + "isSet": false, + "name": "hostname", + "description": "hostname/ip of the image", + "category": "Output", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "instanceid", + "parameter": { + "readonly": false, + "isSet": false, + "name": "instanceid", + "description": "Cloud instance id", + "category": "Output", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + } + ], + "class": "java.util.HashMap" + }, + "cloudImageIdentifiers": { + "class": "org.hibernate.collection.internal.PersistentSet" + }, + "notes": { + "length": 0 + }, + "parentUri": "module/examples/tutorials/service-testing", + "commit": { + "author": "lionel", + "comment": "Updated instance type for cyclone-de1" + }, + "recipe": "", + "packagesExpanded": { + "class": "java.util.HashSet" + }, + "description": "Web client tests server connectivity and verifies content.", + "moduleReferenceUri": "module/examples/images/ubuntu-14.04", + "targets": { + "class": "org.hibernate.collection.internal.PersistentSet", + "target": [ + { + "name": "postscale" + }, + { + "name": "report", + "content": "#!/bin/sh -x\r\ncp /tmp/data.txt $SLIPSTREAM_REPORT_DIR" + }, + { + "name": "onvmadd", + "content": "#!/bin/bash\r\nset -e\r\nset -x\r\n\r\nfunction on_apache() {\r\n for INSTANCE_NAME in $SLIPSTREAM_SCALING_VMS; do\r\n echo Processing $INSTANCE_NAME\r\n ss-get --timeout 360 $INSTANCE_NAME:ready\r\n host_name=$(ss-get $INSTANCE_NAME:hostname)\r\n echo \"New instance of $SLIPSTREAM_SCALING_NODE: $INSTANCE_NAME, $host_name\"\r\n done\r\n}\r\n\r\nfunction on_testclient() {\r\n for NAME in $SLIPSTREAM_SCALING_VMS; do\r\n echo \"test client $NAME was added\"\r\n done\r\n}\r\n\r\ncase $SLIPSTREAM_SCALING_NODE in\r\n \"apache\" )\r\n on_apache ;;\r\n \"testclient\" )\r\n on_testclient ;;\r\nesac" + }, + { + "name": "onvmremove" + }, + { + "name": "execute", + "content": "#!/bin/sh -xe\r\n\r\n[ \"$(ss-get apache:multiplicity)\" = \"0\" ] && { echo \"No web servers to test.\"; exit 0; }\r\n\r\n# Wait for the metadata to be resolved\r\nweb_server_ip=$(ss-get --timeout 360 webserver.hostname)\r\nweb_server_port=$(ss-get --timeout 360 webserver.port)\r\nss-get --timeout 360 webserver.ready\r\n\r\n# Execute the test\r\nENDPOINT=http://${web_server_ip}:${web_server_port}/data.txt\r\nwget -t 2 -O /tmp/data.txt ${ENDPOINT}\r\n[ \"$?\" = \"0\" ] && ss-set statecustom \"OK: $(cat /tmp/data.txt)\" || ss-abort \"Could not get the test file: ${ENDPOINT}\"\r\n" + }, + { + "name": "prescale" + } + ] + }, + "platform": "ubuntu", + "loginUser": "root", + "logoLink": "", + "targetsExpanded": { + "targetExpanded": [ + { + "name": "prerecipe", + "subTarget": [ + { + "moduleShortName": "ubuntu-14.04", + "name": "prerecipe", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + }, + { + "moduleShortName": "client", + "name": "prerecipe", + "moduleUri": "module/examples/tutorials/service-testing/client/13790", + "order": 2 + } + ] + }, + { + "name": "recipe", + "subTarget": [ + { + "moduleShortName": "ubuntu-14.04", + "name": "recipe", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + }, + { + "moduleShortName": "client", + "name": "recipe", + "moduleUri": "module/examples/tutorials/service-testing/client/13790", + "order": 2 + } + ] + }, + { + "name": "onvmadd", + "subTarget": [ + { + "moduleShortName": "ubuntu-14.04", + "name": "onvmadd", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + }, + { + "moduleShortName": "client", + "name": "onvmadd", + "moduleUri": "module/examples/tutorials/service-testing/client/13790", + "content": "#!/bin/bash\r\nset -e\r\nset -x\r\n\r\nfunction on_apache() {\r\n for INSTANCE_NAME in $SLIPSTREAM_SCALING_VMS; do\r\n echo Processing $INSTANCE_NAME\r\n ss-get --timeout 360 $INSTANCE_NAME:ready\r\n host_name=$(ss-get $INSTANCE_NAME:hostname)\r\n echo \"New instance of $SLIPSTREAM_SCALING_NODE: $INSTANCE_NAME, $host_name\"\r\n done\r\n}\r\n\r\nfunction on_testclient() {\r\n for NAME in $SLIPSTREAM_SCALING_VMS; do\r\n echo \"test client $NAME was added\"\r\n done\r\n}\r\n\r\ncase $SLIPSTREAM_SCALING_NODE in\r\n \"apache\" )\r\n on_apache ;;\r\n \"testclient\" )\r\n on_testclient ;;\r\nesac", + "order": 2 + } + ] + }, + { + "name": "report", + "subTarget": [ + { + "moduleShortName": "ubuntu-14.04", + "name": "report", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + }, + { + "moduleShortName": "client", + "name": "report", + "moduleUri": "module/examples/tutorials/service-testing/client/13790", + "content": "#!/bin/sh -x\r\ncp /tmp/data.txt $SLIPSTREAM_REPORT_DIR", + "order": 2 + } + ] + }, + { + "name": "execute", + "subTarget": [ + { + "moduleShortName": "ubuntu-14.04", + "name": "execute", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "content": "#!/bin/bash -xe\r\n\r\n# set the service url to SSH url\r\nurl=$(ss-get --timeout=180 url.ssh)\r\nss-set url.service \"${url}\"\r\nss-set ss:url.service \"${url}\"\r\n\r\n", + "order": 1 + }, + { + "moduleShortName": "client", + "name": "execute", + "moduleUri": "module/examples/tutorials/service-testing/client/13790", + "content": "#!/bin/sh -xe\r\n\r\n[ \"$(ss-get apache:multiplicity)\" = \"0\" ] && { echo \"No web servers to test.\"; exit 0; }\r\n\r\n# Wait for the metadata to be resolved\r\nweb_server_ip=$(ss-get --timeout 360 webserver.hostname)\r\nweb_server_port=$(ss-get --timeout 360 webserver.port)\r\nss-get --timeout 360 webserver.ready\r\n\r\n# Execute the test\r\nENDPOINT=http://${web_server_ip}:${web_server_port}/data.txt\r\nwget -t 2 -O /tmp/data.txt ${ENDPOINT}\r\n[ \"$?\" = \"0\" ] && ss-set statecustom \"OK: $(cat /tmp/data.txt)\" || ss-abort \"Could not get the test file: ${ENDPOINT}\"\r\n", + "order": 2 + } + ] + }, + { + "name": "prescale", + "subTarget": [ + { + "moduleShortName": "client", + "name": "prescale", + "moduleUri": "module/examples/tutorials/service-testing/client/13790", + "order": 2 + }, + { + "moduleShortName": "ubuntu-14.04", + "name": "prescale", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + } + ] + }, + { + "name": "postscale", + "subTarget": [ + { + "moduleShortName": "ubuntu-14.04", + "name": "postscale", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + }, + { + "moduleShortName": "client", + "name": "postscale", + "moduleUri": "module/examples/tutorials/service-testing/client/13790", + "order": 2 + } + ] + }, + { + "name": "onvmremove", + "subTarget": [ + { + "moduleShortName": "client", + "name": "onvmremove", + "moduleUri": "module/examples/tutorials/service-testing/client/13790", + "order": 2 + }, + { + "moduleShortName": "ubuntu-14.04", + "name": "onvmremove", + "moduleUri": "module/examples/images/ubuntu-14.04/13947", + "order": 1 + } + ] + } + ], + "class": "java.util.HashSet" + }, + "creation": "2013-12-03 15:39:52.706 UTC", + "authz": { + "owner": "sixsq", + "groupMembers": { + "string": [ + "elegoff", + "khaled", + "konstan", + "lionel", + "loomis", + "meb", + "cjdcsixsq" + ], + "class": "java.util.ArrayList" + }, + "ownerGet": true, + "ownerDelete": true, + "groupPost": true, + "publicPost": true, + "publicCreateChildren": false, + "ownerCreateChildren": true, + "publicGet": true, + "inheritedGroupMembers": true, + "ownerPost": true, + "groupCreateChildren": false, + "publicPut": false, + "groupGet": true, + "groupDelete": false, + "ownerPut": true, + "publicDelete": false, + "groupPut": true + }, + "buildStates": { + "class": "java.util.HashSet", + "buildState": [ + { + "builtOn": "", + "moduleUri": "module/examples/images/ubuntu-14.04/13947" + }, + { + "builtOn": "", + "moduleUri": "module/examples/tutorials/service-testing/client/13790" + } + ] + }, + "isLatestVersion": true, + "prerecipe": "", + "resourceUri": "module/examples/tutorials/service-testing/client/13790", + "packages": { + "class": "org.hibernate.collection.internal.PersistentSet" + }, + "version": 13790, + "inputParametersExpanded": { + "entry": [ + { + "string": "webserver.port", + "parameter": { + "readonly": false, + "isSet": false, + "name": "webserver.port", + "description": "Port on which the web server listens", + "category": "Input", + "type": "String", + "mandatory": false, + "order_": 0, + "order": 0 + } + }, + { + "string": "webserver.ready", + "parameter": { + "readonly": false, + "isSet": false, + "name": "webserver.ready", + "description": "Server ready to recieve connections", + "category": "Input", + "type": "String", + "mandatory": false, + "order_": 0, + "order": 0 + } + }, + { + "string": "webserver.hostname", + "parameter": { + "readonly": false, + "isSet": false, + "name": "webserver.hostname", + "description": "Server hostname", + "category": "Input", + "type": "String", + "mandatory": false, + "order_": 0, + "order": 0 + } + } + ], + "class": "java.util.HashMap" + }, + "deleted": false, + "name": "examples/tutorials/service-testing/client", + "placementPolicy": "", + "lastModified": "2017-07-23 19:40:30.190 UTC", + "isBase": false, + "category": "Image", + "shortName": "client", + "parameters": { + "entry": [ + { + "string": "nuvlabox-albert-einstein.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-albert-einstein.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-albert-einstein", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-scissor2.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-scissor2.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-scissor2", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "scissor-fr3.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "scissor-fr3.ram", + "description": "Amount of RAM, in GB", + "category": "scissor-fr3", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "cyclone-de1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "cyclone-de1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "cyclone-de1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "hostname", + "parameter": { + "readonly": false, + "isSet": false, + "name": "hostname", + "description": "hostname/ip of the image", + "category": "Output", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "cyclone-fr1.disks.bus.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "virtio", + "name": "cyclone-fr1.disks.bus.type", + "description": "VM disks bus type", + "category": "cyclone-fr1", + "type": "Enum", + "mandatory": true, + "value": "virtio", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "virtio", + "scsi" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-arthur-harden.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-arthur-harden.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-arthur-harden", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-demo.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-demo.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-demo", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-arthur-harden.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-arthur-harden.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-arthur-harden", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "ifb-bird-stack.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ifb-bird-stack.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ifb-bird-stack", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-henry-dunant.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "micro", + "name": "nuvlabox-henry-dunant.instance.type", + "description": "Instance type", + "category": "nuvlabox-henry-dunant", + "type": "Enum", + "mandatory": true, + "value": "micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "micro", + "small", + "medium", + "large" + ], + "length": 4 + } + } + }, + { + "string": "ec2-us-west-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-us-west-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-us-west-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-eu-west-2.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-eu-west-2.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-eu-west-2", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "scissor-fr3.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "scissor-fr3.contextualization.type", + "description": "Contextualization type", + "category": "scissor-fr3", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-cecil-powell.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-cecil-powell.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-cecil-powell", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "ec2-sa-east-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-sa-east-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-sa-east-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "nuvlabox-stanley-cohen.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-stanley-cohen.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-stanley-cohen", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-max-born.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-max-born.network.specific.name", + "description": "Network name", + "category": "nuvlabox-max-born", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "scissor-fr2.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "scissor-fr2.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "scissor-fr2", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-christiane-n-volhard.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-christiane-n-volhard.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-christiane-n-volhard", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "teidehpc-es-tfs1.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "teidehpc-es-tfs1.ram", + "description": "Amount of RAM, in GB", + "category": "teidehpc-es-tfs1", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "ec2-ap-northeast-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-ap-northeast-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-ap-northeast-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-carl-cori.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-carl-cori.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-carl-cori", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-bertil-ohlin.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-bertil-ohlin.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-bertil-ohlin", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "eo-cesnet-cz1.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "eo-cesnet-cz1.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "eo-cesnet-cz1", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-cecil-powell.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-cecil-powell.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-cecil-powell", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-max-planck.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-max-planck.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-max-planck", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-christiane-nusslein-volhard.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-christiane-nusslein-volhard.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-christiane-nusslein-volhard", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 0, + "order": 0 + } + }, + { + "string": "cyclone-fr2.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "cyclone-fr2.security.groups", + "description": "Security Groups (comma separated list)", + "category": "cyclone-fr2", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-yves-chauvin.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-yves-chauvin.network.specific.name", + "description": "Network name", + "category": "nuvlabox-yves-chauvin", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "nuvlabox-cecil-powell.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-cecil-powell.network.specific.name", + "description": "Network name", + "category": "nuvlabox-cecil-powell", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "ec2-ap-southeast-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-ap-southeast-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-ap-southeast-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-henry-dunant.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-henry-dunant.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-henry-dunant", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "eo-cesnet-cz1.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "eo-cesnet-cz1.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "eo-cesnet-cz1", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-max-born.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-max-born.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-max-born", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-christiane-nusslein-volhard.custom.vm.template", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-christiane-nusslein-volhard.custom.vm.template", + "description": "Additional custom VM template", + "category": "nuvlabox-christiane-nusslein-volhard", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-felix-bloch.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-felix-bloch.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-felix-bloch", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-albert-einstein.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-albert-einstein.network.specific.name", + "description": "Network name", + "category": "nuvlabox-albert-einstein", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "ifb-genouest-genostack.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ifb-genouest-genostack.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ifb-genouest-genostack", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-james-chadwick.disks.bus.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "virtio", + "name": "nuvlabox-james-chadwick.disks.bus.type", + "description": "VM disks bus type", + "category": "nuvlabox-james-chadwick", + "type": "Enum", + "mandatory": true, + "value": "virtio", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "virtio", + "scsi" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-cecil-powell.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-cecil-powell.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-cecil-powell", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-scissor2.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-scissor2.network.specific.name", + "description": "Network name", + "category": "nuvlabox-scissor2", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "nuvlabox-max-born.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-max-born.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-max-born", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-arthur-harden.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-arthur-harden.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-arthur-harden", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-yves-chauvin.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-yves-chauvin.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-yves-chauvin", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "ifb-genouest-genostack.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small", + "name": "ifb-genouest-genostack.instance.type", + "description": "Instance type (flavor)", + "category": "ifb-genouest-genostack", + "type": "String", + "mandatory": true, + "value": "m1.small", + "order_": 0, + "order": 0 + } + }, + { + "string": "ifb-core-pilot.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ifb-core-pilot.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ifb-core-pilot", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-scissor2.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-scissor2.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-scissor2", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "ultimum-cz1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "Basic", + "name": "ultimum-cz1.instance.type", + "description": "Instance type (flavor)", + "category": "ultimum-cz1", + "type": "String", + "mandatory": true, + "value": "Basic", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-bertil-ohlin.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-bertil-ohlin.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-bertil-ohlin", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-yves-chauvin.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-yves-chauvin.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-yves-chauvin", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-james-chadwick.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-james-chadwick.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-james-chadwick", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "atos-es1.ram", + "parameter": { + "readonly": false, + "isSet": false, + "name": "atos-es1.ram", + "description": "Amount of RAM, in GB", + "category": "atos-es1", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "open-telekom-de1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "open-telekom-de1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "open-telekom-de1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-albert-einstein.cpu", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-albert-einstein.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-albert-einstein", + "type": "String", + "mandatory": true, + "order_": 10, + "order": 10 + } + }, + { + "string": "ec2-us-west-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-us-west-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-us-west-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "scissor-fr3.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "scissor-fr3.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "scissor-fr3", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-demo.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "micro", + "name": "nuvlabox-demo.instance.type", + "description": "Instance type", + "category": "nuvlabox-demo", + "type": "Enum", + "mandatory": true, + "value": "micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "micro", + "small", + "medium", + "large" + ], + "length": 4 + } + } + }, + { + "string": "nuvlabox-yves-chauvin.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-yves-chauvin.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-yves-chauvin", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "ifb-bird-stack.instance.type", + "parameter": { + "readonly": false, + "isSet": false, + "name": "ifb-bird-stack.instance.type", + "description": "Instance type (flavor)", + "category": "ifb-bird-stack", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "ifb-bistro-iphc.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small", + "name": "ifb-bistro-iphc.instance.type", + "description": "Instance type (flavor)", + "category": "ifb-bistro-iphc", + "type": "String", + "mandatory": true, + "value": "m1.small", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-demo.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-demo.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-demo", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 0, + "order": 0 + } + }, + { + "string": "ifb-prabi-girofle.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small", + "name": "ifb-prabi-girofle.instance.type", + "description": "Instance type (flavor)", + "category": "ifb-prabi-girofle", + "type": "String", + "mandatory": true, + "value": "m1.small", + "order_": 0, + "order": 0 + } + }, + { + "string": "teidehpc-es-tfs1.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "teidehpc-es-tfs1.contextualization.type", + "description": "Contextualization type", + "category": "teidehpc-es-tfs1", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "cyclone-fr2.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small", + "name": "cyclone-fr2.instance.type", + "description": "Instance type (flavor)", + "category": "cyclone-fr2", + "type": "String", + "mandatory": true, + "value": "m1.small", + "order_": 0, + "order": 0 + } + }, + { + "string": "ram.GB", + "parameter": { + "readonly": false, + "isSet": false, + "name": "ram.GB", + "description": "RAM in GB", + "category": "Cloud", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-albert-einstein.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-albert-einstein.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-albert-einstein", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-stanley-cohen.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-stanley-cohen.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-stanley-cohen", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-cecil-powell.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-cecil-powell.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-cecil-powell", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-max-born.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-max-born.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-max-born", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "cyclone-fr1.ram", + "parameter": { + "readonly": false, + "isSet": false, + "name": "cyclone-fr1.ram", + "description": "Amount of RAM, in GB", + "category": "cyclone-fr1", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "cyclone-de1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "small", + "name": "cyclone-de1.instance.type", + "description": "Instance type (flavor)", + "category": "cyclone-de1", + "type": "String", + "mandatory": true, + "value": "small", + "order_": 0, + "order": 0 + } + }, + { + "string": "exoscale-ch-dk.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "exoscale-ch-dk.security.groups", + "description": "Security Groups (comma separated list)", + "category": "exoscale-ch-dk", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "webserver.ready", + "parameter": { + "readonly": false, + "isSet": false, + "name": "webserver.ready", + "description": "Server ready to recieve connections", + "category": "Input", + "type": "String", + "mandatory": false, + "order_": 0, + "order": 0 + } + }, + { + "string": "scissor-fr1.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "scissor-fr1.network.specific.name", + "description": "Network name", + "category": "scissor-fr1", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "nuvlabox-christiane-n-volhard.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-christiane-n-volhard.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-christiane-n-volhard", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-henry-dunant.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-henry-dunant.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-henry-dunant", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-christiane-nusslein-volhard.is.firewall", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-christiane-nusslein-volhard.is.firewall", + "description": "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + "category": "nuvlabox-christiane-nusslein-volhard", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-us-east-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-us-east-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-us-east-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "nuvlabox-stanley-cohen.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-stanley-cohen.network.specific.name", + "description": "Network name", + "category": "nuvlabox-stanley-cohen", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "nuvlabox-felix-bloch.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-felix-bloch.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-felix-bloch", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-max-planck.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-max-planck.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-max-planck", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "teidehpc-es-tfs1.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "teidehpc-es-tfs1.network.specific.name", + "description": "Network name", + "category": "teidehpc-es-tfs1", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "eo-cloudferro-pl1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "eo1.small", + "name": "eo-cloudferro-pl1.instance.type", + "description": "Instance type (flavor)", + "category": "eo-cloudferro-pl1", + "type": "String", + "mandatory": true, + "value": "eo1.small", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-scissor1.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-scissor1.network.specific.name", + "description": "Network name", + "category": "nuvlabox-scissor1", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "softlayer-it-mil01.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "2 CPU, 2GB ram, 100GB", + "name": "softlayer-it-mil01.instance.type", + "description": "Instance type (flavor)", + "category": "softlayer-it-mil01", + "type": "String", + "mandatory": true, + "value": "2 CPU, 2GB ram, 100GB", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-felix-bloch.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-felix-bloch.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-felix-bloch", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "cyfronet-pl1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "CPU-1.RAM-512MB.DISK-10GB", + "name": "cyfronet-pl1.instance.type", + "description": "Instance type (flavor)", + "category": "cyfronet-pl1", + "type": "String", + "mandatory": true, + "value": "CPU-1.RAM-512MB.DISK-10GB", + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-eu-west.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-eu-west.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-eu-west", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-bertil-ohlin.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-bertil-ohlin.network.specific.name", + "description": "Network name", + "category": "nuvlabox-bertil-ohlin", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "nuvlabox-max-planck.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-max-planck.network.specific.name", + "description": "Network name", + "category": "nuvlabox-max-planck", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "atos-es1.cpu", + "parameter": { + "readonly": false, + "isSet": false, + "name": "atos-es1.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "atos-es1", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "cpu.nb", + "parameter": { + "readonly": false, + "isSet": false, + "name": "cpu.nb", + "description": "Number of CPUs", + "category": "Cloud", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-eu-central-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-eu-central-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-eu-central-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "webserver.hostname", + "parameter": { + "readonly": false, + "isSet": false, + "name": "webserver.hostname", + "description": "Server hostname", + "category": "Input", + "type": "String", + "mandatory": false, + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-us-west-2.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-us-west-2.instance.type", + "description": "Cloud instance type", + "category": "ec2-us-west-2", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "eo-cesnet-cz1.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "cloud-init", + "name": "eo-cesnet-cz1.contextualization.type", + "description": "Contextualization type", + "category": "eo-cesnet-cz1", + "type": "Enum", + "mandatory": true, + "value": "cloud-init", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-felix-bloch.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-felix-bloch.network.specific.name", + "description": "Network name", + "category": "nuvlabox-felix-bloch", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "nuvlabox-christiane-n-volhard.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-christiane-n-volhard.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-christiane-n-volhard", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-demo.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-demo.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-demo", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-scissor1.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-scissor1.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-scissor1", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-albert-einstein.ram", + "parameter": { + "readonly": false, + "isSet": false, + "name": "nuvlabox-albert-einstein.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-albert-einstein", + "type": "String", + "mandatory": true, + "order_": 11, + "order": 11 + } + }, + { + "string": "scissor-fr2.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "scissor-fr2.contextualization.type", + "description": "Contextualization type", + "category": "scissor-fr2", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-scissor1.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-scissor1.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-scissor1", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "exoscale-ch-gva.disk", + "parameter": { + "instructions": "Some disk sizes might not be available with all operating system and all instance type", + "isSet": true, + "defaultValue": "10G", + "description": "Size of the root disk", + "type": "Enum", + "mandatory": true, + "order_": 20, + "readonly": false, + "name": "exoscale-ch-gva.disk", + "category": "exoscale-ch-gva", + "value": "10G", + "order": 20, + "enumValues": { + "string": [ + "10G", + "50G", + "100G", + "200G", + "400G", + "800G", + "1600G" + ], + "length": 7 + } + } + }, + { + "string": "nuvlabox-yves-chauvin.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-yves-chauvin.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-yves-chauvin", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-albert-einstein.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-albert-einstein.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-albert-einstein", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-max-born.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-max-born.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-max-born", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "ec2-eu-west-2.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-eu-west-2.instance.type", + "description": "Cloud instance type", + "category": "ec2-eu-west-2", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "nuvlabox-james-chadwick.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-james-chadwick.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-james-chadwick", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "cyclone-fr1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small", + "name": "cyclone-fr1.instance.type", + "description": "Cloud instance type", + "category": "cyclone-fr1", + "type": "Enum", + "mandatory": true, + "value": "m1.small", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "m1.small", + "c1.medium", + "m1.large", + "m1.xlarge", + "c1.xlarge", + "t1.micro", + "standard.xsmall" + ], + "length": 7 + } + } + }, + { + "string": "scissor-fr1.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "scissor-fr1.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "scissor-fr1", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "ec2-ap-northeast-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-ap-northeast-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-ap-northeast-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "ec2-ap-southeast-2.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-ap-southeast-2.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-ap-southeast-2", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "teidehpc-es-tfs1.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "teidehpc-es-tfs1.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "teidehpc-es-tfs1", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-arthur-harden.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-arthur-harden.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-arthur-harden", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-scissor2.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-scissor2.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-scissor2", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-scissor1.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-scissor1.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-scissor1", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-henry-dunant.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-henry-dunant.network.specific.name", + "description": "Network name", + "category": "nuvlabox-henry-dunant", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "atos-es1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small", + "name": "atos-es1.instance.type", + "description": "Cloud instance type", + "category": "atos-es1", + "type": "Enum", + "mandatory": true, + "value": "m1.small", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "m1.small", + "c1.medium", + "m1.large", + "m1.xlarge", + "c1.xlarge", + "t1.micro", + "standard.xsmall" + ], + "length": 7 + } + } + }, + { + "string": "scissor-fr1.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "scissor-fr1.ram", + "description": "Amount of RAM, in GB", + "category": "scissor-fr1", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "ultimum-cz1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ultimum-cz1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ultimum-cz1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-christiane-n-volhard.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-christiane-n-volhard.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-christiane-n-volhard", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-stanley-cohen.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-stanley-cohen.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-stanley-cohen", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-henry-dunant.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-henry-dunant.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-henry-dunant", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-henry-dunant.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-henry-dunant.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-henry-dunant", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "advania-se1.instance.type", + "parameter": { + "readonly": false, + "isSet": false, + "name": "advania-se1.instance.type", + "description": "Instance type (flavor)", + "category": "advania-se1", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "ifb-core-pilot.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "m1.small", + "name": "ifb-core-pilot.instance.type", + "description": "Instance type (flavor)", + "category": "ifb-core-pilot", + "type": "String", + "mandatory": true, + "value": "m1.small", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-james-chadwick.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-james-chadwick.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-james-chadwick", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-bertil-ohlin.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-bertil-ohlin.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-bertil-ohlin", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-bertil-ohlin.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-bertil-ohlin.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-bertil-ohlin", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "eo-cesnet-cz1.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "eo-cesnet-cz1.network.specific.name", + "description": "Network name", + "category": "eo-cesnet-cz1", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "ec2-us-east-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-us-east-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-us-east-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "cyclone-fr1.cpu", + "parameter": { + "readonly": false, + "isSet": false, + "name": "cyclone-fr1.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "cyclone-fr1", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-max-born.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-max-born.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-max-born", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "ifb-bistro-iphc.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ifb-bistro-iphc.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ifb-bistro-iphc", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "exoscale-ch-gva.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "exoscale-ch-gva.security.groups", + "description": "Security Groups (comma separated list)", + "category": "exoscale-ch-gva", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "disk.GB", + "parameter": { + "readonly": false, + "isSet": false, + "name": "disk.GB", + "description": "Disk in GB", + "category": "Cloud", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-max-planck.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "micro", + "name": "nuvlabox-max-planck.instance.type", + "description": "Instance type", + "category": "nuvlabox-max-planck", + "type": "Enum", + "mandatory": true, + "value": "micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "micro", + "small", + "medium", + "large" + ], + "length": 4 + } + } + }, + { + "string": "ec2-eu-central-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-eu-central-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-eu-central-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-james-chadwick.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "micro", + "name": "nuvlabox-james-chadwick.instance.type", + "description": "Instance type", + "category": "nuvlabox-james-chadwick", + "type": "Enum", + "mandatory": true, + "value": "micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "micro", + "small", + "medium", + "large" + ], + "length": 4 + } + } + }, + { + "string": "nuvlabox-max-planck.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-max-planck.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-max-planck", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-carl-cori.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-carl-cori.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-carl-cori", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-henry-dunant.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-henry-dunant.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-henry-dunant", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "nuvlabox-christiane-n-volhard.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-christiane-n-volhard.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-christiane-n-volhard", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "ec2-sa-east-1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-sa-east-1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-sa-east-1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-yves-chauvin.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-yves-chauvin.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-yves-chauvin", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-james-chadwick.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-james-chadwick.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-james-chadwick", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "open-telekom-de1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "c1.medium", + "name": "open-telekom-de1.instance.type", + "description": "Instance type (flavor)", + "category": "open-telekom-de1", + "type": "String", + "mandatory": true, + "value": "c1.medium", + "order_": 0, + "order": 0 + } + }, + { + "string": "advania-se1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "advania-se1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "advania-se1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-scissor1.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-scissor1.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-scissor1", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-carl-cori.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-carl-cori.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-carl-cori", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "webserver.port", + "parameter": { + "readonly": false, + "isSet": false, + "name": "webserver.port", + "description": "Port on which the web server listens", + "category": "Input", + "type": "String", + "mandatory": false, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-scissor1.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-scissor1.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-scissor1", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-scissor2.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-scissor2.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-scissor2", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "scissor-fr2.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "scissor-fr2.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "scissor-fr2", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "azure-west-europe.forwarded.ports", + "parameter": { + "instructions": "Ports that will be forwarded from the public IP of the Azure cloud service. The port 22 (SSH) on Linux machines and the port 3389 (RDP) on Windows machines are already forwarded", + "readonly": false, + "isSet": false, + "name": "azure-west-europe.forwarded.ports", + "description": "Forwarded ports (comma separated list)", + "category": "azure-west-europe", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-stanley-cohen.is.firewall", + "parameter": { + "instructions": "Instance will be started with two network interfaces, the first one will be connected to the public VM network and the other to the private VM network.", + "readonly": false, + "isSet": true, + "defaultValue": "false", + "name": "nuvlabox-stanley-cohen.is.firewall", + "description": "Firewalling", + "category": "nuvlabox-stanley-cohen", + "type": "Boolean", + "mandatory": true, + "value": "false", + "order_": 20, + "order": 20 + } + }, + { + "string": "scissor-fr3.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "scissor-fr3.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "scissor-fr3", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-felix-bloch.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-felix-bloch.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-felix-bloch", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "exoscale-ch-gva.instance.type", + "parameter": { + "instructions": "You might have to request access to Exoscale for some instance types", + "isSet": true, + "defaultValue": "Small", + "description": "Cloud instance type", + "type": "Enum", + "mandatory": true, + "order_": 10, + "readonly": false, + "name": "exoscale-ch-gva.instance.type", + "category": "exoscale-ch-gva", + "value": "Small", + "order": 10, + "enumValues": { + "string": [ + "Micro", + "Tiny", + "Small", + "Medium", + "Large", + "Extra-large", + "Huge", + "Mega", + "Titan", + "GPU-small", + "GPU-huge" + ], + "length": 11 + } + } + }, + { + "string": "atos-es1.disks.bus.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "virtio", + "name": "atos-es1.disks.bus.type", + "description": "VM disks bus type", + "category": "atos-es1", + "type": "Enum", + "mandatory": true, + "value": "virtio", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "virtio", + "scsi" + ], + "length": 2 + } + } + }, + { + "string": "scissor-fr3.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "scissor-fr3.network.specific.name", + "description": "Network name", + "category": "scissor-fr3", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "extra.disk.volatile", + "parameter": { + "readonly": false, + "isSet": false, + "name": "extra.disk.volatile", + "description": "Volatile extra disk in GB", + "category": "Cloud", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-arthur-harden.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-arthur-harden.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-arthur-harden", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "instanceid", + "parameter": { + "readonly": false, + "isSet": false, + "name": "instanceid", + "description": "Cloud instance id", + "category": "Output", + "type": "String", + "mandatory": true, + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-albert-einstein.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "micro", + "name": "nuvlabox-albert-einstein.instance.type", + "description": "Instance type", + "category": "nuvlabox-albert-einstein", + "type": "Enum", + "mandatory": true, + "value": "micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "micro", + "small", + "medium", + "large" + ], + "length": 4 + } + } + }, + { + "string": "nuvlabox-christiane-n-volhard.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-christiane-n-volhard.network.specific.name", + "description": "Network name", + "category": "nuvlabox-christiane-n-volhard", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "nuvlabox-max-planck.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-max-planck.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-max-planck", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "scissor-fr2.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "scissor-fr2.ram", + "description": "Amount of RAM, in GB", + "category": "scissor-fr2", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "teidehpc-es-tfs1.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "teidehpc-es-tfs1.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "teidehpc-es-tfs1", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-demo.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-demo.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-demo", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 0, + "order": 0 + } + }, + { + "string": "scissor-fr2.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "scissor-fr2.network.specific.name", + "description": "Network name", + "category": "scissor-fr2", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "eo-cloudferro-pl1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "eo-cloudferro-pl1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "eo-cloudferro-pl1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-james-chadwick.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-james-chadwick.network.specific.name", + "description": "Network name", + "category": "nuvlabox-james-chadwick", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "scissor-fr1.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "scissor-fr1.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "scissor-fr1", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-arthur-harden.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-arthur-harden.network.specific.name", + "description": "Network name", + "category": "nuvlabox-arthur-harden", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "nuvlabox-christiane-nusslein-volhard.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-christiane-nusslein-volhard.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-christiane-nusslein-volhard", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-stanley-cohen.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-stanley-cohen.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-stanley-cohen", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "ifb-prabi-girofle.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ifb-prabi-girofle.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ifb-prabi-girofle", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-carl-cori.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-carl-cori.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-carl-cori", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "ec2-ap-southeast-2.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-ap-southeast-2.instance.type", + "description": "Cloud instance type", + "category": "ec2-ap-southeast-2", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "cyfronet-pl1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "cyfronet-pl1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "cyfronet-pl1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "network", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "Public", + "name": "network", + "description": "Network type", + "category": "Cloud", + "type": "Enum", + "mandatory": true, + "value": "Public", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "Public", + "Private" + ], + "length": 2 + } + } + }, + { + "string": "azure-west-europe.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "Basic_A0", + "name": "azure-west-europe.instance.type", + "description": "Machine size", + "category": "azure-west-europe", + "type": "Enum", + "mandatory": true, + "value": "Basic_A0", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "Basic_A0", + "Basic_A1", + "Basic_A2", + "Basic_A3", + "Basic_A4", + "ExtraSmall", + "Small", + "Medium", + "Large", + "ExtraLarge", + "A5", + "A6", + "A7", + "A8", + "A9", + "A10", + "A11", + "Standard_D1", + "Standard_D2", + "Standard_D3", + "Standard_D4", + "Standard_D11", + "Standard_D12", + "Standard_D13", + "Standard_D14" + ], + "length": 25 + } + } + }, + { + "string": "nuvlabox-carl-cori.network.specific.name", + "parameter": { + "instructions": "Override network in Cloud configuration section! Connect VM network interface on specified virtual network name. Format: NETWORK_NAME or NETWORK_NAME;NETWORK_UNAME", + "readonly": false, + "isSet": false, + "name": "nuvlabox-carl-cori.network.specific.name", + "description": "Network name", + "category": "nuvlabox-carl-cori", + "type": "String", + "mandatory": true, + "order_": 12, + "order": 12 + } + }, + { + "string": "nuvlabox-bertil-ohlin.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-bertil-ohlin.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-bertil-ohlin", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "nuvlabox-scissor2.custom.vm.template", + "parameter": { + "instructions": "Example: GRAPHICS = [ TYPE = VNC, LISTEN = 0.0.0.0, PORT = 5900 ]", + "readonly": false, + "isSet": false, + "name": "nuvlabox-scissor2.custom.vm.template", + "description": "Additional custom textual VM template", + "category": "nuvlabox-scissor2", + "type": "RestrictedText", + "mandatory": true, + "order_": 101, + "order": 101 + } + }, + { + "string": "nuvlabox-cecil-powell.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-cecil-powell.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-cecil-powell", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "eo-cesnet-cz1.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "eo-cesnet-cz1.ram", + "description": "Amount of RAM, in GB", + "category": "eo-cesnet-cz1", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "nuvlabox-james-chadwick.ram", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "0.5", + "name": "nuvlabox-james-chadwick.ram", + "description": "Amount of RAM, in GB", + "category": "nuvlabox-james-chadwick", + "type": "String", + "mandatory": true, + "value": "0.5", + "order_": 11, + "order": 11 + } + }, + { + "string": "ec2-eu-west.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-eu-west.instance.type", + "description": "Cloud instance type", + "category": "ec2-eu-west", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "cyclone-tb-it1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "os.1", + "name": "cyclone-tb-it1.instance.type", + "description": "Instance type (flavor)", + "category": "cyclone-tb-it1", + "type": "String", + "mandatory": true, + "value": "os.1", + "order_": 0, + "order": 0 + } + }, + { + "string": "exoscale-ch-dk.instance.type", + "parameter": { + "instructions": "You might have to request access to Exoscale for some instance types", + "isSet": true, + "defaultValue": "Micro", + "description": "Cloud instance type", + "type": "Enum", + "mandatory": true, + "order_": 10, + "readonly": false, + "name": "exoscale-ch-dk.instance.type", + "category": "exoscale-ch-dk", + "value": "Micro", + "order": 10, + "enumValues": { + "string": [ + "Micro", + "Tiny", + "Small", + "Medium", + "Large", + "Extra-large", + "Huge", + "Mega", + "Titan", + "GPU-small", + "GPU-huge" + ], + "length": 11 + } + } + }, + { + "string": "nuvlabox-carl-cori.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-carl-cori.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-carl-cori", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "cyclone-tb-it1.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "cyclone-tb-it1.security.groups", + "description": "Security Groups (comma separated list)", + "category": "cyclone-tb-it1", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "ec2-ap-southeast-1.instance.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "t2.micro", + "name": "ec2-ap-southeast-1.instance.type", + "description": "Cloud instance type", + "category": "ec2-ap-southeast-1", + "type": "Enum", + "mandatory": true, + "value": "t2.micro", + "order_": 0, + "order": 0, + "enumValues": { + "string": [ + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "t2.xlarge", + "t2.2xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "m4.16xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "r4.large", + "r4.xlarge", + "r4.2xlarge", + "r4.4xlarge", + "r4.8xlarge", + "r4.16xlarge", + "x1.16xlarge", + "x1.32xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "i3.large", + "i3.xlarge", + "i3.2xlarge", + "i3.4xlarge", + "i3.8xlarge", + "i3.16xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "p2.xlarge", + "p2.8xlarge", + "p2.16xlarge", + "g2.2xlarge", + "g2.8xlarge", + "f1.2xlarge", + "f1.16xlarge", + "t1.micro", + "m1.small", + "m1.large", + "m1.xlarge", + "c1.medium", + "c1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "cc1.4xlarge" + ], + "length": 71 + } + } + }, + { + "string": "scissor-fr1.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "scissor-fr1.contextualization.type", + "description": "Contextualization type", + "category": "scissor-fr1", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + }, + { + "string": "nuvlabox-max-planck.cpu", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "1", + "name": "nuvlabox-max-planck.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "category": "nuvlabox-max-planck", + "type": "String", + "mandatory": true, + "value": "1", + "order_": 10, + "order": 10 + } + }, + { + "string": "exoscale-ch-dk.disk", + "parameter": { + "instructions": "Some disk sizes might not be available with all operating system and all instance type", + "isSet": true, + "defaultValue": "10G", + "description": "Size of the root disk", + "type": "Enum", + "mandatory": true, + "order_": 20, + "readonly": false, + "name": "exoscale-ch-dk.disk", + "category": "exoscale-ch-dk", + "value": "10G", + "order": 20, + "enumValues": { + "string": [ + "10G", + "50G", + "100G", + "200G", + "400G", + "800G", + "1600G" + ], + "length": 7 + } + } + }, + { + "string": "ec2-us-west-2.security.groups", + "parameter": { + "instructions": "If you don't know what is a security group or if you don't want to take care of them, you can use the special value slipstream_managed to let SlipStream generate a security group with everything allowed.", + "readonly": false, + "isSet": true, + "defaultValue": "slipstream_managed", + "name": "ec2-us-west-2.security.groups", + "description": "Security Groups (comma separated list)", + "category": "ec2-us-west-2", + "type": "String", + "mandatory": true, + "value": "slipstream_managed", + "order_": 0, + "order": 0 + } + }, + { + "string": "nuvlabox-felix-bloch.contextualization.type", + "parameter": { + "readonly": false, + "isSet": true, + "defaultValue": "one-context", + "name": "nuvlabox-felix-bloch.contextualization.type", + "description": "Contextualization type", + "category": "nuvlabox-felix-bloch", + "type": "Enum", + "mandatory": true, + "value": "one-context", + "order_": 100, + "order": 100, + "enumValues": { + "string": [ + "one-context", + "cloud-init" + ], + "length": 2 + } + } + } + ], + "class": "org.hibernate.collection.internal.PersistentMap" + } + }, + "imageUri": "module/examples/tutorials/service-testing/client", + "deleted": false, + "notes": { + "length": 0 + }, + "parameterMappings": { + "entry": [ + { + "string": "webserver.port", + "parameter": { + "readonly": false, + "isMappedValue": true, + "name": "webserver.port", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "apache:port", + "order_": 0, + "order": 0 + } + }, + { + "string": "webserver.ready", + "parameter": { + "readonly": false, + "isMappedValue": true, + "name": "webserver.ready", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "apache:ready", + "order_": 0, + "order": 0 + } + }, + { + "string": "webserver.hostname", + "parameter": { + "readonly": false, + "isMappedValue": true, + "name": "webserver.hostname", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "apache:hostname", + "order_": 0, + "order": 0 + } + } + ], + "class": "org.hibernate.collection.internal.PersistentMap" + }, + "name": "testclient", + "maxProvisioningFailures": 0, + "parameters": { + "entry": [ + { + "string": "webserver.port", + "parameter": { + "readonly": false, + "isMappedValue": true, + "name": "webserver.port", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "apache:port", + "order_": 0, + "order": 0 + } + }, + { + "string": "webserver.ready", + "parameter": { + "readonly": false, + "isMappedValue": true, + "name": "webserver.ready", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "apache:ready", + "order_": 0, + "order": 0 + } + }, + { + "string": "webserver.hostname", + "parameter": { + "readonly": false, + "isMappedValue": true, + "name": "webserver.hostname", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "apache:hostname", + "order_": 0, + "order": 0 + } + } + ], + "class": "org.hibernate.collection.internal.PersistentMap" + }, + "creation": "2015-10-20 08:40:43.893 UTC", + "cloudService": "default", + "network": "Public" + }, + "string": "testclient" + } + ], + "class": "org.hibernate.collection.internal.PersistentMap" + }, + "targetsExpanded": { + "class": "java.util.HashSet" + }, + "name": "examples/tutorials/service-testing/system", + "lastModified": "2016-08-24 09:52:20.481 UTC", + "category": "Deployment", + "shortName": "system", + "class": "com.sixsq.slipstream.persistence.DeploymentModule", + "parameters": { + "class": "org.hibernate.collection.internal.PersistentMap" + }, + "creation": "2013-10-30 09:54:53.989 UTC", + "authz": { + "owner": "sixsq", + "groupMembers": { + "string": [ + "elegoff", + "khaled", + "konstan", + "lionel", + "loomis", + "meb", + "cjdcsixsq" + ], + "class": "java.util.ArrayList" + }, + "ownerGet": true, + "ownerDelete": true, + "groupPost": true, + "publicPost": true, + "publicCreateChildren": false, + "ownerCreateChildren": true, + "publicGet": true, + "inheritedGroupMembers": true, + "ownerPost": true, + "groupCreateChildren": false, + "publicPut": false, + "groupGet": true, + "groupDelete": false, + "ownerPut": true, + "publicDelete": false, + "groupPut": true + } + }, + "lastStateChangeTime": "2017-09-14 08:18:38.882 UTC", + "groups": "nuvlabox-carl-cori:apache,nuvlabox-carl-cori:testclient", + "resourceUri": "run/97089b96-5d99-4ccd-9bfe-99ba3ca21ae2", + "type": "Orchestration", + "uuid": "97089b96-5d99-4ccd-9bfe-99ba3ca21ae2", + "nodeNames": "apache.1,testclient.1,orchestrator-nuvlabox-carl-cori", + "deleted": false, + "moduleResourceUri": "module/examples/tutorials/service-testing/system/1940", + "mutable": false, + "runtimeParameters": { + "entry": [ + { + "string": "testclient.1:nuvlabox-carl-cori.cpu", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "nuvlabox-carl-cori.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "type": "String", + "key": "testclient.1:nuvlabox-carl-cori.cpu", + "creation": "2017-09-14 08:12:23.666 UTC", + "content": "1", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:vmstate", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "vmstate", + "description": "State of the VM, according to the cloud layer", + "type": "String", + "key": "testclient.1:vmstate", + "creation": "2017-09-14 08:12:23.628 UTC", + "content": "Unknown", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:image.id", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "image.id", + "description": "Cloud image id", + "type": "String", + "key": "apache.1:image.id", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "d88f85a9489e5c05aa2f06a4a878826f", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:cpu.nb", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "cpu.nb", + "description": "Number of CPUs", + "type": "String", + "key": "apache.1:cpu.nb", + "creation": "2017-09-14 08:12:23.614 UTC", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "ss:abort", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "abort", + "description": "Run abort flag, set when aborting", + "type": "String", + "key": "ss:abort", + "creation": "2017-09-14 08:12:23.613 UTC", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-carl-cori:vmstate", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "vmstate", + "description": "State of the VM, according to the cloud layer", + "type": "String", + "key": "orchestrator-nuvlabox-carl-cori:vmstate", + "creation": "2017-09-14 08:12:23.679 UTC", + "content": "Unknown", + "group": "orchestrator-nuvlabox-carl-cori", + "mapsOthers": false + } + }, + { + "string": "apache.1:nuvlabox-carl-cori.contextualization.type", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "nuvlabox-carl-cori.contextualization.type", + "description": "Contextualization type", + "type": "Enum", + "key": "apache.1:nuvlabox-carl-cori.contextualization.type", + "creation": "2017-09-14 08:12:23.614 UTC", + "content": "one-context", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:vmstate", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "vmstate", + "description": "State of the VM, according to the cloud layer", + "type": "String", + "key": "apache.1:vmstate", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "Unknown", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:scale.iaas.done", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "scale.iaas.done", + "description": "Orchestrator sets to 'true' after scaling the node instance", + "type": "String", + "key": "testclient.1:scale.iaas.done", + "creation": "2017-09-14 08:12:23.628 UTC", + "content": "false", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:nuvlabox-carl-cori.is.firewall", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "nuvlabox-carl-cori.is.firewall", + "description": "Firewalling", + "type": "Boolean", + "key": "testclient.1:nuvlabox-carl-cori.is.firewall", + "creation": "2017-09-14 08:12:23.666 UTC", + "content": "false", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:disk.detach.device", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "disk.detach.device", + "description": "Name of the block device to detach from the VM during vertical scaling", + "type": "String", + "key": "testclient.1:disk.detach.device", + "creation": "2017-09-14 08:12:23.628 UTC", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:url.service", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "url.service", + "description": "Optional service URL for virtual machine", + "type": "String", + "key": "testclient.1:url.service", + "creation": "2017-09-14 08:12:23.628 UTC", + "content": "ssh://root@172.16.0.11", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:statecustom", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "statecustom", + "description": "Custom state", + "type": "String", + "key": "testclient.1:statecustom", + "creation": "2017-09-14 08:12:23.628 UTC", + "content": "OK: Hello from Apache deployed by SlipStream!", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:ram.GB", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "ram.GB", + "description": "RAM in GB", + "type": "String", + "key": "testclient.1:ram.GB", + "creation": "2017-09-14 08:12:23.666 UTC", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:nodename", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "nodename", + "description": "Nodename", + "type": "String", + "key": "testclient.1:nodename", + "creation": "2017-09-14 08:12:23.628 UTC", + "content": "testclient", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:disk.attached.device", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "disk.attached.device", + "description": "Attached device name after the VM's vertical scaling", + "type": "String", + "key": "testclient.1:disk.attached.device", + "creation": "2017-09-14 08:12:23.628 UTC", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:instanceid", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "instanceid", + "description": "Cloud instance id", + "type": "String", + "key": "apache.1:instanceid", + "creation": "2017-09-14 08:12:23.614 UTC", + "content": "282", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "ss:complete", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "complete", + "description": "Global complete flag, set when run completed", + "type": "String", + "key": "ss:complete", + "creation": "2017-09-14 08:12:23.613 UTC", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "apache.1:ready", + "runtimeParameter": { + "mappedRuntimeParameterNames": "testclient.1:webserver.ready,", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "ready", + "description": "Server ready to recieve connections", + "type": "String", + "key": "apache.1:ready", + "creation": "2017-09-14 08:12:23.614 UTC", + "content": "true", + "group": "apache.1", + "mapsOthers": true + } + }, + { + "string": "ss:url.service", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "url.service", + "description": "Optional service URL for the deployment", + "type": "String", + "key": "ss:url.service", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "http://172.16.0.16:8080", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "testclient.1:hostname", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "hostname", + "description": "hostname/ip of the image", + "type": "String", + "key": "testclient.1:hostname", + "creation": "2017-09-14 08:12:23.666 UTC", + "content": "172.16.0.11", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:pre.scale.done", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "pre.scale.done", + "description": "Node instance sets to 'true' after running pre-scale script", + "type": "String", + "key": "apache.1:pre.scale.done", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "false", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:instanceid", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "instanceid", + "description": "Cloud instance id", + "type": "String", + "key": "testclient.1:instanceid", + "creation": "2017-09-14 08:12:23.666 UTC", + "content": "281", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "testclient:multiplicity", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "multiplicity", + "description": "Multiplicity number", + "type": "String", + "key": "testclient:multiplicity", + "creation": "2017-09-14 08:12:23.679 UTC", + "content": "1", + "group": "testclient", + "mapsOthers": false + } + }, + { + "string": "testclient.1:image.platform", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "image.platform", + "description": "Platform (eg: ubuntu, windows)", + "type": "String", + "key": "testclient.1:image.platform", + "creation": "2017-09-14 08:12:23.666 UTC", + "content": "ubuntu", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:service-offer", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "service-offer", + "description": "Service Offer Id", + "type": "String", + "key": "apache.1:service-offer", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "service-offer/7327d738-f2f8-4925-9277-64dc72d6a283", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:pre.scale.done", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "pre.scale.done", + "description": "Node instance sets to 'true' after running pre-scale script", + "type": "String", + "key": "testclient.1:pre.scale.done", + "creation": "2017-09-14 08:12:23.628 UTC", + "content": "false", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:extra.disk.volatile", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "extra.disk.volatile", + "description": "Volatile extra disk in GB", + "type": "String", + "key": "apache.1:extra.disk.volatile", + "creation": "2017-09-14 08:12:23.614 UTC", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:is.orchestrator", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "is.orchestrator", + "description": "True if it's an orchestrator", + "type": "String", + "key": "apache.1:is.orchestrator", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "false", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:disk.GB", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "disk.GB", + "description": "Disk in GB", + "type": "String", + "key": "testclient.1:disk.GB", + "creation": "2017-09-14 08:12:23.666 UTC", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:nuvlabox-carl-cori.cpu", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "nuvlabox-carl-cori.cpu", + "description": "Number of CPUs (i.e. virtual cores)", + "type": "String", + "key": "apache.1:nuvlabox-carl-cori.cpu", + "creation": "2017-09-14 08:12:23.614 UTC", + "content": "1", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:disk.GB", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "disk.GB", + "description": "Disk in GB", + "type": "String", + "key": "apache.1:disk.GB", + "creation": "2017-09-14 08:12:23.614 UTC", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:complete", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "complete", + "description": "'true' when current state is completed", + "type": "String", + "key": "testclient.1:complete", + "creation": "2017-09-14 08:12:23.628 UTC", + "content": "false", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:url.ssh", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "url.ssh", + "description": "SSH URL to connect to virtual machine", + "type": "String", + "key": "testclient.1:url.ssh", + "creation": "2017-09-14 08:12:23.628 UTC", + "content": "ssh://root@172.16.0.11", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:ram.GB", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "ram.GB", + "description": "RAM in GB", + "type": "String", + "key": "apache.1:ram.GB", + "creation": "2017-09-14 08:12:23.614 UTC", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:nuvlabox-carl-cori.ram", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "nuvlabox-carl-cori.ram", + "description": "Amount of RAM, in GB", + "type": "String", + "key": "apache.1:nuvlabox-carl-cori.ram", + "creation": "2017-09-14 08:12:23.614 UTC", + "content": "0.5", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:port", + "runtimeParameter": { + "mappedRuntimeParameterNames": "testclient.1:webserver.port,", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "port", + "description": "Port", + "type": "String", + "key": "apache.1:port", + "creation": "2017-09-14 08:12:23.614 UTC", + "content": "8080", + "group": "apache.1", + "mapsOthers": true + } + }, + { + "string": "testclient.1:webserver.port", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "webserver.port", + "description": "Port on which the web server listens", + "type": "String", + "key": "testclient.1:webserver.port", + "creation": "2017-09-14 08:12:23.666 UTC", + "content": "8080", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:nuvlabox-carl-cori.network.specific.name", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "nuvlabox-carl-cori.network.specific.name", + "description": "Network name", + "type": "String", + "key": "testclient.1:nuvlabox-carl-cori.network.specific.name", + "creation": "2017-09-14 08:12:23.666 UTC", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-carl-cori:cloudservice", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "cloudservice", + "description": "Cloud Service where the node resides", + "type": "String", + "key": "orchestrator-nuvlabox-carl-cori:cloudservice", + "creation": "2017-09-14 08:12:23.680 UTC", + "content": "nuvlabox-carl-cori", + "group": "orchestrator-nuvlabox-carl-cori", + "mapsOthers": false + } + }, + { + "string": "apache.1:scale.state", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "scale.state", + "description": "Defined scalability state", + "type": "String", + "key": "apache.1:scale.state", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "operational", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-carl-cori:is.orchestrator", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "is.orchestrator", + "description": "True if it's an orchestrator", + "type": "String", + "key": "orchestrator-nuvlabox-carl-cori:is.orchestrator", + "creation": "2017-09-14 08:12:23.679 UTC", + "content": "true", + "group": "orchestrator-nuvlabox-carl-cori", + "mapsOthers": false + } + }, + { + "string": "apache.1:nuvlabox-carl-cori.custom.vm.template", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "nuvlabox-carl-cori.custom.vm.template", + "description": "Additional custom textual VM template", + "type": "RestrictedText", + "key": "apache.1:nuvlabox-carl-cori.custom.vm.template", + "creation": "2017-09-14 08:12:23.614 UTC", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:extra.disk.volatile", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "extra.disk.volatile", + "description": "Volatile extra disk in GB", + "type": "String", + "key": "testclient.1:extra.disk.volatile", + "creation": "2017-09-14 08:12:23.666 UTC", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:webserver.ready", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "webserver.ready", + "description": "Server ready to recieve connections", + "type": "String", + "key": "testclient.1:webserver.ready", + "creation": "2017-09-14 08:12:23.666 UTC", + "content": "true", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:cpu.nb", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "cpu.nb", + "description": "Number of CPUs", + "type": "String", + "key": "testclient.1:cpu.nb", + "creation": "2017-09-14 08:12:23.666 UTC", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:cloudservice", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "cloudservice", + "description": "Cloud Service where the node resides", + "type": "String", + "key": "apache.1:cloudservice", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "nuvlabox-carl-cori", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-carl-cori:url.service", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "url.service", + "description": "Optional service URL for virtual machine", + "type": "String", + "key": "orchestrator-nuvlabox-carl-cori:url.service", + "creation": "2017-09-14 08:12:23.679 UTC", + "group": "orchestrator-nuvlabox-carl-cori", + "mapsOthers": false + } + }, + { + "string": "apache.1:disk.attached.device", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "disk.attached.device", + "description": "Attached device name after the VM's vertical scaling", + "type": "String", + "key": "apache.1:disk.attached.device", + "creation": "2017-09-14 08:12:23.613 UTC", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:nuvlabox-carl-cori.custom.vm.template", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "nuvlabox-carl-cori.custom.vm.template", + "description": "Additional custom textual VM template", + "type": "RestrictedText", + "key": "testclient.1:nuvlabox-carl-cori.custom.vm.template", + "creation": "2017-09-14 08:12:23.666 UTC", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:network", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "network", + "description": "Network type", + "type": "Enum", + "key": "apache.1:network", + "creation": "2017-09-14 08:12:23.614 UTC", + "content": "Public", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-carl-cori:max.iaas.workers", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "max.iaas.workers", + "description": "Max number of concurrently provisioned VMs by orchestrator", + "type": "String", + "key": "orchestrator-nuvlabox-carl-cori:max.iaas.workers", + "creation": "2017-09-14 08:12:23.679 UTC", + "content": "7", + "group": "orchestrator-nuvlabox-carl-cori", + "mapsOthers": false + } + }, + { + "string": "testclient.1:network", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "network", + "description": "Network type", + "type": "Enum", + "key": "testclient.1:network", + "creation": "2017-09-14 08:12:23.666 UTC", + "content": "Public", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:hostname", + "runtimeParameter": { + "mappedRuntimeParameterNames": "testclient.1:webserver.hostname,", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "hostname", + "description": "hostname/ip of the image", + "type": "String", + "key": "apache.1:hostname", + "creation": "2017-09-14 08:12:23.614 UTC", + "content": "172.16.0.16", + "group": "apache.1", + "mapsOthers": true + } + }, + { + "string": "apache:ids", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "ids", + "description": "IDs of the machines in a mutable deployment.", + "type": "String", + "key": "apache:ids", + "creation": "2017-09-14 08:12:23.679 UTC", + "content": "1", + "group": "apache", + "mapsOthers": false + } + }, + { + "string": "apache.1:disk.attach.size", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "disk.attach.size", + "description": "Size of the extra disk to attach to the VM during vertical scaling", + "type": "String", + "key": "apache.1:disk.attach.size", + "creation": "2017-09-14 08:12:23.613 UTC", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:scale.iaas.done", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "scale.iaas.done", + "description": "Orchestrator sets to 'true' after scaling the node instance", + "type": "String", + "key": "apache.1:scale.iaas.done", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "false", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:cloudservice", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "cloudservice", + "description": "Cloud Service where the node resides", + "type": "String", + "key": "testclient.1:cloudservice", + "creation": "2017-09-14 08:12:23.628 UTC", + "content": "nuvlabox-carl-cori", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-carl-cori:complete", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "complete", + "description": "'true' when current state is completed", + "type": "String", + "key": "orchestrator-nuvlabox-carl-cori:complete", + "creation": "2017-09-14 08:12:23.679 UTC", + "content": "false", + "group": "orchestrator-nuvlabox-carl-cori", + "mapsOthers": false + } + }, + { + "string": "apache:multiplicity", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "multiplicity", + "description": "Multiplicity number", + "type": "String", + "key": "apache:multiplicity", + "creation": "2017-09-14 08:12:23.679 UTC", + "content": "1", + "group": "apache", + "mapsOthers": false + } + }, + { + "string": "testclient:ids", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "ids", + "description": "IDs of the machines in a mutable deployment.", + "type": "String", + "key": "testclient:ids", + "creation": "2017-09-14 08:12:23.679 UTC", + "content": "1", + "group": "testclient", + "mapsOthers": false + } + }, + { + "string": "testclient.1:image.id", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "image.id", + "description": "Cloud image id", + "type": "String", + "key": "testclient.1:image.id", + "creation": "2017-09-14 08:12:23.666 UTC", + "content": "d88f85a9489e5c05aa2f06a4a878826f", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:disk.detach.device", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "disk.detach.device", + "description": "Name of the block device to detach from the VM during vertical scaling", + "type": "String", + "key": "apache.1:disk.detach.device", + "creation": "2017-09-14 08:12:23.613 UTC", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-carl-cori:url.ssh", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "url.ssh", + "description": "SSH URL to connect to virtual machine", + "type": "String", + "key": "orchestrator-nuvlabox-carl-cori:url.ssh", + "creation": "2017-09-14 08:12:23.679 UTC", + "content": "ssh://root@172.16.0.18", + "group": "orchestrator-nuvlabox-carl-cori", + "mapsOthers": false + } + }, + { + "string": "apache.1:complete", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "complete", + "description": "'true' when current state is completed", + "type": "String", + "key": "apache.1:complete", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "false", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "testclient:max-provisioning-failures", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "max-provisioning-failures", + "description": "Max provisioning failures", + "type": "String", + "key": "testclient:max-provisioning-failures", + "creation": "2017-09-14 08:12:23.679 UTC", + "content": "0", + "group": "testclient", + "mapsOthers": false + } + }, + { + "string": "apache.1:url.ssh", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "url.ssh", + "description": "SSH URL to connect to virtual machine", + "type": "String", + "key": "apache.1:url.ssh", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "ssh://root@172.16.0.16", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-carl-cori:instanceid", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "instanceid", + "description": "Cloud instance id", + "type": "String", + "key": "orchestrator-nuvlabox-carl-cori:instanceid", + "creation": "2017-09-14 08:12:23.679 UTC", + "content": "280", + "group": "orchestrator-nuvlabox-carl-cori", + "mapsOthers": false + } + }, + { + "string": "apache.1:nodename", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "nodename", + "description": "Nodename", + "type": "String", + "key": "apache.1:nodename", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "apache", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:abort", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "abort", + "description": "Machine abort flag, set when aborting", + "type": "String", + "key": "testclient.1:abort", + "creation": "2017-09-14 08:12:23.628 UTC", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "ss:state", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "state", + "description": "Global execution state", + "type": "String", + "key": "ss:state", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "Done", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "ss:groups", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "groups", + "description": "Comma separated node groups", + "type": "String", + "key": "ss:groups", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "nuvlabox-carl-cori:apache,nuvlabox-carl-cori:testclient", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "ss:tags", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "tags", + "description": "Comma separated tag values", + "type": "String", + "key": "ss:tags", + "creation": "2017-09-14 08:12:23.613 UTC", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "apache.1:statecustom", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "statecustom", + "description": "Custom state", + "type": "String", + "key": "apache.1:statecustom", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "Executing script 'module/examples/tutorials/service-testing/apache/13791:Deployment'", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:scale.state", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "scale.state", + "description": "Defined scalability state", + "type": "String", + "key": "testclient.1:scale.state", + "creation": "2017-09-14 08:12:23.628 UTC", + "content": "operational", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:url.service", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "url.service", + "description": "Optional service URL for virtual machine", + "type": "String", + "key": "apache.1:url.service", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "http://172.16.0.16:8080", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "ss:category", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "category", + "description": "Module category", + "type": "String", + "key": "ss:category", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "Deployment", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "apache.1:id", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "id", + "description": "Node instance id", + "type": "String", + "key": "apache.1:id", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "1", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:id", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "id", + "description": "Node instance id", + "type": "String", + "key": "testclient.1:id", + "creation": "2017-09-14 08:12:23.628 UTC", + "content": "1", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "ss:recovery.mode", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "recovery.mode", + "description": "Run abort flag, set when aborting", + "type": "String", + "key": "ss:recovery.mode", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "false", + "group": "Global", + "mapsOthers": false + } + }, + { + "string": "testclient.1:is.orchestrator", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "is.orchestrator", + "description": "True if it's an orchestrator", + "type": "String", + "key": "testclient.1:is.orchestrator", + "creation": "2017-09-14 08:12:23.628 UTC", + "content": "false", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-carl-cori:statecustom", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "statecustom", + "description": "Custom state", + "type": "String", + "key": "orchestrator-nuvlabox-carl-cori:statecustom", + "creation": "2017-09-14 08:12:23.679 UTC", + "content": "No node instances to stop [2017-09-14T08:14:34Z].", + "group": "orchestrator-nuvlabox-carl-cori", + "mapsOthers": false + } + }, + { + "string": "apache.1:image.platform", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "image.platform", + "description": "Platform (eg: ubuntu, windows)", + "type": "String", + "key": "apache.1:image.platform", + "creation": "2017-09-14 08:12:23.613 UTC", + "content": "ubuntu", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:disk.attach.size", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "disk.attach.size", + "description": "Size of the extra disk to attach to the VM during vertical scaling", + "type": "String", + "key": "testclient.1:disk.attach.size", + "creation": "2017-09-14 08:12:23.628 UTC", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:nuvlabox-carl-cori.contextualization.type", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "nuvlabox-carl-cori.contextualization.type", + "description": "Contextualization type", + "type": "Enum", + "key": "testclient.1:nuvlabox-carl-cori.contextualization.type", + "creation": "2017-09-14 08:12:23.666 UTC", + "content": "one-context", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-carl-cori:hostname", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "hostname", + "description": "hostname/ip of the image", + "type": "String", + "key": "orchestrator-nuvlabox-carl-cori:hostname", + "creation": "2017-09-14 08:12:23.679 UTC", + "content": "172.16.0.18", + "group": "orchestrator-nuvlabox-carl-cori", + "mapsOthers": false + } + }, + { + "string": "testclient.1:webserver.hostname", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "webserver.hostname", + "description": "Server hostname", + "type": "String", + "key": "testclient.1:webserver.hostname", + "creation": "2017-09-14 08:12:23.666 UTC", + "content": "172.16.0.16", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:service-offer", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "service-offer", + "description": "Service Offer Id", + "type": "String", + "key": "testclient.1:service-offer", + "creation": "2017-09-14 08:12:23.666 UTC", + "content": "service-offer/7327d738-f2f8-4925-9277-64dc72d6a283", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "apache:max-provisioning-failures", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "max-provisioning-failures", + "description": "Max provisioning failures", + "type": "String", + "key": "apache:max-provisioning-failures", + "creation": "2017-09-14 08:12:23.679 UTC", + "content": "0", + "group": "apache", + "mapsOthers": false + } + }, + { + "string": "apache.1:nuvlabox-carl-cori.is.firewall", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "nuvlabox-carl-cori.is.firewall", + "description": "Firewalling", + "type": "Boolean", + "key": "apache.1:nuvlabox-carl-cori.is.firewall", + "creation": "2017-09-14 08:12:23.614 UTC", + "content": "false", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "testclient.1:nuvlabox-carl-cori.ram", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": true, + "name": "nuvlabox-carl-cori.ram", + "description": "Amount of RAM, in GB", + "type": "String", + "key": "testclient.1:nuvlabox-carl-cori.ram", + "creation": "2017-09-14 08:12:23.666 UTC", + "content": "0.5", + "group": "testclient.1", + "mapsOthers": false + } + }, + { + "string": "orchestrator-nuvlabox-carl-cori:abort", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "abort", + "description": "Machine abort flag, set when aborting", + "type": "String", + "key": "orchestrator-nuvlabox-carl-cori:abort", + "creation": "2017-09-14 08:12:23.679 UTC", + "group": "orchestrator-nuvlabox-carl-cori", + "mapsOthers": false + } + }, + { + "string": "apache.1:abort", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "abort", + "description": "Machine abort flag, set when aborting", + "type": "String", + "key": "apache.1:abort", + "creation": "2017-09-14 08:12:23.613 UTC", + "group": "apache.1", + "mapsOthers": false + } + }, + { + "string": "apache.1:nuvlabox-carl-cori.network.specific.name", + "runtimeParameter": { + "mappedRuntimeParameterNames": "", + "deleted": false, + "isMappedValue": false, + "isSet": false, + "name": "nuvlabox-carl-cori.network.specific.name", + "description": "Network name", + "type": "String", + "key": "apache.1:nuvlabox-carl-cori.network.specific.name", + "creation": "2017-09-14 08:12:23.614 UTC", + "group": "apache.1", + "mapsOthers": false + } + } + ], + "class": "org.hibernate.collection.internal.PersistentMap" + }, + "cloudServiceNames": "nuvlabox-carl-cori", + "startTime": "2017-09-14 08:12:23.474 UTC", + "state": "Done", + "endTime": "2017-09-14 08:18:38.882 UTC", + "category": "Deployment", + "user": "khaled", + "parameters": { + "entry": [ + { + "string": "testclient:run-build-recipes", + "parameter": { + "readonly": false, + "name": "testclient:run-build-recipes", + "description": "Define if the SlipStream executor should run build recipes.", + "category": "General", + "type": "String", + "mandatory": false, + "value": "false", + "order_": 0, + "order": 0 + } + }, + { + "string": "apache:service-offer", + "parameter": { + "readonly": false, + "name": "apache:service-offer", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "service-offer/7327d738-f2f8-4925-9277-64dc72d6a283", + "order_": 0, + "order": 0 + } + }, + { + "string": "testclient:disk.GB", + "parameter": { + "readonly": false, + "name": "testclient:disk.GB", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "", + "order_": 0, + "order": 0 + } + }, + { + "string": "garbage_collected", + "parameter": { + "readonly": false, + "name": "garbage_collected", + "description": "true if the Run was already garbage collected", + "category": "General", + "type": "String", + "mandatory": false, + "value": "false", + "order_": 0, + "order": 0 + } + }, + { + "string": "testclient:ram.GB", + "parameter": { + "readonly": false, + "name": "testclient:ram.GB", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "", + "order_": 0, + "order": 0 + } + }, + { + "string": "apache:cloudservice", + "parameter": { + "readonly": false, + "name": "apache:cloudservice", + "description": "Cloud Service where the node resides", + "category": "General", + "type": "String", + "mandatory": false, + "value": "nuvlabox-carl-cori", + "order_": 0, + "order": 0 + } + }, + { + "string": "apache:cpu.nb", + "parameter": { + "readonly": false, + "name": "apache:cpu.nb", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "", + "order_": 0, + "order": 0 + } + }, + { + "string": "testclient:service-offer", + "parameter": { + "readonly": false, + "name": "testclient:service-offer", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "service-offer/7327d738-f2f8-4925-9277-64dc72d6a283", + "order_": 0, + "order": 0 + } + }, + { + "string": "testclient:cloudservice", + "parameter": { + "readonly": false, + "name": "testclient:cloudservice", + "description": "Cloud Service where the node resides", + "category": "General", + "type": "String", + "mandatory": false, + "value": "nuvlabox-carl-cori", + "order_": 0, + "order": 0 + } + }, + { + "string": "apache:multiplicity", + "parameter": { + "readonly": false, + "name": "apache:multiplicity", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "1", + "order_": 0, + "order": 0 + } + }, + { + "string": "apache:run-build-recipes", + "parameter": { + "readonly": false, + "name": "apache:run-build-recipes", + "description": "Define if the SlipStream executor should run build recipes.", + "category": "General", + "type": "String", + "mandatory": false, + "value": "true", + "order_": 0, + "order": 0 + } + }, + { + "string": "testclient:cpu.nb", + "parameter": { + "readonly": false, + "name": "testclient:cpu.nb", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "", + "order_": 0, + "order": 0 + } + }, + { + "string": "General.keep-running", + "parameter": { + "readonly": false, + "name": "General.keep-running", + "description": "Keep running after deployment", + "category": "General", + "type": "String", + "mandatory": false, + "value": "always", + "order_": 0, + "order": 0 + } + }, + { + "string": "apache:max-provisioning-failures", + "parameter": { + "readonly": false, + "name": "apache:max-provisioning-failures", + "description": "Max provisioning failures", + "category": "General", + "type": "String", + "mandatory": false, + "value": "0", + "order_": 0, + "order": 0 + } + }, + { + "string": "testclient:max-provisioning-failures", + "parameter": { + "readonly": false, + "name": "testclient:max-provisioning-failures", + "description": "Max provisioning failures", + "category": "General", + "type": "String", + "mandatory": false, + "value": "0", + "order_": 0, + "order": 0 + } + }, + { + "string": "apache:disk.GB", + "parameter": { + "readonly": false, + "name": "apache:disk.GB", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "", + "order_": 0, + "order": 0 + } + }, + { + "string": "apache:node.increment", + "parameter": { + "readonly": false, + "name": "apache:node.increment", + "description": "Current increment value for node instances ids", + "category": "General", + "type": "String", + "mandatory": false, + "value": "2", + "order_": 0, + "order": 0 + } + }, + { + "string": "apache:ram.GB", + "parameter": { + "readonly": false, + "name": "apache:ram.GB", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "", + "order_": 0, + "order": 0 + } + }, + { + "string": "testclient:node.increment", + "parameter": { + "readonly": false, + "name": "testclient:node.increment", + "description": "Current increment value for node instances ids", + "category": "General", + "type": "String", + "mandatory": false, + "value": "2", + "order_": 0, + "order": 0 + } + }, + { + "string": "testclient:multiplicity", + "parameter": { + "readonly": false, + "name": "testclient:multiplicity", + "description": "", + "category": "General", + "type": "String", + "mandatory": false, + "value": "1", + "order_": 0, + "order": 0 + } + } + ], + "class": "org.hibernate.collection.internal.PersistentMap" + }, + "creation": "2017-09-14 08:12:23.474 UTC" + } +} \ No newline at end of file diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment/java_to_clj_deployment_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment/java_to_clj_deployment_test.clj new file mode 100644 index 000000000..f0dcee898 --- /dev/null +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment/java_to_clj_deployment_test.clj @@ -0,0 +1,451 @@ +(ns com.sixsq.slipstream.ssclj.resources.deployment.java-to-clj-deployment-test + (:require [com.sixsq.slipstream.ssclj.resources.deployment.java-to-clj-deployment :refer :all] + [clojure.test :refer :all] + [clojure.data.json :as json] + [clojure.data :as data])) + + +(def test-deployment-application-json + (-> "test-resources/deployment-service-testing.json" + slurp + (json/read-str :key-fn keyword))) + +(def test-deployment-build-json + (-> "test-resources/deployment-build-apache-testing.json" + slurp + (json/read-str :key-fn keyword))) + +(def test-deployment-image-json + (-> "test-resources/deployment-image-wordpress-testing.json" + slurp + (json/read-str :key-fn keyword))) + +(def deployment-application-result-edn + {:id "deployment/97089b96-5d99-4ccd-9bfe-99ba3ca21ae2", + :state "Done", + :type "Orchestration", + :category "Deployment", + :module-resource-uri + "module/examples/tutorials/service-testing/system/1940", + :mutable false, + :keep-running "always", + :nodes + {:apache + {:runtime-parameters + {:scale.iaas.done + {:description + "Orchestrator sets to 'true' after scaling the node instance", + :value "false"}, + :nuvlabox-carl-cori.custom.vm.template + {:description "Additional custom textual VM template", :value nil}, + :ready + {:description "Server ready to recieve connections", + :value "true", + :mapped-to ["testclient.1:webserver.ready"]}, + :nuvlabox-carl-cori.is.firewall + {:description "Firewalling", :value "false"}, + :vmstate + {:description "State of the VM, according to the cloud layer", + :value "Unknown"}, + :pre.scale.done + {:description + "Node instance sets to 'true' after running pre-scale script", + :value "false"}, + :nuvlabox-carl-cori.cpu + {:description "Number of CPUs (i.e. virtual cores)", :value "1"}, + :disk.attached.device + {:description + "Attached device name after the VM's vertical scaling", + :value nil}, + :instanceid {:description "Cloud instance id", :value "282"}, + :extra.disk.volatile + {:description "Volatile extra disk in GB", :value nil}, + :statecustom + {:description "Custom state", + :value + "Executing script 'module/examples/tutorials/service-testing/apache/13791:Deployment'"}, + :ids + {:description "IDs of the machines in a mutable deployment.", + :value "1"}, + :hostname + {:description "hostname/ip of the image", + :value "172.16.0.16", + :mapped-to ["testclient.1:webserver.hostname"]}, + :port + {:description "Port", + :value "8080", + :mapped-to ["testclient.1:webserver.port"]}, + :abort + {:description "Machine abort flag, set when aborting", :value nil}, + :nuvlabox-carl-cori.network.specific.name + {:description "Network name", :value nil}, + :image.id + {:description "Cloud image id", + :value "d88f85a9489e5c05aa2f06a4a878826f"}, + :scale.state + {:description "Defined scalability state", :value "operational"}, + :disk.detach.device + {:description + "Name of the block device to detach from the VM during vertical scaling", + :value nil}, + :is.orchestrator + {:description "True if it's an orchestrator", :value "false"}, + :nuvlabox-carl-cori.ram + {:description "Amount of RAM, in GB", :value "0.5"}, + :id {:description "Node instance id", :value "1"}, + :url.ssh + {:description "SSH URL to connect to virtual machine", + :value "ssh://root@172.16.0.16"}, + :complete + {:description "'true' when current state is completed", + :value "false"}, + :network {:description "Network type", :value "Public"}, + :url.service + {:description "Optional service URL for virtual machine", + :value "http://172.16.0.16:8080"}, + :nuvlabox-carl-cori.contextualization.type + {:description "Contextualization type", :value "one-context"}, + :nodename {:description "Nodename", :value "apache"}, + :image.platform + {:description "Platform (eg: ubuntu, windows)", :value "ubuntu"}, + :disk.attach.size + {:description + "Size of the extra disk to attach to the VM during vertical scaling", + :value nil}}, + :parameters + {:service-offer + {:description "", + :value "service-offer/7327d738-f2f8-4925-9277-64dc72d6a283"}, + :cloudservice + {:description "Cloud Service where the node resides", + :value "nuvlabox-carl-cori"}, + :cpu.nb {:description "", :value ""}, + :multiplicity {:description "", :value "1"}, + :run-build-recipes + {:description + "Define if the SlipStream executor should run build recipes.", + :value "true"}, + :max-provisioning-failures + {:description "Max provisioning failures", :value "0"}, + :disk.GB {:description "", :value ""}, + :node.increment + {:description "Current increment value for node instances ids", + :value "2"}, + :ram.GB {:description "", :value ""}}}, + :testclient + {:runtime-parameters + {:scale.iaas.done + {:description + "Orchestrator sets to 'true' after scaling the node instance", + :value "false"}, + :nuvlabox-carl-cori.custom.vm.template + {:description "Additional custom textual VM template", :value nil}, + :nuvlabox-carl-cori.is.firewall + {:description "Firewalling", :value "false"}, + :vmstate + {:description "State of the VM, according to the cloud layer", + :value "Unknown"}, + :pre.scale.done + {:description + "Node instance sets to 'true' after running pre-scale script", + :value "false"}, + :nuvlabox-carl-cori.cpu + {:description "Number of CPUs (i.e. virtual cores)", :value "1"}, + :webserver.port + {:description "Port on which the web server listens", + :value "8080"}, + :disk.attached.device + {:description + "Attached device name after the VM's vertical scaling", + :value nil}, + :instanceid {:description "Cloud instance id", :value "281"}, + :extra.disk.volatile + {:description "Volatile extra disk in GB", :value nil}, + :statecustom + {:description "Custom state", + :value "OK: Hello from Apache deployed by SlipStream!"}, + :ids + {:description "IDs of the machines in a mutable deployment.", + :value "1"}, + :hostname + {:description "hostname/ip of the image", :value "172.16.0.11"}, + :abort + {:description "Machine abort flag, set when aborting", :value nil}, + :nuvlabox-carl-cori.network.specific.name + {:description "Network name", :value nil}, + :image.id + {:description "Cloud image id", + :value "d88f85a9489e5c05aa2f06a4a878826f"}, + :scale.state + {:description "Defined scalability state", :value "operational"}, + :disk.detach.device + {:description + "Name of the block device to detach from the VM during vertical scaling", + :value nil}, + :webserver.hostname + {:description "Server hostname", :value "172.16.0.16"}, + :is.orchestrator + {:description "True if it's an orchestrator", :value "false"}, + :nuvlabox-carl-cori.ram + {:description "Amount of RAM, in GB", :value "0.5"}, + :id {:description "Node instance id", :value "1"}, + :url.ssh + {:description "SSH URL to connect to virtual machine", + :value "ssh://root@172.16.0.11"}, + :complete + {:description "'true' when current state is completed", + :value "false"}, + :webserver.ready + {:description "Server ready to recieve connections", + :value "true"}, + :network {:description "Network type", :value "Public"}, + :url.service + {:description "Optional service URL for virtual machine", + :value "ssh://root@172.16.0.11"}, + :nuvlabox-carl-cori.contextualization.type + {:description "Contextualization type", :value "one-context"}, + :nodename {:description "Nodename", :value "testclient"}, + :image.platform + {:description "Platform (eg: ubuntu, windows)", :value "ubuntu"}, + :disk.attach.size + {:description + "Size of the extra disk to attach to the VM during vertical scaling", + :value nil}}, + :parameters + {:run-build-recipes + {:description + "Define if the SlipStream executor should run build recipes.", + :value "false"}, + :disk.GB {:description "", :value ""}, + :ram.GB {:description "", :value ""}, + :service-offer + {:description "", + :value "service-offer/7327d738-f2f8-4925-9277-64dc72d6a283"}, + :cloudservice + {:description "Cloud Service where the node resides", + :value "nuvlabox-carl-cori"}, + :cpu.nb {:description "", :value ""}, + :max-provisioning-failures + {:description "Max provisioning failures", :value "0"}, + :node.increment + {:description "Current increment value for node instances ids", + :value "2"}, + :multiplicity {:description "", :value "1"}}}, + :orchestrator-nuvlabox-carl-cori + {:runtime-parameters + {:vmstate + {:description "State of the VM, according to the cloud layer", + :value "Unknown"}, + :instanceid {:description "Cloud instance id", :value "280"}, + :max.iaas.workers + {:description + "Max number of concurrently provisioned VMs by orchestrator", + :value "7"}, + :statecustom + {:description "Custom state", + :value "No node instances to stop [2017-09-14T08:14:34Z]."}, + :hostname + {:description "hostname/ip of the image", :value "172.16.0.18"}, + :abort + {:description "Machine abort flag, set when aborting", :value nil}, + :is.orchestrator + {:description "True if it's an orchestrator", :value "true"}, + :url.ssh + {:description "SSH URL to connect to virtual machine", + :value "ssh://root@172.16.0.18"}, + :complete + {:description "'true' when current state is completed", + :value "false"}, + :url.service + {:description "Optional service URL for virtual machine", + :value nil}}}}} + ) + +(def deployment-build-image-result-edn + {:id "deployment/380798cb-bb04-41e4-8498-d8ee090e1643", + :state "Done", + :type "Machine", + :category "Image", + :module-resource-uri + "module/examples/tutorials/service-testing/apache/5071", + :mutable false, + :keep-running "always", + :nodes + {:machine + {:runtime-parameters + {:scale.iaas.done + {:description + "Orchestrator sets to 'true' after scaling the node instance", + :value "false"}, + :ready + {:description "Server ready to recieve connections", :value nil}, + :vmstate + {:description "State of the VM, according to the cloud layer", + :value "Unknown"}, + :pre.scale.done + {:description + "Node instance sets to 'true' after running pre-scale script", + :value "false"}, + :disk.attached.device + {:description + "Attached device name after the VM's vertical scaling", + :value nil}, + :nuvlabox-stanley-cohen.is.firewall + {:description + "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + :value "false"}, + :instanceid {:description "Cloud instance id", :value "120"}, + :extra.disk.volatile + {:description "Volatile extra disk in GB", :value nil}, + :statecustom {:description "Custom state", :value "Image saved !"}, + :hostname + {:description "hostname/ip of the image", :value "172.16.0.15"}, + :port {:description "Port", :value "8080"}, + :abort + {:description "Machine abort flag, set when aborting", :value nil}, + :image.id + {:description "Cloud image id", + :value "d88f85a9489e5c05aa2f06a4a878826f"}, + :scale.state + {:description "Defined scalability state", :value "creating"}, + :disk.detach.device + {:description + "Name of the block device to detach from the VM during vertical scaling", + :value nil}, + :is.orchestrator + {:description "True if it's an orchestrator", :value "false"}, + :nuvlabox-stanley-cohen.cpu + {:description "Number of CPUs (i.e. virtual cores)", :value "1"}, + :nuvlabox-stanley-cohen.custom.vm.template + {:description "Additional custom VM template", :value nil}, + :url.ssh + {:description "SSH URL to connect to virtual machine", + :value "ssh://root@172.16.0.15"}, + :nuvlabox-stanley-cohen.ram + {:description "Amount of RAM, in GB", :value "0.5"}, + :complete + {:description "'true' when current state is completed", + :value "false"}, + :network {:description "Network type", :value "Public"}, + :url.service + {:description "Optional service URL for virtual machine", + :value nil}, + :nuvlabox-stanley-cohen.network.specific.name + {:description "Network name", :value nil}, + :image.platform + {:description "Platform (eg: ubuntu, windows)", :value "ubuntu"}, + :disk.attach.size + {:description + "Size of the extra disk to attach to the VM during vertical scaling", + :value nil}}, + :parameters + {:cloudservice {:description "", :value "nuvlabox-stanley-cohen"}}}}} + ) + +(def deployment-image-result-edn + {:id "deployment/0e0fca32-1bbb-40e3-b2cd-2d97a318694a", + :state "Done", + :type "Run", + :category "Image", + :module-resource-uri "module/apps/WordPress/wordpress/3842", + :mutable false, + :keep-running "always", + :nodes + {:machine + {:runtime-parameters + {:admin_password + {:description "admin password", :value "8rsBZBM659jK"}, + :wordpress_title + {:description "Title (name) to give to the WordPress instance", + :value "Change Me Please 2"}, + :scale.iaas.done + {:description + "Orchestrator sets to 'true' after scaling the node instance", + :value "false"}, + :vmstate + {:description "State of the VM, according to the cloud layer", + :value "Unknown"}, + :pre.scale.done + {:description + "Node instance sets to 'true' after running pre-scale script", + :value "false"}, + :disk.attached.device + {:description + "Attached device name after the VM's vertical scaling", + :value nil}, + :instanceid {:description "Cloud instance id", :value "23"}, + :extra.disk.volatile + {:description "Volatile extra disk in GB", :value nil}, + :statecustom + {:description "Custom state", :value "WordPress ready to go!"}, + :hostname + {:description "hostname/ip of the image", :value "172.16.0.13"}, + :abort + {:description "Machine abort flag, set when aborting", :value nil}, + :nuvlabox-bertil-ohlin.ram + {:description "Amount of RAM, in GB", :value "0.5"}, + :image.id {:description "Cloud image id", :value "8"}, + :scale.state + {:description "Defined scalability state", :value "operational"}, + :disk.detach.device + {:description + "Name of the block device to detach from the VM during vertical scaling", + :value nil}, + :nuvlabox-bertil-ohlin.cpu + {:description "Number of CPUs (i.e. virtual cores)", :value "1"}, + :is.orchestrator + {:description "True if it's an orchestrator", :value "false"}, + :nuvlabox-bertil-ohlin.network.specific.name + {:description "Network name", :value nil}, + :admin_email + {:description "admin email", :value "admin@example.com"}, + :mysql_password + {:description "MySQL password", :value "AX9ytTh2vWF4"}, + :url.ssh + {:description "SSH URL to connect to virtual machine", + :value "ssh://root@172.16.0.13"}, + :complete + {:description "'true' when current state is completed", + :value "false"}, + :network {:description "Network type", :value "Public"}, + :url.service + {:description "Optional service URL for virtual machine", + :value "http://172.16.0.13:8080"}, + :image.platform + {:description "Platform (eg: ubuntu, windows)", :value "ubuntu"}, + :nuvlabox-bertil-ohlin.custom.vm.template + {:description "Additional custom VM template", :value nil}, + :disk.attach.size + {:description + "Size of the extra disk to attach to the VM during vertical scaling", + :value nil}, + :nuvlabox-bertil-ohlin.is.firewall + {:description + "If this flag is set, the instance will be started on the internal network and on the natted network so it can act as a firewall for instances on the internal network.", + :value "false"}}, + :parameters + {:run-build-recipes + {:description + "Define if the SlipStream executor should run build recipes.", + :value "false"}, + :cloudservice {:description "", :value "nuvlabox-bertil-ohlin"}}}}} + ) + +(deftest load-deployment-application-transform + (let [result (transform test-deployment-application-json) + diff-result (data/diff result deployment-application-result-edn)] + (is (and (-> diff-result first nil?) (-> diff-result second nil?))))) + + +(deftest load-deployment-build-transform + (let [result (transform test-deployment-build-json) + diff-result (data/diff result deployment-build-image-result-edn)] + (clojure.pprint/pprint result) + (is (and (-> diff-result first nil?) (-> diff-result second nil?))))) + +(deftest load-deployment-image-transform + (let [result (transform test-deployment-image-json) + diff-result (data/diff result deployment-image-result-edn)] + (is (and (-> diff-result first nil?) (-> diff-result second nil?))))) + + diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj index 46bc815ca..c0a2f88a0 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj @@ -17,12 +17,28 @@ [com.sixsq.slipstream.ssclj.resources.deployment.utils :as du] [com.sixsq.slipstream.ssclj.resources.deployment.state-machine :as dsm] [com.sixsq.slipstream.ssclj.resources.deployment-template-std :as std] + [com.sixsq.slipstream.ssclj.resources.deployment-std :as dstd] [com.sixsq.slipstream.ssclj.resources.lifecycle-test-utils :as ltu] - [com.sixsq.slipstream.ssclj.resources.common.dynamic-load :as dyn])) + [com.sixsq.slipstream.ssclj.resources.common.dynamic-load :as dyn] + [clj-http.fake :refer [with-fake-routes]])) (use-fixtures :once t/setup-embedded-zk) -(use-fixtures :each (join-fixtures [t/with-test-es-client-fixture t/cleanup-all-zk-nodes])) +(defn fake-http-java-server [f] + (with-fake-routes + {"http://localhost:8182/run" (fn + [request] + {:status 201 + :headers + {"Location" + "http://localhost:8182/run/97089b96-5d99-4ccd-9bfe-99ba3ca21ae2"}}) + "http://localhost:8182/run/97089b96-5d99-4ccd-9bfe-99ba3ca21ae2" + (fn [request] {:status 200 + :body (slurp "test-resources/deployment-service-testing.json")}) + } + (f))) + +(use-fixtures :each (join-fixtures [t/with-test-es-client-fixture t/cleanup-all-zk-nodes fake-http-java-server])) (def base-uri (str p/service-context resource-url)) @@ -62,10 +78,10 @@ template-url (str p/service-context dt/resource-url "/" std/method) session-admin (-> (session (ring-app)) (content-type "application/json") - (header authn-info-header "root ADMIN")) + (header authn-info-header "super ADMIN")) session-user (-> (session (ring-app)) (content-type "application/json") - (header authn-info-header "jane USER ANON")) + (header authn-info-header "test USER ANON")) session-anon (-> (session (ring-app)) (content-type "application/json") (header authn-info-header "unknown ANON")) @@ -75,57 +91,16 @@ (ltu/is-status 200) (get-in [:response :body])) - no-href-create {:deploymentTemplate (strip-unwanted-attrs (assoc template - :module "nom/module"))} - href-create {:deploymentTemplate {:href href - :module "nom/module"}} + no-href-create {:deploymentTemplate (strip-unwanted-attrs + (assoc template + :module "module/examples/tutorials/service-testing/system/1940"))} + href-create {:deploymentTemplate {:href href + :module "module/examples/tutorials/service-testing/system/1940"}} invalid-create (assoc-in href-create [:deploymentTemplate :href] "deployment-template/unknown-template")] - ;; admin user collection query should succeed but be empty (no deployments created yet) - ;(-> session-admin - ; (request base-uri) - ; (ltu/body->edn) - ; (ltu/is-status 200) - ; (ltu/is-count zero?) - ; (ltu/is-operation-present "add") - ; (ltu/is-operation-absent "delete") - ; (ltu/is-operation-absent "edit")) - ; - ;;; create a new deployment as administrator; fail without reference - ;(-> session-admin - ; (request base-uri - ; :request-method :post - ; :body (json/write-str no-href-create)) - ; (ltu/body->edn) - ; (ltu/is-status 400)) - ; - ;;; anonymous create must fail - ;(-> session-anon - ; (request base-uri - ; :request-method :post - ; :body (json/write-str href-create)) - ; (ltu/body->edn) - ; (ltu/is-status 403)) - ; - ;;; anonymous create without template reference fails - ;(-> session-anon - ; (request base-uri - ; :request-method :post - ; :body (json/write-str no-href-create)) - ; (ltu/body->edn) - ; (ltu/is-status 400)) - ; - ;;; admin create with invalid template fails - ;(-> session-admin - ; (request base-uri - ; :request-method :post - ; :body (json/write-str invalid-create)) - ; (ltu/body->edn) - ; (ltu/is-status 400)) - - ;; create a deployment via admin + ;; create a deployment via user (let [create-req href-create - resp (-> session-admin + resp (-> session-user (request base-uri :request-method :post :body (json/write-str create-req)) @@ -137,20 +112,13 @@ abs-uri (str p/service-context (u/de-camelcase uri))] ;; admin should be able to see, edit, and delete deployment - (-> session-admin + (-> session-user (request abs-uri) (ltu/body->edn) (ltu/is-status 200) (ltu/is-operation-present "delete") (ltu/is-operation-absent "edit")) - (-> session-user - (request abs-uri) - (ltu/body->edn) - (ltu/is-status 403) - (ltu/is-operation-absent "delete") - (ltu/is-operation-absent "edit")) - ;; admin can delete resource (-> session-admin (request abs-uri @@ -169,7 +137,7 @@ (ltu/location)) abs-uri (str p/service-context (u/de-camelcase uri))] - ;; admin should be able to see, edit, and delete deployment + ;; admin should be able to see, and delete deployment (-> session-admin (request abs-uri) (ltu/body->edn) @@ -190,6 +158,7 @@ :request-method :delete) (ltu/body->edn) (ltu/is-status 200))) + )) ; From 41a13276910d3ca4e03c95e82f45d688d23d1b42 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Tue, 19 Sep 2017 09:28:45 +0200 Subject: [PATCH 43/46] fix lifecycle tests for deployment --- .../slipstream/ssclj/resources/deployment.clj | 6 +- .../ssclj/resources/deployment/utils.clj | 5 +- .../ssclj/resources/deployment_std.clj | 11 +- .../resources/deployment_lifecycle_test.clj | 555 +++++++----------- 4 files changed, 233 insertions(+), 344 deletions(-) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj index c8e275a31..afc43c93e 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj @@ -18,7 +18,8 @@ [clojure.tools.logging :as log] [clojure.core.async :as async] [clj-time.core :as time] - [com.sixsq.slipstream.ssclj.util.log :as logu]) + [com.sixsq.slipstream.ssclj.util.log :as logu] + [clj-http.client :as http]) (:import (clojure.lang ExceptionInfo))) (def ^:const resource-name du/deployment-resource-name) @@ -168,7 +169,7 @@ (assoc deployment :start-time now))) (defmethod crud/do-action [resource-url "start"] - [{{uuid :uuid} :params identity :identity :as request}] + [{{uuid :uuid} :params identity :identity username :user-name :as request}] (try (let [current (-> (str (u/de-camelcase resource-name) "/" uuid) (db/retrieve request) @@ -178,6 +179,7 @@ (u/update-timestamps) (crud/validate))] (du/create-parameters identity current) + (http/post (str du/slipstream-java-endpoint "/run/" uuid) {:headers {"slipstream-authn-info" username}}) (db/edit deployment request)) (catch ExceptionInfo ei (ex-data ei)))) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj index 052872771..73b83db47 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj @@ -12,7 +12,8 @@ [com.sixsq.slipstream.ssclj.resources.zk.deployment.utils :as zdu] [com.sixsq.slipstream.ssclj.resources.deployment.state-machine :as dsm] [com.sixsq.slipstream.ssclj.util.zookeeper :as uzk] - [clojure.string :as string]) + [clojure.string :as string] + [environ.core :as env]) (:import (clojure.lang ExceptionInfo))) (def ^:const deployment-resource-name "Deployment") @@ -31,6 +32,8 @@ :type "ROLE" :right "MODIFY"}]}) +(def slipstream-java-endpoint (or (env/env :slipstream-java-endpoint) "http://localhost:8182")) + (def deployment-parameter-id-separator "_") (defn deployment-href-to-uuid [href] (string/replace-first href #"^deployment/" "")) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_std.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_std.clj index 5f7b9c087..29ffc3458 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_std.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_std.clj @@ -6,11 +6,9 @@ [com.sixsq.slipstream.ssclj.resources.deployment :as d] [com.sixsq.slipstream.ssclj.resources.deployment-template-std :as dtpl] [com.sixsq.slipstream.ssclj.resources.common.utils :as u] - [environ.core :as env] [clj-http.client :as http] - [clojure.data.json :as json])) - -(def slipstream-java-endpoint (or (env/env :slipstream-java-endpoint) "http://localhost:8182")) + [clojure.data.json :as json] + [com.sixsq.slipstream.ssclj.resources.deployment.utils :as du])) ;; ;; validate the create resource @@ -26,14 +24,13 @@ ;; (defmethod d/tpl->deployment dtpl/method [{module :module :as resource} {username :user-name :as request}] - (let [java-deployment-location (-> (http/post (str slipstream-java-endpoint "/run") + (let [java-deployment-location (-> (http/post (str du/slipstream-java-endpoint "/run") {:headers {"slipstream-authn-info" username} :form-params {:refqname module :bypass-ssh-check true}}) (get-in [:headers "Location"])) java-deployment-json (-> (http/get java-deployment-location {:headers {"slipstream-authn-info" username "Accept" "application/json"}}) :body - (json/read-str :key-fn keyword)) - ] + (json/read-str :key-fn keyword))] (java-to-clj-deployment/transform java-deployment-json))) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj index c0a2f88a0..30c4fedb5 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj @@ -33,9 +33,9 @@ {"Location" "http://localhost:8182/run/97089b96-5d99-4ccd-9bfe-99ba3ca21ae2"}}) "http://localhost:8182/run/97089b96-5d99-4ccd-9bfe-99ba3ca21ae2" - (fn [request] {:status 200 - :body (slurp "test-resources/deployment-service-testing.json")}) - } + {:get (fn [request] {:status 200 + :body (slurp "test-resources/deployment-service-testing.json")}) + :post (fn [request] {:status 200})}} (f))) (use-fixtures :each (join-fixtures [t/with-test-es-client-fixture t/cleanup-all-zk-nodes fake-http-java-server])) @@ -53,27 +53,8 @@ :created :updated :name :description}] (into {} (remove #(unwanted (first %)) m)))) -(def valid-entry-deployment-uuid "dfd34916-6ede-47f7-aaeb-a30ddecbba5c") - -(def valid-entry - {:id (str resource-url "/" valid-entry-deployment-uuid) - :resourceURI resource-uri - :module-resource-uri "module/examples/tutorials/service-testing/system/1940" - :category "Deployment" - :type "Orchestration" - :mutable false - :keep-running true - :nodes {:node1 {:parameters {:cloudservice {:description "p1 description" ;TODO only node name and multiplicity are being used for now from all these parameters - :value "abc"} - :multiplicity {:value "2"}} - :runtime-parameters {:p1 {:description "p1 description" - :value "abc" - :mapped-to "a"}}} - :node2 {:parameters {:cloudservice {:description "param1 description" - :value "abc"}}}}}) - - -(deftest lifecycle +(deftest create-deployment + (let [href (str dt/resource-url "/" std/method) template-url (str p/service-context dt/resource-url "/" std/method) session-admin (-> (session (ring-app)) @@ -157,314 +138,220 @@ (request abs-uri :request-method :delete) (ltu/body->edn) - (ltu/is-status 200))) + (ltu/is-status 200))))) + +(deftest start-deployment + + (let [href (str dt/resource-url "/" std/method) + template-url (str p/service-context dt/resource-url "/" std/method) + session-admin (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "super ADMIN")) + session-user (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "test USER ANON")) + session-anon (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "unknown ANON")) + template (-> session-admin + (request template-url) + (ltu/body->edn) + (ltu/is-status 200) + (get-in [:response :body])) + + href-create {:deploymentTemplate {:href href + :module "module/examples/tutorials/service-testing/system/1940"}}] + + (let [create-req href-create + resp (-> session-user + (request base-uri + :request-method :post + :body (json/write-str create-req)) + (ltu/body->edn) + (ltu/is-status 201)) + id (get-in resp [:response :body :resource-id]) + uri (-> resp + (ltu/location)) + abs-uri (str p/service-context (u/de-camelcase uri)) + deployment (-> session-user + (request abs-uri) + (ltu/body->edn)) + start-uri (str p/service-context + (t/get-op deployment "http://schemas.dmtf.org/cimi/2/action/start")) + started-deployment (-> session-user + (request start-uri) + (t/body->edn) + (t/is-status 200))] + + (is (not (get-in deployment [:body :start-time]))) + (is (get-in started-deployment [:response :body :start-time])) + + (is (= dsm/init-state (get-in started-deployment [:response :body :state]))) + + (are [expected value] + (= expected value) + dsm/init-state (uzk/get-data (str zdu/separator uri "/state")) + "unknown" (uzk/get-data + (str zdu/separator uri "/" zdu/nodes-name "/apache/1/" "vmstate")))))) + + +(deftest update-deployment-state + + (let [href (str dt/resource-url "/" std/method) + template-url (str p/service-context dt/resource-url "/" std/method) + session-admin (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "super ADMIN")) + session-user (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "test USER ANON")) + session-anon (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "unknown ANON")) + template (-> session-admin + (request template-url) + (ltu/body->edn) + (ltu/is-status 200) + (get-in [:response :body])) + + href-create {:deploymentTemplate {:href href + :module "module/examples/tutorials/service-testing/system/1940"}}] + + (let [create-req href-create + resp (-> session-user + (request base-uri + :request-method :post + :body (json/write-str create-req)) + (ltu/body->edn) + (ltu/is-status 201)) + id (get-in resp [:response :body :resource-id]) + uri (-> resp + (ltu/location)) + abs-uri (str p/service-context (u/de-camelcase uri)) + deployment (-> session-user + (request abs-uri) + (ltu/body->edn)) + start-uri (str p/service-context + (t/get-op deployment "http://schemas.dmtf.org/cimi/2/action/start")) + started-deployment (-> session-user + (request start-uri) + (t/body->edn) + (t/is-status 200)) + abs-uri-deployment-parameter-state (str p/service-context dp/resource-url + "/" (du/deployment-href-to-uuid uri) "_state") + update-deployment-parameter-state + (-> session-user + (request abs-uri-deployment-parameter-state :request-method :put + :body (json/write-str {:value dsm/provisioning-state})) + (t/body->edn) + (t/is-status 403)) + update-deployment-parameter-state + (-> session-admin + (request abs-uri-deployment-parameter-state :request-method :put + :body (json/write-str {:value dsm/provisioning-state})) + (t/body->edn) + (t/is-status 200)) + provisioning-deployment (-> session-user + (request start-uri) + (t/body->edn) + (t/is-status 200))] + + (is (= dsm/provisioning-state (get-in provisioning-deployment [:response :body :state]))) + + (is (= dsm/provisioning-state (uzk/get-data (str zdu/separator uri "/state")))) + ))) + +(deftest update-deployment-move-states-abort + + (let [href (str dt/resource-url "/" std/method) + template-url (str p/service-context dt/resource-url "/" std/method) + session-admin (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "super ADMIN")) + session-user (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "test USER ANON")) + session-anon (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "unknown ANON")) + template (-> session-admin + (request template-url) + (ltu/body->edn) + (ltu/is-status 200) + (get-in [:response :body])) + + href-create {:deploymentTemplate {:href href + :module "module/examples/tutorials/service-testing/system/1940"}}] + + (let [create-req href-create + resp (-> session-user + (request base-uri + :request-method :post + :body (json/write-str create-req)) + (ltu/body->edn) + (ltu/is-status 201)) + id (get-in resp [:response :body :resource-id]) + uri (-> resp + (ltu/location)) + abs-uri (str p/service-context (u/de-camelcase uri)) + deployment (-> session-user + (request abs-uri) + (ltu/body->edn)) + start-uri (str p/service-context + (t/get-op deployment "http://schemas.dmtf.org/cimi/2/action/start")) + started-deployment (-> session-user + (request start-uri) + (t/body->edn) + (t/is-status 200)) + abs-uri-deployment-parameter-state (str p/service-context dp/resource-url + "/" (du/deployment-href-to-uuid uri) "_state") + update-deployment-parameter-state + (-> session-user + (request abs-uri-deployment-parameter-state :request-method :put + :body (json/write-str {:value dsm/provisioning-state})) + (t/body->edn) + (t/is-status 403)) + update-deployment-parameter-state + (-> session-admin + (request abs-uri-deployment-parameter-state :request-method :put + :body (json/write-str {:value dsm/provisioning-state})) + (t/body->edn) + (t/is-status 200)) + provisioning-deployment (-> session-user + (request start-uri) + (t/body->edn) + (t/is-status 200))] + + (-> session-admin + (request (str p/service-context (du/deployment-parameter-href + {:deployment {:href uri} :node-name "testclient" + :node-index 1 :name "state-complete"})) + :request-method :put :body (json/write-str {:value dsm/provisioning-state})) + (t/body->edn) + (t/is-status 200)) + (-> session-admin + (request (str p/service-context (du/deployment-parameter-href + {:deployment {:href uri} :node-name "apache" + :node-index 1 :name "state-complete"})) + :request-method :put :body (json/write-str {:value dsm/provisioning-state})) + (t/body->edn) + (t/is-status 200)) + + (-> session-admin + (request (str p/service-context (du/deployment-parameter-href + {:deployment {:href uri} :node-name "apache" + :node-index 1 :name "abort"})) + :request-method :put :body (json/write-str {:value "Error in node 1 abort the run"})) + (t/body->edn) + (t/is-status 200)) + + (is (= 1 (count (uzk/children + (zdu/deployment-state-path uri))))) + + (is (= dsm/aborted-state (uzk/get-data (str zdu/separator uri "/state")))) - )) - -; -;(deftest create-deployment -; -; (let [session-admin-json (-> (session (ring-app)) -; (content-type "application/json") -; (header authn-info-header "super ADMIN USER ANON")) -; session-admin-form (-> (session (ring-app)) -; (content-type "application/x-www-form-urlencoded") -; (header authn-info-header "super ADMIN USER ANON")) -; session-user (-> (session (ring-app)) -; (content-type "application/json") -; (header authn-info-header "jane USER ANON")) -; session-anon (-> (session (ring-app)) -; (content-type "application/json"))] -; -; ;; adding, retrieving and deleting entry as user should succeed -; (let [deployment-href (-> session-user -; (request base-uri -; :request-method :post -; :body (json/write-str valid-entry)) -; (t/body->edn) -; (t/is-status 201) -; (t/location)) -; abs-uri (str p/service-context (u/de-camelcase deployment-href)) -; created-deployment (-> session-user -; (request abs-uri) -; (t/body->edn) -; (t/is-status 200))] -; -; (is (not (uzk/exists (str zdu/separator deployment-href))))))) -; -; -;(deftest start-deployment -; -; (let [session-admin-json (-> (session (ring-app)) -; (content-type "application/json") -; (header authn-info-header "super ADMIN USER ANON")) -; session-admin-form (-> (session (ring-app)) -; (content-type "application/x-www-form-urlencoded") -; (header authn-info-header "super ADMIN USER ANON")) -; session-user (-> (session (ring-app)) -; (content-type "application/json") -; (header authn-info-header "jane USER ANON")) -; session-anon (-> (session (ring-app)) -; (content-type "application/json"))] -; -; ;; adding, retrieving and deleting entry as user should succeed -; (let [deployment-href (-> session-user -; (request base-uri -; :request-method :post -; :body (json/write-str valid-entry)) -; (t/body->edn) -; (t/is-status 201) -; (t/location)) -; abs-uri (str p/service-context (u/de-camelcase deployment-href)) -; created-deployment (-> session-user -; (request abs-uri) -; (t/body->edn) -; (t/is-status 200)) -; start-uri (str p/service-context -; (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) -; started-deployment (-> session-user -; (request start-uri) -; (t/body->edn) -; (t/is-status 200)) -; ] -; -; (is (not (get-in created-deployment [:body :start-time]))) -; (is (get-in started-deployment [:response :body :start-time])) -; -; (is (= dsm/init-state (get-in started-deployment [:response :body :state]))) -; -; (are [expected value] -; (= expected value) -; dsm/init-state (uzk/get-data (str zdu/separator deployment-href "/state")) -; "unknown" (uzk/get-data -; (str zdu/separator deployment-href "/" zdu/nodes-name "/node2/1/" "vmstate")))))) -; -;(deftest create-deployment-update-deployment-state -; -; (let [session-admin-json (-> (session (ring-app)) -; (content-type "application/json") -; (header authn-info-header "super ADMIN USER ANON")) -; session-user (-> (session (ring-app)) -; (content-type "application/json") -; (header authn-info-header "jane USER ANON"))] -; -; ;; adding, retrieving and deleting entry as user should succeed -; (let [deployment-href (-> session-user -; (request base-uri -; :request-method :post -; :body (json/write-str valid-entry)) -; (t/body->edn) -; (t/is-status 201) -; (t/location)) -; abs-uri (str p/service-context (u/de-camelcase deployment-href)) -; abs-uri-deployment-parameter-state (str p/service-context dp/resource-url -; "/" valid-entry-deployment-uuid "_state") -; created-deployment (-> session-user -; (request abs-uri) -; (t/body->edn) -; (t/is-status 200)) -; start-uri (str p/service-context -; (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) -; started-deployment (-> session-user -; (request start-uri) -; (t/body->edn) -; (t/is-status 200)) -; update-deployment-parameter-state -; (-> session-user -; (request abs-uri-deployment-parameter-state :request-method :put -; :body (json/write-str {:value dsm/provisioning-state})) -; (t/body->edn) -; (t/is-status 403)) -; update-deployment-parameter-state -; (-> session-admin-json -; (request abs-uri-deployment-parameter-state :request-method :put -; :body (json/write-str {:value dsm/provisioning-state})) -; (t/body->edn) -; (t/is-status 200)) -; provisioning-deployment (-> session-user -; (request start-uri) -; (t/body->edn) -; (t/is-status 200))] -; -; (is (= dsm/provisioning-state (get-in provisioning-deployment [:response :body :state]))) -; -; (is (= dsm/provisioning-state (uzk/get-data (str zdu/separator deployment-href "/state")))) -; ))) -; -;(deftest create-deployment-move-states -; -; (let [session-admin-json (-> (session (ring-app)) -; (content-type "application/json") -; (header authn-info-header "super ADMIN USER ANON")) -; session-user (-> (session (ring-app)) -; (content-type "application/json") -; (header authn-info-header "jane USER ANON"))] -; -; ;; adding, retrieving and deleting entry as user should succeed -; (let [deployment-href (-> session-user -; (request base-uri -; :request-method :post -; :body (json/write-str valid-entry)) -; (t/body->edn) -; (t/location)) -; abs-uri (str p/service-context (u/de-camelcase deployment-href)) -; abs-uri-deployment-parameter-state (str p/service-context dp/resource-url -; "/" valid-entry-deployment-uuid "_state") -; created-deployment (-> session-user -; (request abs-uri) -; (t/body->edn)) -; start-uri (str p/service-context -; (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) -; started-deployment (-> session-user -; (request start-uri) -; (t/body->edn)) -; update-deployment-parameter-state -; (-> session-admin-json -; (request abs-uri-deployment-parameter-state :request-method :put -; :body (json/write-str {:value dsm/provisioning-state})) -; (t/body->edn) -; (t/is-status 200)) -; -; provisioning-deployment (-> session-user -; (request start-uri) -; (t/body->edn) -; (t/is-status 200))] -; (is (= dsm/provisioning-state (get-in provisioning-deployment [:response :body :state]))) -; -; (is (= dsm/provisioning-state (uzk/get-data (str zdu/separator deployment-href "/state")))) -; -; (-> session-admin-json -; (request (str p/service-context (du/deployment-parameter-href -; {:deployment {:href deployment-href} :node-name "node1" -; :node-index 1 :name "state-complete"})) -; :request-method :put :body (json/write-str {:value dsm/provisioning-state})) -; (t/body->edn) -; (t/is-status 200)) -; (-> session-admin-json -; (request (str p/service-context (du/deployment-parameter-href -; {:deployment {:href deployment-href} :node-name "node1" -; :node-index 2 :name "state-complete"})) -; :request-method :put :body (json/write-str {:value dsm/provisioning-state})) -; (t/body->edn) -; (t/is-status 200)) -; -; (is (= 1 (count (uzk/children -; (zdu/deployment-state-path deployment-href))))) -; -; (-> session-admin-json -; (request (str p/service-context (du/deployment-parameter-href -; {:deployment {:href deployment-href} :node-name "node2" -; :node-index 1 :name "state-complete"})) -; :request-method :put :body (json/write-str {:value dsm/provisioning-state})) -; (t/body->edn) -; (t/is-status 200)) -; -; (is (= dsm/executing-state (uzk/get-data (str zdu/separator deployment-href "/state")))) -; -; (is (= dsm/executing-state (-> session-user -; (request (str p/service-context deployment-href)) -; (t/body->edn) -; (get-in [:response :body :state])))) -; -; (is (= 3 (count (uzk/children -; (zdu/deployment-state-path deployment-href))))) -; -; (-> session-admin-json -; (request (str p/service-context (du/deployment-parameter-href -; {:deployment {:href deployment-href} :node-name "node1" -; :node-index 1 :name "state-complete"})) -; :request-method :put :body (json/write-str {:value dsm/executing-state})) -; (t/body->edn) -; (t/is-status 200)) -; (-> session-admin-json -; (request (str p/service-context (du/deployment-parameter-href -; {:deployment {:href deployment-href} :node-name "node1" -; :node-index 2 :name "state-complete"})) -; :request-method :put :body (json/write-str {:value dsm/executing-state})) -; (t/body->edn) -; (t/is-status 200)) -; -; (-> session-admin-json -; (request (str p/service-context (du/deployment-parameter-href -; {:deployment {:href deployment-href} :node-name "node2" -; :node-index 1 :name "state-complete"})) -; :request-method :put :body (json/write-str {:value dsm/executing-state})) -; (t/body->edn) -; (t/is-status 200)) -; -; (is (= dsm/sending-report-state (-> session-user -; (request (str p/service-context deployment-href)) -; (t/body->edn) -; (get-in [:response :body :state])))) -; -; ))) -; -; -;(deftest create-deployment-move-states-abort -; -; (let [session-admin-json (-> (session (ring-app)) -; (content-type "application/json") -; (header authn-info-header "super ADMIN USER ANON")) -; session-user (-> (session (ring-app)) -; (content-type "application/json") -; (header authn-info-header "jane USER ANON"))] -; -; ;; adding, retrieving and deleting entry as user should succeed -; (let [deployment-href (-> session-user -; (request base-uri -; :request-method :post -; :body (json/write-str valid-entry)) -; (t/body->edn) -; (t/location)) -; abs-uri (str p/service-context (u/de-camelcase deployment-href)) -; abs-uri-deployment-parameter-state (str p/service-context dp/resource-url -; "/" valid-entry-deployment-uuid "_state") -; created-deployment (-> session-user -; (request abs-uri) -; (t/body->edn)) -; start-uri (str p/service-context -; (t/get-op created-deployment "http://schemas.dmtf.org/cimi/2/action/start")) -; started-deployment (-> session-user -; (request start-uri) -; (t/body->edn)) -; update-deployment-parameter-state -; (-> session-admin-json -; (request abs-uri-deployment-parameter-state :request-method :put -; :body (json/write-str {:value dsm/provisioning-state})) -; (t/body->edn) -; (t/is-status 200))] -; -; (-> session-admin-json -; (request (str p/service-context (du/deployment-parameter-href -; {:deployment {:href deployment-href} :node-name "node1" -; :node-index 1 :name "state-complete"})) -; :request-method :put :body (json/write-str {:value dsm/provisioning-state})) -; (t/body->edn) -; (t/is-status 200)) -; (-> session-admin-json -; (request (str p/service-context (du/deployment-parameter-href -; {:deployment {:href deployment-href} :node-name "node1" -; :node-index 2 :name "state-complete"})) -; :request-method :put :body (json/write-str {:value dsm/provisioning-state})) -; (t/body->edn) -; (t/is-status 200)) -; -; (-> session-admin-json -; (request (str p/service-context (du/deployment-parameter-href -; {:deployment {:href deployment-href} :node-name "node2" -; :node-index 1 :name "abort"})) -; :request-method :put :body (json/write-str {:value "Error in node 1 abort the run"})) -; (t/body->edn) -; (t/is-status 200)) -; -; (is (= 1 (count (uzk/children -; (zdu/deployment-state-path deployment-href))))) -; -; (is (= dsm/aborted-state (uzk/get-data (str zdu/separator deployment-href "/state")))) -; -; (is (= dsm/aborted-state (-> session-user -; (request (str p/service-context deployment-href)) -; (t/body->edn) -; (get-in [:response :body :state])))) -; -; ))) \ No newline at end of file + (is (= dsm/aborted-state (-> session-user + (request (str p/service-context uri)) + (t/body->edn) + (get-in [:response :body :state])))) + ))) From a683fafa996d44bc114ef8239faaff31815f1115 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Tue, 19 Sep 2017 19:45:02 +0200 Subject: [PATCH 44/46] set java runtime parameter are propagated to ssclj and dyn creation of depl params --- .../com/sixsq/slipstream/persistence/Run.java | 2 +- .../persistence/RuntimeParameter.java | 50 ++++++++++- .../com/sixsq/slipstream/util/SscljProxy.java | 4 + .../sixsq/slipstream/run/RunListResource.java | 2 +- .../ssclj/resources/deployment/utils.clj | 84 ++++++++----------- .../resources/deployment_lifecycle_test.clj | 6 +- .../deployment_parameter_lifecycle_test.clj | 16 ++-- 7 files changed, 101 insertions(+), 63 deletions(-) diff --git a/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/Run.java b/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/Run.java index b7ed16cde..d9b2f9d3c 100644 --- a/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/Run.java +++ b/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/Run.java @@ -1135,7 +1135,7 @@ public void addGroup(String group, String serviceName) { @Attribute @Column(length = 1024) public String getGroups() { - getRuntimeParameters().get(RuntimeParameter.GLOBAL_NODE_GROUPS_KEY).setValue(groups); + getRuntimeParameters().get(RuntimeParameter.GLOBAL_NODE_GROUPS_KEY).setInitValue(groups); return groups; } diff --git a/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/RuntimeParameter.java b/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/RuntimeParameter.java index 5bb24c7c9..128ee1dad 100644 --- a/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/RuntimeParameter.java +++ b/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/RuntimeParameter.java @@ -20,9 +20,7 @@ * -=================================================================- */ -import java.util.Arrays; -import java.util.List; -import java.util.Properties; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -36,11 +34,18 @@ import javax.persistence.NoResultException; import javax.persistence.Query; +import com.google.gson.JsonObject; +import org.restlet.Response; import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Text; import com.sixsq.slipstream.exceptions.ValidationException; + +import com.sixsq.slipstream.util.SscljProxy; + +import static com.sixsq.slipstream.util.ServiceOffersUtil.parseJson; + /** * Unit tests: * @@ -349,7 +354,7 @@ private void init() { if (GLOBAL_NAMESPACE.equals(group_)) { group_ = "Global"; } - setValue(value); + setInitValue(value); } public boolean isMappedValue() { @@ -390,13 +395,50 @@ public String getResourceUri() { return resourceUri; } + public static String getSScljDeploymentParameterUri(RuntimeParameter rp) { + String deploymentParameterId = "deployment-parameter/" + rp.container.getUuid() + "_"; + String paramName = rp.name_.replace(".", "-"); + if (!rp.group_.equals("Global")) { + String nodeIndex = rp.key_.replaceAll("^" + rp.group_ + ":", ""); + nodeIndex = nodeIndex.replaceAll(":" + paramName +"$", ""); + if (!nodeIndex.isEmpty()) { + deploymentParameterId = deploymentParameterId + String.join("_", rp.group_, "1", paramName); + } else { + deploymentParameterId = deploymentParameterId + + String.join("_", rp.group_, nodeIndex, paramName); + } + } else { + paramName = paramName.replaceAll("^ss:", ""); + deploymentParameterId = deploymentParameterId + paramName; + } + return SscljProxy.BASE_RESOURCE + deploymentParameterId; + } + public String getValue() { + /*Response response; + JsonObject res = new JsonObject(); + response = SscljProxy.get(getSScljDeploymentParameterUri(this), "super ADMIN"); + if (response != null && response.getStatus().getCode() == 200) { + res = parseJson(response.getEntityAsText()); + return res.get("value").toString(); + }*/ return value; } + public void setInitValue(String value) { + setIsSet(!isNullOrEmpty(value)); + this.value = value; + processValue(); + } + public void setValue(String value) { setIsSet(!isNullOrEmpty(value)); this.value = value; + + Map mapValue = new HashMap(); + mapValue.put("value", value); + SscljProxy.put(getSScljDeploymentParameterUri(this), + "super ADMIN", mapValue, true); processValue(); } diff --git a/jar-persistence/src/main/java/com/sixsq/slipstream/util/SscljProxy.java b/jar-persistence/src/main/java/com/sixsq/slipstream/util/SscljProxy.java index 376dd4f93..97cb5a620 100644 --- a/jar-persistence/src/main/java/com/sixsq/slipstream/util/SscljProxy.java +++ b/jar-persistence/src/main/java/com/sixsq/slipstream/util/SscljProxy.java @@ -85,6 +85,10 @@ public static Response put(String resource, String username, Object obj) { return request(Method.PUT, resource, obj, username, null, null, null); } + public static Response put(String resource, String username, Object obj, Boolean throwException) { + return request(Method.PUT, resource, obj, username, null, null, throwException); + } + public static Response post(String resource, Object obj) { return request(Method.POST, resource, obj, null, null, null, null); } diff --git a/jar-service/src/main/java/com/sixsq/slipstream/run/RunListResource.java b/jar-service/src/main/java/com/sixsq/slipstream/run/RunListResource.java index 7a4dd36e0..350d52f60 100644 --- a/jar-service/src/main/java/com/sixsq/slipstream/run/RunListResource.java +++ b/jar-service/src/main/java/com/sixsq/slipstream/run/RunListResource.java @@ -251,7 +251,7 @@ private void validateUserPublicKey(User user, RunType type, Form form) throws Va private void setTags(Run run, Form form) { RuntimeParameter rp = run.getRuntimeParameters().get(RuntimeParameter.GLOBAL_TAGS_KEY); if (rp != null){ - rp.setValue(form.getFirstValue(TAGS_KEY, "")); + rp.setInitValue(form.getFirstValue(TAGS_KEY, "")); } } diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj index 73b83db47..40c0a9a19 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj @@ -40,7 +40,7 @@ (defn deployment-parameter-href [{{deployment-href :href} :deployment node-name :node-name node-index - :node-index name :name :as deployment-parameter}] + :node-index name :name :as deployment-parameter}] (let [deployment-uuid (deployment-href-to-uuid deployment-href) deployment-parameter-element (cond (and deployment-uuid node-name node-index) [deployment-uuid node-name @@ -94,7 +94,7 @@ (doseq [i (range 1 (inc multiplicity))] (uzk/create-all (zdu/deployment-parameter-node-instance-complete-state-path - deployment-href node-name i "state-complete") :persistent? true))))) + deployment-href node-name i "complete") :persistent? true))))) (zdu/unlock-deployment deployment-href)) (defn abort-deployment [deployment-href current-state] @@ -116,7 +116,7 @@ node-path (zdu/deployment-parameter-path deployment-parameter)] (uzk/create-all node-path :persistent? true) (uzk/set-data node-path value) - (when (and (= "state-complete" (:name deployment-parameter)) + (when (and (= "complete" (:name deployment-parameter)) (= "node-instance" (:type deployment-parameter))) (uzk/create-all (zdu/deployment-parameter-node-instance-complete-state-path deployment-parameter) :persistent? true)) @@ -140,12 +140,12 @@ (case (:type deployment-parameter) "deployment" (set-deployment-attribute deployment-href parameter-name value) "node-instance" (case parameter-name - "state-complete" (do - (zdu/check-deployment-lock-and-throw! deployment-href) - (zdu/check-same-state-and-throw! deployment-href value) - (zdu/complete-node-instance-state merged) - (when (zdu/all-nodes-completed-current-state? deployment-href) - (move-deployment-next-state deployment-href value))) + "complete" (do + (zdu/check-deployment-lock-and-throw! deployment-href) + (zdu/check-same-state-and-throw! deployment-href value) + (zdu/complete-node-instance-state merged) + (when (zdu/all-nodes-completed-current-state? deployment-href) + (move-deployment-next-state deployment-href value))) "abort" (do (zdu/check-deployment-lock-and-throw! deployment-href) (uzk/set-data (zdu/deployment-parameter-path deployment-parameter) value) @@ -153,44 +153,32 @@ (uzk/set-data (zdu/deployment-parameter-path deployment-parameter) value)))) (db/edit deployment-parameter request))) -(defn create-parameters [identity {nodes :nodes deployment-href :id state :state}] +(defn create-parameters [identity {nodes :nodes deployment-href :id state :state category :category}] (let [user (:current identity)] - (create-deployment-parameter - {:deployment {:href deployment-href} :name "state" :value state :type "deployment" - :acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:principal user - :type "USER" - :right "VIEW"}]}}) - (create-deployment-parameter - {:deployment {:href deployment-href} :name "abort" :value state :type "deployment" - :acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:principal user - :type "USER" - :right "VIEW"}]}}) - (doseq [n nodes] - (let [node-name (name (key n)) - multiplicity (read-string (get-in (val n) [:parameters :multiplicity :value] "1"))] + (doseq [[gp-key gp-body] {:category {:description "Module category" :value category} + :complete {:description "Global complete flag, set when run completed" :value ""} + :abort {:description "Run abort flag, set when aborting" :value ""} + :state {:description "Global execution state" :value state} + :url-service {:description "Optional service URL for the deployment" :value ""} + :tags {:description "Tags (comma separated) or annotations for this VM" :value ""} + :recovery-mode {:description "Run abort flag, set when aborting" :value "false"}}] + (create-deployment-parameter + {:deployment {:href deployment-href} :name (name gp-key) :value (:value gp-body) :type "deployment" + :acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal user + :type "USER" + :right "VIEW"}]}})) + (doseq [[node-key node-params] nodes] + (let [multiplicity (read-string (get-in node-params [:parameters :multiplicity :value] "1"))] (doseq [i (range 1 (inc multiplicity))] - (create-deployment-parameter - {:deployment {:href deployment-href} :node-name node-name :node-index i :type "node-instance" - :name "state-complete" :value "" :acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:principal user - :type "USER" - :right "MODIFY"}]}}) - (create-deployment-parameter - {:deployment {:href deployment-href} :node-name node-name :node-index i :type "node-instance" - :name "abort" :value "" :acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:principal user - :type "USER" - :right "MODIFY"}]}}) - (create-deployment-parameter - {:deployment {:href deployment-href} :node-name node-name :node-index i :type "node-instance" - :name "vmstate" :value "unknown" :acl {:owner {:principal "ADMIN" - :type "ROLE"} - :rules [{:principal user - :type "USER" - :right "MODIFY"}]}})))))) \ No newline at end of file + (doseq [[rp-key rp-body] (:runtime-parameters node-params)] + (create-deployment-parameter + {:deployment {:href deployment-href} :node-name (name node-key) :node-index i :type "node-instance" + :name (clojure.string/replace (name rp-key) #"\." "-") :value (or (:value rp-body) "") + :description (:description rp-body) :acl {:owner {:principal "ADMIN" + :type "ROLE"} + :rules [{:principal user + :type "USER" + :right "MODIFY"}]}}))))) + )) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj index 30c4fedb5..527e1b25b 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj @@ -191,7 +191,7 @@ (are [expected value] (= expected value) dsm/init-state (uzk/get-data (str zdu/separator uri "/state")) - "unknown" (uzk/get-data + "Unknown" (uzk/get-data (str zdu/separator uri "/" zdu/nodes-name "/apache/1/" "vmstate")))))) @@ -325,14 +325,14 @@ (-> session-admin (request (str p/service-context (du/deployment-parameter-href {:deployment {:href uri} :node-name "testclient" - :node-index 1 :name "state-complete"})) + :node-index 1 :name "complete"})) :request-method :put :body (json/write-str {:value dsm/provisioning-state})) (t/body->edn) (t/is-status 200)) (-> session-admin (request (str p/service-context (du/deployment-parameter-href {:deployment {:href uri} :node-name "apache" - :node-index 1 :name "state-complete"})) + :node-index 1 :name "complete"})) :request-method :put :body (json/write-str {:value dsm/provisioning-state})) (t/body->edn) (t/is-status 200)) diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj index 2ab7534b0..a83feb63f 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj @@ -59,11 +59,18 @@ (-> session-user-jane (request abs-uri :request-method :put :body (json/write-str {:value "newvalue"})) - (t/body->edn) + (t/body->edn (t/is-status 200)) (is (= "newvalue" (uzk/get-data znode-path)) "deployment parameter can be updated") + (-> session-user-jane + (request abs-uri :request-method :get) + (t/body->edn) + (t/is-status 200) + (t/is-key-value :value "newvalue") + ) + (-> session-user-albert (request abs-uri :request-method :put :body (json/write-str {:value "newvalue"})) @@ -73,13 +80,10 @@ (is (not (= "newvalue-albert" (uzk/get-data znode-path))) "deployment parameter can be updated") + ;type should not be updated (-> session-user-jane (request abs-uri :request-method :put :body (json/write-str {:type "deployment"})) (t/body->edn) (t/is-status 200) - (get-in [:response :body :type]) - (= "node-instance") - (is "type should not be updated"))) - - ) + (t/is-key-value :type "node-instance")))) From daaa39f7e5bbd2d83452a0a61af7e8c2b7142405 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Wed, 20 Sep 2017 18:49:14 +0200 Subject: [PATCH 45/46] terminate action on deployment to be continued --- .../connector/CliConnectorBase.java | 2 +- .../com/sixsq/slipstream/util/Terminator.java | 30 +-- .../com/sixsq/slipstream/persistence/Run.java | 14 +- .../sixsq/slipstream/run/RunNodeResource.java | 4 +- .../run/RuntimeParameterResource.java | 4 +- .../ssclj/resources/common/schema.clj | 2 +- .../slipstream/ssclj/resources/deployment.clj | 39 +++- .../resources/deployment/state_machine.clj | 55 +++-- .../ssclj/resources/deployment/utils.clj | 14 +- .../ssclj/resources/deployment_std.clj | 3 +- .../ssclj/resources/zk/deployment/utils.clj | 16 +- .../deployment/state_machine_test.clj | 7 +- .../resources/deployment_lifecycle_test.clj | 196 +++++++++++++----- .../deployment_parameter_lifecycle_test.clj | 4 +- 14 files changed, 269 insertions(+), 121 deletions(-) diff --git a/jar-connector/src/main/java/com/sixsq/slipstream/connector/CliConnectorBase.java b/jar-connector/src/main/java/com/sixsq/slipstream/connector/CliConnectorBase.java index b1d1eed1e..847a2cfa0 100644 --- a/jar-connector/src/main/java/com/sixsq/slipstream/connector/CliConnectorBase.java +++ b/jar-connector/src/main/java/com/sixsq/slipstream/connector/CliConnectorBase.java @@ -164,7 +164,7 @@ public void terminate(Run run, User user) throws SlipStreamException { validateCredentials(user); - List instanceIds = getCloudNodeInstanceIds(run); + List instanceIds = getCloudNodeInstanceIds(run); //TODO KB extract ids for each cloud service for terminate if(instanceIds.isEmpty()){ throw new SlipStreamClientException("There is no instances to terminate"); } diff --git a/jar-connector/src/main/java/com/sixsq/slipstream/util/Terminator.java b/jar-connector/src/main/java/com/sixsq/slipstream/util/Terminator.java index 8ebc259d6..17bb6cc4d 100644 --- a/jar-connector/src/main/java/com/sixsq/slipstream/util/Terminator.java +++ b/jar-connector/src/main/java/com/sixsq/slipstream/util/Terminator.java @@ -25,7 +25,7 @@ import com.sixsq.slipstream.persistence.Run; import com.sixsq.slipstream.persistence.User; import com.sixsq.slipstream.persistence.UserParameter; -import com.sixsq.slipstream.statemachine.StateMachine; +//import com.sixsq.slipstream.statemachine.StateMachine; import com.sixsq.slipstream.statemachine.States; public class Terminator { @@ -44,7 +44,7 @@ public static int purge() throws ConfigurationException, ValidationException { u = User.loadByName(u.getName()); int timeout = u.getTimeout(); - List old = Run.listOldTransient(u, timeout); + List old = Run.listOldTransient(u, timeout); //TODO kb for (Run r : old) { EntityManager em = PersistenceUtil.createEntityManager(); try { @@ -68,7 +68,7 @@ public static int purge() throws ConfigurationException, ValidationException { public static void purgeRun(Run run) throws SlipStreamException { Run.abort("The run has timed out", run.getUuid()); - boolean isGarbageCollected = Run.isGarbageCollected(run); + boolean isGarbageCollected = Run.isGarbageCollected(run); //TODO kb Run.setGarbageCollected(run); run = run.store(); @@ -94,18 +94,20 @@ public static void terminate(String runResourceUri) throws SlipStreamException { Run run = Run.load(runResourceUri, em); User user = User.loadByName(run.getUser()); - StateMachine sc = StateMachine.createStateMachine(run); + //StateMachine sc = StateMachine.createStateMachine(run); - if (sc.canCancel()) { - sc.tryAdvanceToCancelled(); - terminateInstances(run, user); - } else { - if (sc.getState() == States.Ready) { - sc.tryAdvanceToFinalizing(); - } - terminateInstances(run, user); - sc.tryAdvanceState(true); - } + //if (sc.canCancel()) { + // sc.tryAdvanceToCancelled(); + // terminateInstances(run, user); + //} else { + // if (sc.getState() == States.Ready) { + // sc.tryAdvanceToFinalizing(); + // } + // terminateInstances(run, user); + // sc.tryAdvanceState(true); + //} + + terminateInstances(run, user); em.close(); } diff --git a/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/Run.java b/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/Run.java index d9b2f9d3c..717659042 100644 --- a/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/Run.java +++ b/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/Run.java @@ -128,7 +128,7 @@ public class Run extends Parameterized { private static final Set STOP_ACCOUNTING_STATES = new HashSet(Arrays.asList(STOP_VALUES)); - public static Run abortOrReset(String abortMessage, String nodename, + public static Run abortOrReset(String abortMessage, String nodename, //TODO kb String uuid) { EntityManager em = PersistenceUtil.createEntityManager(); EntityTransaction transaction = em.getTransaction(); @@ -142,7 +142,7 @@ public static Run abortOrReset(String abortMessage, String nodename, return run; } - public static Run abortOrReset(String abortMessage, String nodename, + public static Run abortOrReset(String abortMessage, String nodename, //TODO kb EntityManager em, String uuid) { Run run = Run.loadFromUuid(uuid, em); @@ -177,7 +177,7 @@ public static Run abortOrReset(String abortMessage, String nodename, return run; } - private static void setGlobalAbortState(String abortMessage, + private static void setGlobalAbortState(String abortMessage, //TODO kb RuntimeParameter globalAbort) { globalAbort.setValue(abortMessage); globalAbort.store(); @@ -192,7 +192,7 @@ public static Run abort(String abortMessage, String uuid) { if (!globalAbort.isSet()) { setGlobalAbortState(abortMessage, globalAbort); } - if (run.state == States.Provisioning) { + if (run.state == States.Provisioning) { //TODO kb setRecoveryMode(run); } em.close(); @@ -210,7 +210,7 @@ private static String getNodeAbortKey(String nodeName) { + RuntimeParameter.ABORT_KEY; } - private static RuntimeParameter getRecoveryModeParameter(Run run) { + private static RuntimeParameter getRecoveryModeParameter(Run run) { //TODO kb return run.getRuntimeParameters().get( RuntimeParameter.GLOBAL_RECOVERY_MODE_KEY); } @@ -331,7 +331,7 @@ private static List convertRunsToRunViews(List runs, Map vmCountPerRun) { + private static RunView convertRunToRunView(Run run, Map vmCountPerRun) { //TODO kb if (run == null) { return null; @@ -480,7 +480,7 @@ public static List listOldTransient(User user) throws ConfigurationExceptio } @SuppressWarnings("unchecked") - public static List listOldTransient(User user, int timeout) throws ConfigurationException, + public static List listOldTransient(User user, int timeout) throws ConfigurationException, //TODO kb ValidationException { if (timeout <= 0) { timeout = DEFAULT_TIMEOUT; diff --git a/jar-service/src/main/java/com/sixsq/slipstream/run/RunNodeResource.java b/jar-service/src/main/java/com/sixsq/slipstream/run/RunNodeResource.java index 0ccef9b8c..b04e5ae77 100644 --- a/jar-service/src/main/java/com/sixsq/slipstream/run/RunNodeResource.java +++ b/jar-service/src/main/java/com/sixsq/slipstream/run/RunNodeResource.java @@ -144,7 +144,7 @@ private Representation addNodeInstancesInTransaction(Representation entity) run.postEventScaleUp(nodename, instanceNames, noOfInst); incrementNodeMultiplicityOnRun(noOfInst, run); - StateMachine.createStateMachine(run).tryAdvanceToProvisionning(); + StateMachine.createStateMachine(run).tryAdvanceToProvisionning(); //TODO kb if (Configuration.isQuotaEnabled()) { User user = User.loadByName(run.getUser()); @@ -223,7 +223,7 @@ private void deleteNodeInstancesInTransaction(Representation entity) throws Exce } if (!deleteOnly) { - StateMachine.createStateMachine(run).tryAdvanceToProvisionning(); + StateMachine.createStateMachine(run).tryAdvanceToProvisionning(); //TODO kb } transaction.commit(); diff --git a/jar-service/src/main/java/com/sixsq/slipstream/run/RuntimeParameterResource.java b/jar-service/src/main/java/com/sixsq/slipstream/run/RuntimeParameterResource.java index 443e08a2f..7ba4b2c69 100644 --- a/jar-service/src/main/java/com/sixsq/slipstream/run/RuntimeParameterResource.java +++ b/jar-service/src/main/java/com/sixsq/slipstream/run/RuntimeParameterResource.java @@ -137,7 +137,7 @@ public void resetRuntimeParameter() throws ResourceException { } @Get - public String represent() throws ResourceException, NotFoundException, + public String represent() throws ResourceException, NotFoundException, //TODO kb should no more be used ValidationException { getMetricsTimer().start(); try { @@ -166,7 +166,7 @@ private String truncateMiddle(int maxLength, String text, String truncateMessage } @Put - public void update(Representation entity) throws ResourceException, + public void update(Representation entity) throws ResourceException, //TODO kb should no more be used NotFoundException, ValidationException { EntityManager em = PersistenceUtil.createEntityManager(); diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/common/schema.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/common/schema.clj index 7bf8da80a..de800146b 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/common/schema.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/common/schema.clj @@ -16,7 +16,7 @@ ;; additional resource actions have a URI prefix (def ^:const action-prefix (str cimi-schema-uri "action/")) (def ^:const prefixed-actions - #{:start :stop :restart :pause :suspend + #{:start :stop :restart :pause :suspend :terminate :export :import :capture :snapshot :forceSync :swapBackup :restore :enable :disable}) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj index afc43c93e..91b9a24a3 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment.clj @@ -103,7 +103,7 @@ (assoc :resourceURI resource-uri) u/update-timestamps (crud/add-acl request) - (assoc :state dsm/init-state)) + (assoc :state dsm/initializing-state)) response (db/add resource-name (crud/validate new-deployment) {})] response)) @@ -147,18 +147,22 @@ (defmethod crud/set-operations resource-uri [{:keys [id resourceURI] :as resource} request] - (let [href (str id "/start")] + (let [href-start (str id "/start") + href-terminate (str id "/terminate") + start-op {:rel (:start c/action-uri) :href href-start} + terminate-op {:rel (:terminate c/action-uri) :href href-terminate}] (try (a/can-modify? resource request) (let [ops (if (.endsWith resourceURI "Collection") [{:rel (:add c/action-uri) :href id}] [{:rel (:delete c/action-uri) :href id} - {:rel (:start c/action-uri) :href href}])] + start-op + terminate-op])] (assoc resource :operations ops)) (catch Exception e (if (.endsWith resourceURI "Collection") (dissoc resource :operations) - (assoc resource :operations [{:rel (:start c/action-uri) :href href}])))))) + (assoc resource :operations [start-op terminate-op])))))) ;; ;; actions @@ -168,6 +172,10 @@ (let [now (u/time-now)] (assoc deployment :start-time now))) +(defn add-end-time [deployment] + (let [now (u/time-now)] + (assoc deployment :end-time now))) + (defmethod crud/do-action [resource-url "start"] [{{uuid :uuid} :params identity :identity username :user-name :as request}] (try @@ -179,7 +187,28 @@ (u/update-timestamps) (crud/validate))] (du/create-parameters identity current) - (http/post (str du/slipstream-java-endpoint "/run/" uuid) {:headers {"slipstream-authn-info" username}}) + (http/post (str du/slipstream-java-endpoint "/run/" uuid) {:headers {"slipstream-authn-info" username} + "Accept" "application/json"}) + (db/edit deployment request)) + (catch ExceptionInfo ei + (ex-data ei)))) + +(defmethod crud/do-action [resource-url "terminate"] + [{{uuid :uuid} :params identity :identity username :user-name :as request}] + (try + (let [{current-state :state :as current} (-> (str (u/de-camelcase resource-name) "/" uuid) + (db/retrieve request) + (a/can-modify? request)) + {id :id new-state :state :as deployment} (-> current + (add-end-time) + (update :state (constantly dsm/cancelled-state)) + (u/update-timestamps) + (crud/validate))] + (http/delete (str du/slipstream-java-endpoint "/run/" uuid) {:headers {"slipstream-authn-info" username + "Accept" "application/json"}}) + (if (dsm/can-terminate? current-state) + (du/move-deployment-next-state id new-state) + (du/set-global-deployment-parameter id "state" dsm/cancelled-state)) ;TODO delete znode of deployment, to be done also for done state, fetch runtime-param of old run should not fetch from zookeeper (db/edit deployment request)) (catch ExceptionInfo ei (ex-data ei)))) \ No newline at end of file diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/state_machine.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/state_machine.clj index 076b569e7..cf7b8acbb 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/state_machine.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/state_machine.clj @@ -18,26 +18,32 @@ The topology of the run is persisted as an edn structure inside the ./topology znode. This can be changed as nodes come and go, for scalable deployments.") -(def init-state "Initializing") -(def provisioning-state "Provisioning") -(def executing-state "Executing") +(def initializing-state "Initializing") +(def provisioning-state "Provisioning") +(def executing-state "Executing") (def sending-report-state "SendingReports") -(def ready-state "Ready") -(def finalyzing-state "Finalizing") -(def done-state "Done") - -(def cancelled-state "Cancelled") -(def aborted-state "Aborted") -(def unknown-state "Unknown") - -(def valid-transitions - {init-state [provisioning-state] - provisioning-state [executing-state] - executing-state [sending-report-state] - sending-report-state [ready-state] - ready-state [provisioning-state] - finalyzing-state [done-state] - done-state []}) +(def ready-state "Ready") +(def finalyzing-state "Finalizing") +(def done-state "Done") + +(def cancelled-state "Cancelled") +(def aborted-state "Aborted") +(def unknown-state "Unknown") + +(def state-machine + {initializing-state {:next-state provisioning-state + :valid-transition #{provisioning-state cancelled-state}} + provisioning-state {:next-state executing-state + :valid-transition #{executing-state cancelled-state}} + executing-state {:next-state sending-report-state + :valid-transition #{sending-report-state cancelled-state}} + sending-report-state {:next-state ready-state + :valid-transition #{ready-state cancelled-state}} + ready-state {:next-state provisioning-state + :valid-transition #{provisioning-state}} + finalyzing-state {:next-state done-state + :valid-transition #{done-state}} + done-state {:valid-transition #{done-state}}}) (defn is-completed? [current-state] (contains? #{cancelled-state aborted-state done-state unknown-state} current-state)) @@ -46,6 +52,11 @@ (contains? #{cancelled-state aborted-state done-state ready-state} current-state)) (defn get-next-state [current-state] - (->> current-state - (get valid-transitions) - first)) + (-> (get state-machine current-state) + :next-state)) + +(defn is-valid-transition? [current-state next-state] + (-> (get state-machine current-state) + :valid-transition + (contains? next-state))) + diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj index 40c0a9a19..848d51e2e 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment/utils.clj @@ -93,10 +93,20 @@ multiplicity (read-string (get-in (val n) [:parameters :multiplicity :value] "1"))] (doseq [i (range 1 (inc multiplicity))] (uzk/create-all - (zdu/deployment-parameter-node-instance-complete-state-path + (zdu/deployment-parameter-node-instance-state-path deployment-href node-name i "complete") :persistent? true))))) (zdu/unlock-deployment deployment-href)) +(defn cancel-deployment [deployment-href] + (zdu/check-deployment-lock-and-throw! deployment-href) + (zdu/lock-deployment-path deployment-href) + (set-global-deployment-parameter deployment-href "state" dsm/cancelled-state) + () + (let [deployment (set-deployment-attribute deployment-href "state" dsm/cancelled-state)] + (zdu/unlock-deployment deployment-href) + deployment + )) + (defn abort-deployment [deployment-href current-state] (zdu/check-deployment-lock-and-throw! deployment-href) (zdu/lock-deployment-path deployment-href) @@ -119,7 +129,7 @@ (when (and (= "complete" (:name deployment-parameter)) (= "node-instance" (:type deployment-parameter))) (uzk/create-all - (zdu/deployment-parameter-node-instance-complete-state-path deployment-parameter) :persistent? true)) + (zdu/deployment-parameter-node-instance-state-path deployment-parameter) :persistent? true)) (-> (db/add deployment-parameter-resource-name deployment-parameter {}) :body))) diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_std.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_std.clj index 29ffc3458..baed77b92 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_std.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/deployment_std.clj @@ -25,7 +25,8 @@ (defmethod d/tpl->deployment dtpl/method [{module :module :as resource} {username :user-name :as request}] (let [java-deployment-location (-> (http/post (str du/slipstream-java-endpoint "/run") - {:headers {"slipstream-authn-info" username} + {:headers {"slipstream-authn-info" username + "Accept" "application/json"} :form-params {:refqname module :bypass-ssh-check true}}) (get-in [:headers "Location"])) java-deployment-json (-> (http/get java-deployment-location {:headers {"slipstream-authn-info" username diff --git a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj index 36d1a473b..d7fdab0a4 100644 --- a/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj +++ b/ssclj/jar/src/com/sixsq/slipstream/ssclj/resources/zk/deployment/utils.clj @@ -25,14 +25,14 @@ -(defn deployment-parameter-node-instance-complete-state-path +(defn deployment-parameter-node-instance-state-path ([deployment-href node-name node-index parameter-name] - (let [node-instance-complete-state-znode-id (string/join "_" [node-name node-index name])] + (let [node-instance-state-znode-id (string/join "_" [node-name node-index name])] (str separator - (string/join separator [deployment-href "state" node-instance-complete-state-znode-id])))) + (string/join separator [deployment-href "state" node-instance-state-znode-id])))) ([{{deployment-href :href} :deployment node-name :node-name node-index :node-index name :name :as deployment-parameter}] - (deployment-parameter-node-instance-complete-state-path deployment-href node-name node-index name))) + (deployment-parameter-node-instance-state-path deployment-href node-name node-index name))) (defn lock-deployment "Create a lock for the deployment. This should be used each time multi-operations on zookeeper are needed to complete @@ -68,15 +68,15 @@ (uzk/get-data (deployment-state-path deployment-href))) (defn check-same-state-and-throw! - [deployment-href node-complete-state] + [deployment-href node-state] (let [current-deployment-state (get-deployment-state deployment-href)] - (when-not (= node-complete-state current-deployment-state) + (when-not (= node-state current-deployment-state) (throw (Exception. - (str "State machine (complete-state = " node-complete-state + (str "State machine (state = " node-state ") in different state from deployment state = " current-deployment-state "!")))))) (defn complete-node-instance-state [{state :value :as deployment-parameter}] - (uzk/delete (deployment-parameter-node-instance-complete-state-path deployment-parameter)) + (uzk/delete (deployment-parameter-node-instance-state-path deployment-parameter)) (uzk/set-data (deployment-parameter-path deployment-parameter) state)) (defn all-nodes-completed-current-state? [deployment-href] diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment/state_machine_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment/state_machine_test.clj index 4ef47e2ee..a407fb9fe 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment/state_machine_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment/state_machine_test.clj @@ -14,4 +14,9 @@ (is (can-terminate? ready-state)) (is (can-terminate? aborted-state)) (is (can-terminate? cancelled-state)) - (is (not (can-terminate? executing-state)))) \ No newline at end of file + (is (not (can-terminate? executing-state)))) + +(deftest is-valid-transition + (is (is-valid-transition? initializing-state cancelled-state)) + (is (is-valid-transition? executing-state cancelled-state)) + (is (not (is-valid-transition? done-state cancelled-state)))) \ No newline at end of file diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj index 527e1b25b..0512d0555 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_lifecycle_test.clj @@ -7,7 +7,7 @@ [com.sixsq.slipstream.ssclj.resources.deployment :refer :all] [com.sixsq.slipstream.ssclj.resources.deployment-template :as dt] [com.sixsq.slipstream.ssclj.resources.deployment-parameter :as dp] - [com.sixsq.slipstream.ssclj.resources.lifecycle-test-utils :as t] + [com.sixsq.slipstream.ssclj.resources.lifecycle-test-utils :as ltu] [com.sixsq.slipstream.ssclj.middleware.authn-info-header :refer [authn-info-header]] [com.sixsq.slipstream.ssclj.app.routes :as routes] [com.sixsq.slipstream.ssclj.app.params :as p] @@ -20,9 +20,10 @@ [com.sixsq.slipstream.ssclj.resources.deployment-std :as dstd] [com.sixsq.slipstream.ssclj.resources.lifecycle-test-utils :as ltu] [com.sixsq.slipstream.ssclj.resources.common.dynamic-load :as dyn] + [com.sixsq.slipstream.ssclj.resources.common.schema :as c] [clj-http.fake :refer [with-fake-routes]])) -(use-fixtures :once t/setup-embedded-zk) +(use-fixtures :once ltu/setup-embedded-zk) (defn fake-http-java-server [f] (with-fake-routes @@ -33,17 +34,18 @@ {"Location" "http://localhost:8182/run/97089b96-5d99-4ccd-9bfe-99ba3ca21ae2"}}) "http://localhost:8182/run/97089b96-5d99-4ccd-9bfe-99ba3ca21ae2" - {:get (fn [request] {:status 200 - :body (slurp "test-resources/deployment-service-testing.json")}) - :post (fn [request] {:status 200})}} + {:get (fn [request] {:status 200 + :body (slurp "test-resources/deployment-service-testing.json")}) + :post (fn [request] {:status 200}) + :delete (fn [request] {:status 200})}} (f))) -(use-fixtures :each (join-fixtures [t/with-test-es-client-fixture t/cleanup-all-zk-nodes fake-http-java-server])) +(use-fixtures :each (join-fixtures [ltu/with-test-es-client-fixture ltu/cleanup-all-zk-nodes fake-http-java-server])) (def base-uri (str p/service-context resource-url)) (defn ring-app [] - (t/make-ring-app (t/concat-routes routes/final-routes))) + (ltu/make-ring-app (ltu/concat-routes routes/final-routes))) ;; initialize must to called to pull in SessionTemplate test examples (dyn/initialize) @@ -92,13 +94,15 @@ (ltu/location)) abs-uri (str p/service-context (u/de-camelcase uri))] - ;; admin should be able to see, edit, and delete deployment + ;; user should be able to see and start, terminate and delete deployment (-> session-user (request abs-uri) (ltu/body->edn) (ltu/is-status 200) (ltu/is-operation-present "delete") - (ltu/is-operation-absent "edit")) + (ltu/is-operation-absent "edit") + (ltu/is-operation-present "start") + (ltu/is-operation-present "terminate")) ;; admin can delete resource (-> session-admin @@ -118,20 +122,15 @@ (ltu/location)) abs-uri (str p/service-context (u/de-camelcase uri))] - ;; admin should be able to see, and delete deployment + ;; admin should be able to see and start, terminate and delete deployment (-> session-admin (request abs-uri) (ltu/body->edn) (ltu/is-status 200) (ltu/is-operation-present "delete") - (ltu/is-operation-absent "edit")) - - (-> session-user - (request abs-uri) - (ltu/body->edn) - (ltu/is-status 200) - (ltu/is-operation-present "delete") - (ltu/is-operation-absent "edit")) + (ltu/is-operation-absent "edit") + (ltu/is-operation-present "start") + (ltu/is-operation-present "terminate")) ;; user can delete resource (-> session-user @@ -177,20 +176,20 @@ (request abs-uri) (ltu/body->edn)) start-uri (str p/service-context - (t/get-op deployment "http://schemas.dmtf.org/cimi/2/action/start")) + (ltu/get-op deployment "http://schemas.dmtf.org/cimi/2/action/start")) started-deployment (-> session-user - (request start-uri) - (t/body->edn) - (t/is-status 200))] + (request start-uri :request-method :post) + (ltu/body->edn) + (ltu/is-status 200))] (is (not (get-in deployment [:body :start-time]))) (is (get-in started-deployment [:response :body :start-time])) - (is (= dsm/init-state (get-in started-deployment [:response :body :state]))) + (is (= dsm/initializing-state (get-in started-deployment [:response :body :state]))) (are [expected value] (= expected value) - dsm/init-state (uzk/get-data (str zdu/separator uri "/state")) + dsm/initializing-state (uzk/get-data (str zdu/separator uri "/state")) "Unknown" (uzk/get-data (str zdu/separator uri "/" zdu/nodes-name "/apache/1/" "vmstate")))))) @@ -232,29 +231,29 @@ (request abs-uri) (ltu/body->edn)) start-uri (str p/service-context - (t/get-op deployment "http://schemas.dmtf.org/cimi/2/action/start")) + (ltu/get-op deployment "http://schemas.dmtf.org/cimi/2/action/start")) started-deployment (-> session-user - (request start-uri) - (t/body->edn) - (t/is-status 200)) + (request start-uri :request-method :post) + (ltu/body->edn) + (ltu/is-status 200)) abs-uri-deployment-parameter-state (str p/service-context dp/resource-url "/" (du/deployment-href-to-uuid uri) "_state") update-deployment-parameter-state (-> session-user (request abs-uri-deployment-parameter-state :request-method :put :body (json/write-str {:value dsm/provisioning-state})) - (t/body->edn) - (t/is-status 403)) + (ltu/body->edn) + (ltu/is-status 403)) update-deployment-parameter-state (-> session-admin (request abs-uri-deployment-parameter-state :request-method :put :body (json/write-str {:value dsm/provisioning-state})) - (t/body->edn) - (t/is-status 200)) + (ltu/body->edn) + (ltu/is-status 200)) provisioning-deployment (-> session-user - (request start-uri) - (t/body->edn) - (t/is-status 200))] + (request abs-uri) + (ltu/body->edn) + (ltu/is-status 200))] (is (= dsm/provisioning-state (get-in provisioning-deployment [:response :body :state]))) @@ -298,52 +297,52 @@ (request abs-uri) (ltu/body->edn)) start-uri (str p/service-context - (t/get-op deployment "http://schemas.dmtf.org/cimi/2/action/start")) + (ltu/get-op deployment "http://schemas.dmtf.org/cimi/2/action/start")) started-deployment (-> session-user - (request start-uri) - (t/body->edn) - (t/is-status 200)) + (request start-uri :request-method :post) + (ltu/body->edn) + (ltu/is-status 200)) abs-uri-deployment-parameter-state (str p/service-context dp/resource-url "/" (du/deployment-href-to-uuid uri) "_state") update-deployment-parameter-state (-> session-user (request abs-uri-deployment-parameter-state :request-method :put :body (json/write-str {:value dsm/provisioning-state})) - (t/body->edn) - (t/is-status 403)) + (ltu/body->edn) + (ltu/is-status 403)) update-deployment-parameter-state (-> session-admin (request abs-uri-deployment-parameter-state :request-method :put :body (json/write-str {:value dsm/provisioning-state})) - (t/body->edn) - (t/is-status 200)) + (ltu/body->edn) + (ltu/is-status 200)) provisioning-deployment (-> session-user - (request start-uri) - (t/body->edn) - (t/is-status 200))] + (request abs-uri) + (ltu/body->edn) + (ltu/is-status 200))] (-> session-admin (request (str p/service-context (du/deployment-parameter-href {:deployment {:href uri} :node-name "testclient" :node-index 1 :name "complete"})) :request-method :put :body (json/write-str {:value dsm/provisioning-state})) - (t/body->edn) - (t/is-status 200)) + (ltu/body->edn) + (ltu/is-status 200)) (-> session-admin (request (str p/service-context (du/deployment-parameter-href {:deployment {:href uri} :node-name "apache" :node-index 1 :name "complete"})) :request-method :put :body (json/write-str {:value dsm/provisioning-state})) - (t/body->edn) - (t/is-status 200)) + (ltu/body->edn) + (ltu/is-status 200)) (-> session-admin (request (str p/service-context (du/deployment-parameter-href {:deployment {:href uri} :node-name "apache" :node-index 1 :name "abort"})) :request-method :put :body (json/write-str {:value "Error in node 1 abort the run"})) - (t/body->edn) - (t/is-status 200)) + (ltu/body->edn) + (ltu/is-status 200)) (is (= 1 (count (uzk/children (zdu/deployment-state-path uri))))) @@ -352,6 +351,97 @@ (is (= dsm/aborted-state (-> session-user (request (str p/service-context uri)) - (t/body->edn) + (ltu/body->edn) (get-in [:response :body :state])))) ))) + +(deftest update-deployment-move-states-cancel + + (let [href (str dt/resource-url "/" std/method) + template-url (str p/service-context dt/resource-url "/" std/method) + session-admin (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "super ADMIN")) + session-user (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "test USER ANON")) + session-anon (-> (session (ring-app)) + (content-type "application/json") + (header authn-info-header "unknown ANON")) + template (-> session-admin + (request template-url) + (ltu/body->edn) + (ltu/is-status 200) + (get-in [:response :body])) + + href-create {:deploymentTemplate {:href href + :module "module/examples/tutorials/service-testing/system/1940"}}] + + (let [create-req href-create + resp (-> session-user + (request base-uri + :request-method :post + :body (json/write-str create-req)) + (ltu/body->edn) + (ltu/is-status 201)) + id (get-in resp [:response :body :resource-id]) + uri (-> resp + (ltu/location)) + abs-uri (str p/service-context (u/de-camelcase uri)) + deployment (-> session-user + (request abs-uri) + (ltu/body->edn)) + start-uri (str p/service-context + (ltu/get-op deployment "http://schemas.dmtf.org/cimi/2/action/start")) + terminate-uri (str p/service-context + (ltu/get-op deployment "http://schemas.dmtf.org/cimi/2/action/terminate")) + started-deployment (-> session-user + (request start-uri :request-method :post) + (ltu/body->edn) + (ltu/is-status 200)) + abs-uri-deployment-parameter-state (str p/service-context dp/resource-url + "/" (du/deployment-href-to-uuid uri) "_state") + + update-deployment-parameter-state + (-> session-admin + (request abs-uri-deployment-parameter-state :request-method :put + :body (json/write-str {:value dsm/provisioning-state})) + (ltu/body->edn) + (ltu/is-status 200)) + provisioning-deployment (-> session-user + (request abs-uri) + (ltu/body->edn) + (ltu/is-status 200))] + + (-> session-admin + (request (str p/service-context (du/deployment-parameter-href + {:deployment {:href uri} :node-name "testclient" + :node-index 1 :name "complete"})) + :request-method :put :body (json/write-str {:value dsm/provisioning-state})) + (ltu/body->edn) + (ltu/is-status 200)) + (-> session-admin + (request (str p/service-context (du/deployment-parameter-href + {:deployment {:href uri} :node-name "apache" + :node-index 1 :name "complete"})) + :request-method :put :body (json/write-str {:value dsm/provisioning-state})) + (ltu/body->edn) + (ltu/is-status 200)) + + (-> session-user + (request terminate-uri :request-method :post) + (ltu/body->edn) + (ltu/is-status 200)) + + (is (= dsm/cancelled-state (uzk/get-data (str zdu/separator uri "/state")))) + + + (is (= dsm/cancelled-state (-> session-user + (request (str p/service-context uri)) + (ltu/body->edn) + (get-in [:response :body :state])))) + + ))) + + + diff --git a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj index a83feb63f..0b88b0006 100644 --- a/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj +++ b/ssclj/jar/test/com/sixsq/slipstream/ssclj/resources/deployment_parameter_lifecycle_test.clj @@ -59,7 +59,7 @@ (-> session-user-jane (request abs-uri :request-method :put :body (json/write-str {:value "newvalue"})) - (t/body->edn + (t/body->edn) (t/is-status 200)) (is (= "newvalue" (uzk/get-data znode-path)) "deployment parameter can be updated") @@ -73,7 +73,7 @@ (-> session-user-albert (request abs-uri :request-method :put - :body (json/write-str {:value "newvalue"})) + :body (json/write-str {:value "newvalue-albert"})) (t/body->edn) (t/is-status 403)) From 95a3763716b4c47c42e0d2d1622947ae9a52304d Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Thu, 21 Sep 2017 17:38:35 +0200 Subject: [PATCH 46/46] minor --- .../main/java/com/sixsq/slipstream/util/Terminator.java | 4 ++-- .../main/java/com/sixsq/slipstream/persistence/Run.java | 6 +++--- .../sixsq/slipstream/persistence/RuntimeParameter.java | 3 +-- .../java/com/sixsq/slipstream/run/RunNodeResource.java | 8 ++++---- .../sixsq/slipstream/run/RuntimeParameterResource.java | 8 ++++---- 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/jar-connector/src/main/java/com/sixsq/slipstream/util/Terminator.java b/jar-connector/src/main/java/com/sixsq/slipstream/util/Terminator.java index 17bb6cc4d..dbc0a7c84 100644 --- a/jar-connector/src/main/java/com/sixsq/slipstream/util/Terminator.java +++ b/jar-connector/src/main/java/com/sixsq/slipstream/util/Terminator.java @@ -44,7 +44,7 @@ public static int purge() throws ConfigurationException, ValidationException { u = User.loadByName(u.getName()); int timeout = u.getTimeout(); - List old = Run.listOldTransient(u, timeout); //TODO kb + List old = Run.listOldTransient(u, timeout); //TODO kb search for timeout on ssclj deployment for (Run r : old) { EntityManager em = PersistenceUtil.createEntityManager(); try { @@ -68,7 +68,7 @@ public static int purge() throws ConfigurationException, ValidationException { public static void purgeRun(Run run) throws SlipStreamException { Run.abort("The run has timed out", run.getUuid()); - boolean isGarbageCollected = Run.isGarbageCollected(run); //TODO kb + boolean isGarbageCollected = Run.isGarbageCollected(run); //TODO kb Garbage collected run Run.setGarbageCollected(run); run = run.store(); diff --git a/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/Run.java b/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/Run.java index 717659042..3b2e90519 100644 --- a/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/Run.java +++ b/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/Run.java @@ -192,7 +192,7 @@ public static Run abort(String abortMessage, String uuid) { if (!globalAbort.isSet()) { setGlobalAbortState(abortMessage, globalAbort); } - if (run.state == States.Provisioning) { //TODO kb + if (run.state == States.Provisioning) { //TODO kb recovery mode setRecoveryMode(run); } em.close(); @@ -331,7 +331,7 @@ private static List convertRunsToRunViews(List runs, Map vmCountPerRun) { //TODO kb + private static RunView convertRunToRunView(Run run, Map vmCountPerRun) { //TODO kb UI if (run == null) { return null; @@ -480,7 +480,7 @@ public static List listOldTransient(User user) throws ConfigurationExceptio } @SuppressWarnings("unchecked") - public static List listOldTransient(User user, int timeout) throws ConfigurationException, //TODO kb + public static List listOldTransient(User user, int timeout) throws ConfigurationException, //TODO kb search for old transient deployment on ssclj ValidationException { if (timeout <= 0) { timeout = DEFAULT_TIMEOUT; diff --git a/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/RuntimeParameter.java b/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/RuntimeParameter.java index 128ee1dad..3169e045d 100644 --- a/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/RuntimeParameter.java +++ b/jar-persistence/src/main/java/com/sixsq/slipstream/persistence/RuntimeParameter.java @@ -436,8 +436,7 @@ public void setValue(String value) { this.value = value; Map mapValue = new HashMap(); - mapValue.put("value", value); - SscljProxy.put(getSScljDeploymentParameterUri(this), + mapValue.put("value", value);SscljProxy.put(getSScljDeploymentParameterUri(this), "super ADMIN", mapValue, true); processValue(); } diff --git a/jar-service/src/main/java/com/sixsq/slipstream/run/RunNodeResource.java b/jar-service/src/main/java/com/sixsq/slipstream/run/RunNodeResource.java index b04e5ae77..2e43a2f90 100644 --- a/jar-service/src/main/java/com/sixsq/slipstream/run/RunNodeResource.java +++ b/jar-service/src/main/java/com/sixsq/slipstream/run/RunNodeResource.java @@ -122,7 +122,7 @@ public Representation addNodeInstances(Representation entity) return result; } - private Representation addNodeInstancesInTransaction(Representation entity) + private Representation addNodeInstancesInTransaction(Representation entity) //TODO kb scaling throws Exception { EntityManager em = PersistenceUtil.createEntityManager(); @@ -144,7 +144,7 @@ private Representation addNodeInstancesInTransaction(Representation entity) run.postEventScaleUp(nodename, instanceNames, noOfInst); incrementNodeMultiplicityOnRun(noOfInst, run); - StateMachine.createStateMachine(run).tryAdvanceToProvisionning(); //TODO kb + StateMachine.createStateMachine(run).tryAdvanceToProvisionning(); if (Configuration.isQuotaEnabled()) { User user = User.loadByName(run.getUser()); @@ -180,7 +180,7 @@ public void deleteNodeInstances(Representation entity) throws Exception { } } - private void deleteNodeInstancesInTransaction(Representation entity) throws Exception { + private void deleteNodeInstancesInTransaction(Representation entity) throws Exception { //TODO kb scaling EntityManager em = PersistenceUtil.createEntityManager(); EntityTransaction transaction = em.getTransaction(); @@ -223,7 +223,7 @@ private void deleteNodeInstancesInTransaction(Representation entity) throws Exce } if (!deleteOnly) { - StateMachine.createStateMachine(run).tryAdvanceToProvisionning(); //TODO kb + StateMachine.createStateMachine(run).tryAdvanceToProvisionning(); } transaction.commit(); diff --git a/jar-service/src/main/java/com/sixsq/slipstream/run/RuntimeParameterResource.java b/jar-service/src/main/java/com/sixsq/slipstream/run/RuntimeParameterResource.java index 7ba4b2c69..b3989514a 100644 --- a/jar-service/src/main/java/com/sixsq/slipstream/run/RuntimeParameterResource.java +++ b/jar-service/src/main/java/com/sixsq/slipstream/run/RuntimeParameterResource.java @@ -114,7 +114,7 @@ private void abortOrReset(String abortMessage, EntityManager em) { } @Delete - public void resetRuntimeParameter() throws ResourceException { + public void resetRuntimeParameter() throws ResourceException { //TODO kb should no more be used with new client runtimeParameter.setValue(""); runtimeParameter.setIsSet(false); @@ -137,7 +137,7 @@ public void resetRuntimeParameter() throws ResourceException { } @Get - public String represent() throws ResourceException, NotFoundException, //TODO kb should no more be used + public String represent() throws ResourceException, NotFoundException, //TODO kb should no more be used with new client ValidationException { getMetricsTimer().start(); try { @@ -166,7 +166,7 @@ private String truncateMiddle(int maxLength, String text, String truncateMessage } @Put - public void update(Representation entity) throws ResourceException, //TODO kb should no more be used + public void update(Representation entity) throws ResourceException, //TODO kb should no more be used with new client NotFoundException, ValidationException { EntityManager em = PersistenceUtil.createEntityManager(); @@ -281,7 +281,7 @@ private States attemptChangeGlobalStateToProvisioning() { @Post - public void completeCurrentNodeStateOrChangeGlobalState(Representation entity) { + public void completeCurrentNodeStateOrChangeGlobalState(Representation entity) { //TODO kb should be no more used, new client will talk to ssclj deployment String nodeName = runtimeParameter.getNodeName(); States newState = attemptCompleteCurrentNodeState(nodeName); getResponse().setEntity(newState.toString(), MediaType.TEXT_PLAIN);