Browse code

Explicit parameter generation syntax in templates

- Add "generate" field to specify generator to be used
- Add "from" field to specify the input value for generator
- Remove "type" field, as it's always "string" anyway

Vojtech Vitek (V-Teq) authored on 2014/10/07 08:37:09
Showing 11 changed files
... ...
@@ -27,16 +27,15 @@
27 27
             "type": "string",
28 28
             "required": true
29 29
           },
30
-          "type": {
30
+          "generate": {
31 31
             "type": "string",
32
-            "required": true,
33
-            "enum": ["string"]
32
+            "required": false
34 33
           },
35
-          "value": {
34
+          "from": {
36 35
             "type": "string",
37 36
             "required": false
38 37
           },
39
-          "expression": {
38
+          "value": {
40 39
             "type": "string",
41 40
             "required": false
42 41
           },
... ...
@@ -8,19 +8,18 @@
8 8
     {
9 9
       "name": "DB_PASSWORD",
10 10
       "description": "PostgreSQL admin user password",
11
-      "type": "string",
12
-      "expression": "[a-zA-Z0-9]{8}"
11
+      "generate": "expression",
12
+      "from": "[a-zA-Z0-9]{8}"
13 13
     },
14 14
     {
15 15
       "name": "DB_USER",
16 16
       "description": "PostgreSQL username",
17
-      "type": "string",
18
-      "expression": "admin[a-zA-Z0-9]{4}"
17
+      "generate": "expression",
18
+      "from": "admin[a-zA-Z0-9]{4}"
19 19
     },
20 20
     {
21 21
       "name": "DB_NAME",
22 22
       "description": "PostgreSQL database name",
23
-      "type": "string",
24 23
       "value": "mydb"
25 24
     }
26 25
   ],
... ...
@@ -1,4 +1,4 @@
1
-<!DOCTYPE HTML><html><head><title>OpenShift 3 API documentation</title><meta http-equiv=X-UA-Compatible content="IE=edge"><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=generator content="https://github.com/kevinrenskers/raml2html 1.0.4"><link rel=stylesheet href=http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css><link rel=stylesheet href=http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.1/styles/default.min.css><script type=text/javascript src=http://code.jquery.com/jquery-1.11.0.min.js></script><script type=text/javascript src=http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js></script><script type=text/javascript src=http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.1/highlight.min.js></script><script type=text/javascript>
1
+<!DOCTYPE HTML><html><head><title>OpenShift 3 API documentation</title><meta http-equiv=X-UA-Compatible content="IE=edge"><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=generator content="https://github.com/kevinrenskers/raml2html 1.0.3"><link rel=stylesheet href=http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css><link rel=stylesheet href=http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.1/styles/default.min.css><script type=text/javascript src=http://code.jquery.com/jquery-1.11.0.min.js></script><script type=text/javascript src=http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js></script><script type=text/javascript src=http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.1/highlight.min.js></script><script type=text/javascript>
2 2
         $(document).ready(function() {
3 3
             $('.page-header pre code, .top-resource-description pre code').each(function(i, block) {
4 4
                 hljs.highlightBlock(block);
... ...
@@ -1577,16 +1577,15 @@
1577 1577
             "type": "string",
1578 1578
             "required": true
1579 1579
           },
1580
-          "type": {
1580
+          "generate": {
1581 1581
             "type": "string",
1582
-            "required": true,
1583
-            "enum": ["string"]
1582
+            "required": false
1584 1583
           },
1585
-          "value": {
1584
+          "from": {
1586 1585
             "type": "string",
1587 1586
             "required": false
1588 1587
           },
1589
-          "expression": {
1588
+          "value": {
1590 1589
             "type": "string",
1591 1590
             "required": false
1592 1591
           },
... ...
@@ -1617,27 +1616,27 @@
1617 1617
     }
1618 1618
   }
1619 1619
 }</code></pre><p><strong>Example</strong>:</p><pre><code>{
1620
-  "kind": "Template",
1621 1620
   "id": "example1",
1621
+  "kind": "Template",
1622
+  "apiVersion": "v1beta1",
1622 1623
   "name": "My awesome PHP app",
1623 1624
   "description": "Example PHP application with PostgreSQL database",
1624 1625
   "parameters": [
1625 1626
     {
1626 1627
       "name": "DB_PASSWORD",
1627 1628
       "description": "PostgreSQL admin user password",
1628
-      "type": "string",
1629
-      "expression": "[a-zA-Z0-9]{8}"
1629
+      "generate": "expression",
1630
+      "from": "[a-zA-Z0-9]{8}"
1630 1631
     },
1631 1632
     {
1632 1633
       "name": "DB_USER",
1633 1634
       "description": "PostgreSQL username",
1634
-      "type": "string",
1635
-      "expression": "admin[a-zA-Z0-9]{4}"
1635
+      "generate": "expression",
1636
+      "from": "admin[a-zA-Z0-9]{4}"
1636 1637
     },
1637 1638
     {
1638 1639
       "name": "DB_NAME",
1639 1640
       "description": "PostgreSQL database name",
1640
-      "type": "string",
1641 1641
       "value": "mydb"
1642 1642
     }
1643 1643
   ],
... ...
@@ -1754,7 +1753,8 @@
1754 1754
       }
1755 1755
     }
1756 1756
   ]
1757
-}</code></pre></div><div class=tab-pane id=_templateConfigs_post_response><h2>HTTP status code <a href=http://httpstatus.es/200 target=_blank>200</a></h2><h3>Body</h3><p><strong>Type: application/json</strong></p><p><strong>Example</strong>:</p><pre><code>{
1757
+}
1758
+</code></pre></div><div class=tab-pane id=_templateConfigs_post_response><h2>HTTP status code <a href=http://httpstatus.es/200 target=_blank>200</a></h2><h3>Body</h3><p><strong>Type: application/json</strong></p><p><strong>Example</strong>:</p><pre><code>{
1758 1759
   "kind": "Config",
1759 1760
   "id": "example1",
1760 1761
   "name": "My awesome PHP app",
... ...
@@ -1902,63 +1902,49 @@
1902 1902
     }
1903 1903
   ]
1904 1904
 }</code></pre></div></div></div></div></div></div></div></div></div></div><div class="panel panel-default"><div class=panel-heading><h3 id=_templates class=panel-title>/templates (NOT IMPLEMENTED)</h3></div><div class=panel-body><div class=panel-group><div class="panel panel-white"><div class=panel-heading><h4 class=panel-title><a class=collapsed data-toggle=collapse href=#panel__templates><span class=parent></span>/templates</a> <span class=methods><a href=# data-toggle=modal data-target=#_templates_get><span class="badge badge_get">get</span></a> <a href=# data-toggle=modal data-target=#_templates_post><span class="badge badge_post">post</span></a></span></h4></div><div id=panel__templates class="panel-collapse collapse"><div class=panel-body><div class=list-group><div data-toggle=modal data-target=#_templates_get class=list-group-item><span class="badge badge_get">get</span><div class=method_description><p>List all templates that your account has access to.</p><p>A template represents generic config with parameters.</p><p>Parameters:</p><p>Example #1 - static paramater:</p><pre><code>{
1905
-
1906 1905
   "name": "DB_NAME",
1907
-
1908 1906
   "description": "PostgreSQL database name",
1909
-
1910
-  "type": "string",
1911
-
1912 1907
   "value": "mydb"
1913
-
1914 1908
 }
1915
-</code></pre><p>The above parameter can be referenced in the rest of the template as ${DB_NAME} expression, which is to be substituted by its value (the "mydb" string) during the transformation.</p><p>Example #2 - parameter with generator:</p><pre><code>{
1916
-
1909
+</code></pre><p>The above parameter can be referenced in the rest of the template as ${DB_NAME} expression, which is to be substituted by its value (the "mydb" string) during the template to config transformation.</p><p>Example #2 - parameter with generator:</p><pre><code>{
1917 1910
   "name": "DB_PASSWORD",
1918
-
1919 1911
   "description": "PostgreSQL admin user password",
1920
-
1921
-  "type": "string",
1922
-
1923
-  "expression": "[a-zA-Z0-9]{8}"
1924
-
1912
+  "generate": "expression",
1913
+  "from": "[a-zA-Z0-9]{8}"
1925 1914
 }
1926
-</code></pre><p>The above parameter can be referenced in the rest of the template as ${DB_PASSWORD} expression, which is to be substituted by its newly generated value during the transformation.</p><p>Generators:</p><p>Generators generate random values based on the input. OpenShift 3 currently support expression value generator only.</p><p>Expression value generator generates random string based on the input expression. The input expression is a string, which may contain "[a-zA-Z0-9]{length}" expression constructs, defining range and length of the result random characters.</p><p>Examples ("expression" =&gt; "value"):</p><pre><code>"test[0-9]{1}x" =&gt; "test7x"
1927
-
1928
-"[0-1]{8}" =&gt; "01001100"
1929
-
1930
-"0x[A-F0-9]{4}" =&gt; "0xB3AF"
1931
-
1932
-"[a-zA-Z0-9]{8}" =&gt; "hW4yQU5i"
1915
+</code></pre><p>The above parameter can be referenced in the rest of the template as ${DB_PASSWORD} expression, which is to be substituted with its newly generated value by expression value generator during the template to config transformation.</p><p>Generators:</p><p>The value of "generate" field specifies the generator to be used. The selected generator then generates random value based on the "from" input value. OpenShift 3 currently supports expression value generator only.</p><p>Expression value generator:</p><p>Expression value generator is used when generate field matches "expression" value. It generates random string based on the "from" input value. The input value is a string expression, which may contain "[a-zA-Z0-9]{length}" constructs, defining range and length of the result random characters.</p><pre><code>{
1916
+  "name": "PARAM",
1917
+  "generate": "expression",
1918
+  "from": "input expression"
1919
+}
1920
+</code></pre><p>Examples:</p><pre><code>from             | value
1921
+-----------------------------
1922
+"test[0-9]{1}x"  | "test7x"
1923
+"[0-1]{8}"       | "01001100"
1924
+"0x[A-F0-9]{4}"  | "0xB3AF"
1925
+"[a-zA-Z0-9]{8}" | "hW4yQU5i"
1933 1926
 </code></pre></div><div class=clearfix></div></div><div data-toggle=modal data-target=#_templates_post class=list-group-item><span class="badge badge_post">post</span><div class=method_description><p>Create a new template.</p></div><div class=clearfix></div></div></div></div></div><div class="modal fade" tabindex=0 id=_templates_get><div class=modal-dialog><div class=modal-content><div class=modal-header><button type=button class=close data-dismiss=modal aria-hidden=true>&times;</button><h4 class=modal-title id=myModalLabel><span class="badge badge_get">get</span> <span class=parent></span>/templates</h4></div><div class=modal-body><div class="alert alert-info"><p>List all templates that your account has access to.</p><p>A template represents generic config with parameters.</p><p>Parameters:</p><p>Example #1 - static paramater:</p><pre><code>{
1934
-
1935 1927
   "name": "DB_NAME",
1936
-
1937 1928
   "description": "PostgreSQL database name",
1938
-
1939
-  "type": "string",
1940
-
1941 1929
   "value": "mydb"
1942
-
1943 1930
 }
1944
-</code></pre><p>The above parameter can be referenced in the rest of the template as ${DB_NAME} expression, which is to be substituted by its value (the "mydb" string) during the transformation.</p><p>Example #2 - parameter with generator:</p><pre><code>{
1945
-
1931
+</code></pre><p>The above parameter can be referenced in the rest of the template as ${DB_NAME} expression, which is to be substituted by its value (the "mydb" string) during the template to config transformation.</p><p>Example #2 - parameter with generator:</p><pre><code>{
1946 1932
   "name": "DB_PASSWORD",
1947
-
1948 1933
   "description": "PostgreSQL admin user password",
1949
-
1950
-  "type": "string",
1951
-
1952
-  "expression": "[a-zA-Z0-9]{8}"
1953
-
1934
+  "generate": "expression",
1935
+  "from": "[a-zA-Z0-9]{8}"
1954 1936
 }
1955
-</code></pre><p>The above parameter can be referenced in the rest of the template as ${DB_PASSWORD} expression, which is to be substituted by its newly generated value during the transformation.</p><p>Generators:</p><p>Generators generate random values based on the input. OpenShift 3 currently support expression value generator only.</p><p>Expression value generator generates random string based on the input expression. The input expression is a string, which may contain "[a-zA-Z0-9]{length}" expression constructs, defining range and length of the result random characters.</p><p>Examples ("expression" =&gt; "value"):</p><pre><code>"test[0-9]{1}x" =&gt; "test7x"
1956
-
1957
-"[0-1]{8}" =&gt; "01001100"
1958
-
1959
-"0x[A-F0-9]{4}" =&gt; "0xB3AF"
1960
-
1961
-"[a-zA-Z0-9]{8}" =&gt; "hW4yQU5i"
1937
+</code></pre><p>The above parameter can be referenced in the rest of the template as ${DB_PASSWORD} expression, which is to be substituted with its newly generated value by expression value generator during the template to config transformation.</p><p>Generators:</p><p>The value of "generate" field specifies the generator to be used. The selected generator then generates random value based on the "from" input value. OpenShift 3 currently supports expression value generator only.</p><p>Expression value generator:</p><p>Expression value generator is used when generate field matches "expression" value. It generates random string based on the "from" input value. The input value is a string expression, which may contain "[a-zA-Z0-9]{length}" constructs, defining range and length of the result random characters.</p><pre><code>{
1938
+  "name": "PARAM",
1939
+  "generate": "expression",
1940
+  "from": "input expression"
1941
+}
1942
+</code></pre><p>Examples:</p><pre><code>from             | value
1943
+-----------------------------
1944
+"test[0-9]{1}x"  | "test7x"
1945
+"[0-1]{8}"       | "01001100"
1946
+"0x[A-F0-9]{4}"  | "0xB3AF"
1947
+"[a-zA-Z0-9]{8}" | "hW4yQU5i"
1962 1948
 </code></pre></div><ul class="nav nav-tabs"><li class=active><a href=#_templates_get_request data-toggle=tab>Request</a></li></ul><div class=tab-content><div class="tab-pane active" id=_templates_get_request></div></div></div></div></div></div><div class="modal fade" tabindex=0 id=_templates_post><div class=modal-dialog><div class=modal-content><div class=modal-header><button type=button class=close data-dismiss=modal aria-hidden=true>&times;</button><h4 class=modal-title id=myModalLabel><span class="badge badge_post">post</span> <span class=parent></span>/templates</h4></div><div class=modal-body><div class="alert alert-info"><p>Create a new template.</p></div><ul class="nav nav-tabs"><li class=active><a href=#_templates_post_request data-toggle=tab>Request</a></li><li><a href=#_templates_post_response data-toggle=tab>Response</a></li></ul><div class=tab-content><div class="tab-pane active" id=_templates_post_request><h3>Body</h3><p><strong>Type: application/json</strong></p><p><strong>Schema</strong>:</p><pre><code>{
1963 1949
   "$schema": "http://json-schema.org/draft-03/schema",
1964 1950
   "type": "object",
... ...
@@ -1988,16 +1974,15 @@
1988 1988
             "type": "string",
1989 1989
             "required": true
1990 1990
           },
1991
-          "type": {
1991
+          "generate": {
1992 1992
             "type": "string",
1993
-            "required": true,
1994
-            "enum": ["string"]
1993
+            "required": false
1995 1994
           },
1996
-          "value": {
1995
+          "from": {
1997 1996
             "type": "string",
1998 1997
             "required": false
1999 1998
           },
2000
-          "expression": {
1999
+          "value": {
2001 2000
             "type": "string",
2002 2001
             "required": false
2003 2002
           },
... ...
@@ -2028,27 +2013,27 @@
2028 2028
     }
2029 2029
   }
2030 2030
 }</code></pre><p><strong>Example</strong>:</p><pre><code>{
2031
-  "kind": "Template",
2032 2031
   "id": "example1",
2032
+  "kind": "Template",
2033
+  "apiVersion": "v1beta1",
2033 2034
   "name": "My awesome PHP app",
2034 2035
   "description": "Example PHP application with PostgreSQL database",
2035 2036
   "parameters": [
2036 2037
     {
2037 2038
       "name": "DB_PASSWORD",
2038 2039
       "description": "PostgreSQL admin user password",
2039
-      "type": "string",
2040
-      "expression": "[a-zA-Z0-9]{8}"
2040
+      "generate": "expression",
2041
+      "from": "[a-zA-Z0-9]{8}"
2041 2042
     },
2042 2043
     {
2043 2044
       "name": "DB_USER",
2044 2045
       "description": "PostgreSQL username",
2045
-      "type": "string",
2046
-      "expression": "admin[a-zA-Z0-9]{4}"
2046
+      "generate": "expression",
2047
+      "from": "admin[a-zA-Z0-9]{4}"
2047 2048
     },
2048 2049
     {
2049 2050
       "name": "DB_NAME",
2050 2051
       "description": "PostgreSQL database name",
2051
-      "type": "string",
2052 2052
       "value": "mydb"
2053 2053
     }
2054 2054
   ],
... ...
@@ -2165,34 +2150,35 @@
2165 2165
       }
2166 2166
     }
2167 2167
   ]
2168
-}</code></pre></div><div class=tab-pane id=_templates_post_response><h2>HTTP status code <a href=http://httpstatus.es/200 target=_blank>200</a></h2><h3>Body</h3><p><strong>Type: application/json</strong></p><p><strong>Example</strong>:</p><pre><code>{
2168
+}
2169
+</code></pre></div><div class=tab-pane id=_templates_post_response><h2>HTTP status code <a href=http://httpstatus.es/200 target=_blank>200</a></h2><h3>Body</h3><p><strong>Type: application/json</strong></p><p><strong>Example</strong>:</p><pre><code>{
2169 2170
     "apiVersion": "v1beta1",
2170 2171
     "creationTimestamp": null,
2171 2172
     "kind": "Status",
2172 2173
     "status": "success"
2173 2174
 }
2174 2175
 </code></pre></div></div></div></div></div></div></div><div class="panel panel-white"><div class=panel-heading><h4 class=panel-title><a class=collapsed data-toggle=collapse href=#panel__templates__templateID_><span class=parent>/templates</span>/{templateID}</a> <span class=methods><a href=# data-toggle=modal data-target=#_templates__templateID__get><span class="badge badge_get">get</span></a> <a href=# data-toggle=modal data-target=#_templates__templateID__put><span class="badge badge_put">put</span></a> <a href=# data-toggle=modal data-target=#_templates__templateID__delete><span class="badge badge_delete">delete</span></a></span></h4></div><div id=panel__templates__templateID_ class="panel-collapse collapse"><div class=panel-body><div class=list-group><div data-toggle=modal data-target=#_templates__templateID__get class=list-group-item><span class="badge badge_get">get</span><div class=method_description><p>Get a specific template.</p></div><div class=clearfix></div></div><div data-toggle=modal data-target=#_templates__templateID__put class=list-group-item><span class="badge badge_put">put</span><div class=method_description><p>Update a specific template.</p></div><div class=clearfix></div></div><div data-toggle=modal data-target=#_templates__templateID__delete class=list-group-item><span class="badge badge_delete">delete</span><div class=method_description><p>Delete a specific template.</p></div><div class=clearfix></div></div></div></div></div><div class="modal fade" tabindex=0 id=_templates__templateID__get><div class=modal-dialog><div class=modal-content><div class=modal-header><button type=button class=close data-dismiss=modal aria-hidden=true>&times;</button><h4 class=modal-title id=myModalLabel><span class="badge badge_get">get</span> <span class=parent>/templates</span>/{templateID}</h4></div><div class=modal-body><div class="alert alert-info"><p>Get a specific template.</p></div><ul class="nav nav-tabs"><li class=active><a href=#_templates__templateID__get_request data-toggle=tab>Request</a></li><li><a href=#_templates__templateID__get_response data-toggle=tab>Response</a></li></ul><div class=tab-content><div class="tab-pane active" id=_templates__templateID__get_request><h3>URI Parameters</h3><ul><li><strong>templateID</strong>: <em>required (string)</em></li></ul></div><div class=tab-pane id=_templates__templateID__get_response><h2>HTTP status code <a href=http://httpstatus.es/200 target=_blank>200</a></h2><h3>Body</h3><p><strong>Type: application/json</strong></p><p><strong>Example</strong>:</p><pre><code>{
2175
-  "kind": "Template",
2176 2176
   "id": "example1",
2177
+  "kind": "Template",
2178
+  "apiVersion": "v1beta1",
2177 2179
   "name": "My awesome PHP app",
2178 2180
   "description": "Example PHP application with PostgreSQL database",
2179 2181
   "parameters": [
2180 2182
     {
2181 2183
       "name": "DB_PASSWORD",
2182 2184
       "description": "PostgreSQL admin user password",
2183
-      "type": "string",
2184
-      "expression": "[a-zA-Z0-9]{8}"
2185
+      "generate": "expression",
2186
+      "from": "[a-zA-Z0-9]{8}"
2185 2187
     },
2186 2188
     {
2187 2189
       "name": "DB_USER",
2188 2190
       "description": "PostgreSQL username",
2189
-      "type": "string",
2190
-      "expression": "admin[a-zA-Z0-9]{4}"
2191
+      "generate": "expression",
2192
+      "from": "admin[a-zA-Z0-9]{4}"
2191 2193
     },
2192 2194
     {
2193 2195
       "name": "DB_NAME",
2194 2196
       "description": "PostgreSQL database name",
2195
-      "type": "string",
2196 2197
       "value": "mydb"
2197 2198
     }
2198 2199
   ],
... ...
@@ -2309,7 +2295,8 @@
2309 2309
       }
2310 2310
     }
2311 2311
   ]
2312
-}</code></pre></div></div></div></div></div></div><div class="modal fade" tabindex=0 id=_templates__templateID__put><div class=modal-dialog><div class=modal-content><div class=modal-header><button type=button class=close data-dismiss=modal aria-hidden=true>&times;</button><h4 class=modal-title id=myModalLabel><span class="badge badge_put">put</span> <span class=parent>/templates</span>/{templateID}</h4></div><div class=modal-body><div class="alert alert-info"><p>Update a specific template.</p></div><ul class="nav nav-tabs"><li class=active><a href=#_templates__templateID__put_request data-toggle=tab>Request</a></li><li><a href=#_templates__templateID__put_response data-toggle=tab>Response</a></li></ul><div class=tab-content><div class="tab-pane active" id=_templates__templateID__put_request><h3>URI Parameters</h3><ul><li><strong>templateID</strong>: <em>required (string)</em></li></ul></div><div class=tab-pane id=_templates__templateID__put_response><h2>HTTP status code <a href=http://httpstatus.es/200 target=_blank>200</a></h2><h3>Body</h3><p><strong>Type: application/json</strong></p><p><strong>Example</strong>:</p><pre><code>{
2312
+}
2313
+</code></pre></div></div></div></div></div></div><div class="modal fade" tabindex=0 id=_templates__templateID__put><div class=modal-dialog><div class=modal-content><div class=modal-header><button type=button class=close data-dismiss=modal aria-hidden=true>&times;</button><h4 class=modal-title id=myModalLabel><span class="badge badge_put">put</span> <span class=parent>/templates</span>/{templateID}</h4></div><div class=modal-body><div class="alert alert-info"><p>Update a specific template.</p></div><ul class="nav nav-tabs"><li class=active><a href=#_templates__templateID__put_request data-toggle=tab>Request</a></li><li><a href=#_templates__templateID__put_response data-toggle=tab>Response</a></li></ul><div class=tab-content><div class="tab-pane active" id=_templates__templateID__put_request><h3>URI Parameters</h3><ul><li><strong>templateID</strong>: <em>required (string)</em></li></ul></div><div class=tab-pane id=_templates__templateID__put_response><h2>HTTP status code <a href=http://httpstatus.es/200 target=_blank>200</a></h2><h3>Body</h3><p><strong>Type: application/json</strong></p><p><strong>Example</strong>:</p><pre><code>{
2313 2314
     "apiVersion": "v1beta1",
2314 2315
     "creationTimestamp": null,
2315 2316
     "kind": "Status",
... ...
@@ -426,58 +426,58 @@ documentation:
426 426
         Example #1 - static paramater:
427 427
 
428 428
           {
429
-
430 429
             "name": "DB_NAME",
431
-
432 430
             "description": "PostgreSQL database name",
433
-
434
-            "type": "string",
435
-
436 431
             "value": "mydb"
437
-
438 432
           }
439 433
 
440 434
         The above parameter can be referenced in the rest of the template
441 435
         as ${DB_NAME} expression, which is to be substituted by its value
442
-        (the "mydb" string) during the transformation.
436
+        (the "mydb" string) during the template to config transformation.
443 437
 
444 438
         Example #2 - parameter with generator:
445 439
 
446 440
           {
447
-
448 441
             "name": "DB_PASSWORD",
449
-
450 442
             "description": "PostgreSQL admin user password",
451
-
452
-            "type": "string",
453
-
454
-            "expression": "[a-zA-Z0-9]{8}"
455
-
443
+            "generate": "expression",
444
+            "from": "[a-zA-Z0-9]{8}"
456 445
           }
457 446
 
458 447
         The above parameter can be referenced in the rest of the template
459
-        as ${DB_PASSWORD} expression, which is to be substituted by its
460
-        newly generated value during the transformation.
448
+        as ${DB_PASSWORD} expression, which is to be substituted with its
449
+        newly generated value by expression value generator during the
450
+        template to config transformation.
461 451
 
462 452
       Generators:
463 453
 
464
-        Generators generate random values based on the input. OpenShift 3
465
-        currently support expression value generator only.
466
-
467
-        Expression value generator generates random string based on the
468
-        input expression. The input expression is a string, which may contain
469
-        "[a-zA-Z0-9]{length}" expression constructs, defining range and length
470
-        of the result random characters.
454
+        The value of "generate" field specifies the generator to be used.
455
+        The selected generator then generates random value based on the
456
+        "from" input value. OpenShift 3 currently supports expression value
457
+        generator only.
471 458
 
472
-        Examples ("expression" => "value"):
459
+      Expression value generator:
473 460
 
474
-          "test[0-9]{1}x" => "test7x"
461
+        Expression value generator is used when generate field matches
462
+        "expression" value. It generates random string based on the "from"
463
+        input value. The input value is a string expression, which may
464
+        contain "[a-zA-Z0-9]{length}" constructs, defining range and length
465
+        of the result random characters.
475 466
 
476
-          "[0-1]{8}" => "01001100"
467
+          {
468
+            "name": "PARAM",
469
+            "generate": "expression",
470
+            "from": "input expression"
471
+          }
477 472
 
478
-          "0x[A-F0-9]{4}" => "0xB3AF"
473
+        Examples:
479 474
 
480
-          "[a-zA-Z0-9]{8}" => "hW4yQU5i"
475
+          from             | value
476
+          -----------------------------
477
+          "test[0-9]{1}x"  | "test7x"
478
+          "[0-1]{8}"       | "01001100"
479
+          "0x[A-F0-9]{4}"  | "0xB3AF"
480
+          "[a-zA-Z0-9]{8}" | "hW4yQU5i"
481 481
 
482 482
   post:
483 483
     description: Create a new template.
... ...
@@ -8,20 +8,20 @@
8 8
     {
9 9
       "name": "ADMIN_USERNAME",
10 10
       "description": "Guestbook administrator username",
11
-      "type": "string",
12
-      "expression": "admin[A-Z0-9]{3}"
11
+      "generate": "expression",
12
+      "from": "admin[A-Z0-9]{3}"
13 13
     },
14 14
     {
15 15
       "name": "ADMIN_PASSWORD",
16 16
       "description": "Guestboot administrator password",
17
-      "type": "string",
18
-      "expression": "[a-zA-Z0-9]{8}"
17
+      "generate": "expression",
18
+      "from": "[a-zA-Z0-9]{8}"
19 19
     },
20 20
     {
21 21
       "name": "REDIS_PASSWORD",
22 22
       "description": "The password Redis use for communication",
23
-      "type": "string",
24
-      "expression": "[a-zA-Z0-9]{8}"
23
+      "generate": "expression",
24
+      "from": "[a-zA-Z0-9]{8}"
25 25
     }
26 26
   ],
27 27
   "items": [
... ...
@@ -8,20 +8,20 @@
8 8
     {
9 9
       "name": "ADMIN_USERNAME",
10 10
       "description": "administrator username",
11
-      "type": "string",
12
-      "expression": "admin[A-Z0-9]{3}"
11
+      "generate": "expression",
12
+      "from": "admin[A-Z0-9]{3}"
13 13
     },
14 14
     {
15 15
       "name": "ADMIN_PASSWORD",
16 16
       "description": "administrator password",
17
-      "type": "string",
18
-      "expression": "[a-zA-Z0-9]{8}"
17
+      "generate": "expression",
18
+      "from": "[a-zA-Z0-9]{8}"
19 19
     },
20 20
     {
21 21
       "name": "DB_PASSWORD",
22
-      "description": "",
23
-      "type": "string",
24
-      "expression": "[a-zA-Z0-9]{8}"
22
+      "description": "database password",
23
+      "generate": "expression",
24
+      "from": "[a-zA-Z0-9]{8}"
25 25
     }
26 26
   ],
27 27
   "items": [
... ...
@@ -35,18 +35,20 @@ type Parameter struct {
35 35
 	Name string `json:"name" yaml:"name"`
36 36
 
37 37
 	// Optional: Description describes the Parameter.
38
-	Description string `json:"description" yaml:"description"`
38
+	Description string `json:"description,omitempty" yaml:"description,omitempty"`
39 39
 
40
-	// Required: Type defines the type of the Parameter value.
41
-	Type string `json:"type" yaml:"type"`
40
+	// Optional: Generate specifies the generator to be used to generate
41
+	// random string from an input value specified by From field. The result
42
+	// string is stored into Value field. If empty, no generator is being
43
+	// used, leaving the result Value untouched.
44
+	Generate string `json:"generate,omitempty" yaml:"generate,omitempty"`
42 45
 
43
-	// Optional: Expression generates new Value data using the
44
-	// GeneratorExpressionValue expression.
45
-	// TODO: Support more Generator types.
46
-	Expression string `json:"expression,omitempty" yaml:"expression,omitempty"`
46
+	// Optional: From is an input value for the generator.
47
+	From string `json:"from,omitempty" yaml:"from,omitempty"`
47 48
 
48
-	// Optional: Value holds the Parameter data. The data replaces all occurances
49
-	// of the Parameter name during the Template to Config transformation.
50
-	// TODO: Change this to runtime.Object and support more types than just string.
49
+	// Optional: Value holds the Parameter data. The Value data can be
50
+	// overwritten by the generator. The value replaces all occurances
51
+	// of the Parameter ${Name} expression during the Template to Config
52
+	// transformation.
51 53
 	Value string `json:"value,omitempty" yaml:"value,omitempty"`
52 54
 }
... ...
@@ -35,18 +35,20 @@ type Parameter struct {
35 35
 	Name string `json:"name" yaml:"name"`
36 36
 
37 37
 	// Optional: Description describes the Parameter.
38
-	Description string `json:"description" yaml:"description"`
38
+	Description string `json:"description,omitempty" yaml:"description,omitempty"`
39 39
 
40
-	// Required: Type defines the type of the Parameter value.
41
-	Type string `json:"type" yaml:"type"`
40
+	// Optional: Generate specifies the generator to be used to generate
41
+	// random string from an input value specified by From field. The result
42
+	// string is stored into Value field. If empty, no generator is being
43
+	// used, leaving the result Value untouched.
44
+	Generate string `json:"generate,omitempty" yaml:"generate,omitempty"`
42 45
 
43
-	// Optional: Expression generates new Value data using the
44
-	// GeneratorExpressionValue expression.
45
-	// TODO: Support more Generator types.
46
-	Expression string `json:"expression,omitempty" yaml:"expression,omitempty"`
46
+	// Optional: From is an input value for the generator.
47
+	From string `json:"from,omitempty" yaml:"from,omitempty"`
47 48
 
48
-	// Optional: Value holds the Parameter data. The data replaces all occurances
49
-	// of the Parameter name during the Template to Config transformation.
50
-	// TODO: Change this to runtime.Object and support more types than just string.
49
+	// Optional: Value holds the Parameter data. The Value data can be
50
+	// overwritten by the generator. The value replaces all occurances
51
+	// of the Parameter ${Name} expression during the Template to Config
52
+	// transformation.
51 53
 	Value string `json:"value,omitempty" yaml:"value,omitempty"`
52 54
 }
... ...
@@ -10,14 +10,17 @@ import (
10 10
 
11 11
 // ExpressionValueGenerator implements Generator interface. It generates
12 12
 // random string based on the input expression. The input expression is
13
-// a string, which may contain "[a-zA-Z0-9]{length}" expression constructs,
13
+// a string, which may contain "[a-zA-Z0-9]{length}" constructs,
14 14
 // defining range and length of the result random characters.
15 15
 //
16 16
 // Examples:
17
-//   - "test[0-9]{1}x" => "test7x"
18
-//   - "[0-1]{8}" => "01001100"
19
-//   - "0x[A-F0-9]{4}" => "0xB3AF"
20
-//   - "[a-zA-Z0-9]{8}" => "hW4yQU5i"
17
+//
18
+// from             | value
19
+// -----------------------------
20
+// "test[0-9]{1}x"  | "test7x"
21
+// "[0-1]{8}"       | "01001100"
22
+// "0x[A-F0-9]{4}"  | "0xB3AF"
23
+// "[a-zA-Z0-9]{8}" | "hW4yQU5i"
21 24
 //
22 25
 // TODO: Support more regexp constructs.
23 26
 type ExpressionValueGenerator struct {
... ...
@@ -96,7 +96,7 @@ func (p *TemplateProcessor) SubstituteParameters(t *api.Template) error {
96 96
 			p.substituteParametersInManifest(&obj.DesiredState.Manifest, paramMap)
97 97
 			t.Items[i] = runtime.EmbeddedObject{Object: obj}
98 98
 		default:
99
-			glog.V(1).Infof("Parameter substitution not implemented for resource '%T'.", obj)
99
+			glog.V(1).Infof("template.items[%v]: Parameter substitution not implemented for resource '%T'.", i, obj)
100 100
 		}
101 101
 	}
102 102
 
... ...
@@ -124,29 +124,34 @@ func (p *TemplateProcessor) substituteParametersInManifest(manifest *kubeapi.Con
124 124
 }
125 125
 
126 126
 // GenerateParameterValues generates Value for each Parameter of the given
127
-// Template that has Expression field specified and doesn't have any
128
-// Value yet.
127
+// Template that has Generate field specified.
129 128
 //
130
-// Examples (Expression => Value):
131
-//   - "test[0-9]{1}x" => "test7x"
132
-//   - "[0-1]{8}" => "01001100"
133
-//   - "0x[A-F0-9]{4}" => "0xB3AF"
134
-//   - "[a-zA-Z0-9]{8}" => "hW4yQU5i"
129
+// Examples:
130
+//
131
+// from             | value
132
+// -----------------------------
133
+// "test[0-9]{1}x"  | "test7x"
134
+// "[0-1]{8}"       | "01001100"
135
+// "0x[A-F0-9]{4}"  | "0xB3AF"
136
+// "[a-zA-Z0-9]{8}" | "hW4yQU5i"
135 137
 func (p *TemplateProcessor) GenerateParameterValues(t *api.Template) error {
136 138
 	for i, _ := range t.Parameters {
137 139
 		param := &t.Parameters[i]
138
-		if param.Expression != "" && param.Value == "" {
139
-			generator, ok := p.Generators["expression"]
140
+		if param.Generate != "" {
141
+			generator, ok := p.Generators[param.Generate]
140 142
 			if !ok {
141
-				return fmt.Errorf("Can't find expression generator.")
143
+				return fmt.Errorf("template.parameters[%v]: Unable to find the '%v' generator.", i, param.Generate)
144
+			}
145
+			if generator == nil {
146
+				return fmt.Errorf("template.parameters[%v]: Invalid '%v' generator.", i, param.Generate)
142 147
 			}
143
-			value, err := generator.GenerateValue(param.Expression)
148
+			value, err := generator.GenerateValue(param.From)
144 149
 			if err != nil {
145 150
 				return err
146 151
 			}
147 152
 			param.Value, ok = value.(string)
148 153
 			if !ok {
149
-				return fmt.Errorf("Can't convert the generated value %v to string.", value)
154
+				return fmt.Errorf("template.parameters[%v]: Unable to convert the generated value '%#v' to string.", i, value)
150 155
 			}
151 156
 		}
152 157
 	}
... ...
@@ -13,7 +13,7 @@ import (
13 13
 
14 14
 	"github.com/openshift/origin/pkg/api/latest"
15 15
 	"github.com/openshift/origin/pkg/template/api"
16
-	. "github.com/openshift/origin/pkg/template/generator"
16
+	"github.com/openshift/origin/pkg/template/generator"
17 17
 )
18 18
 
19 19
 func TestNewTemplate(t *testing.T) {
... ...
@@ -44,16 +44,67 @@ func TestAddParameter(t *testing.T) {
44 44
 	}
45 45
 }
46 46
 
47
-func TestEmptyGenerators(t *testing.T) {
48
-	var template api.Template
49
-	jsonData, _ := ioutil.ReadFile("../../examples/guestbook/template.json")
50
-	json.Unmarshal(jsonData, &template)
47
+type FooGenerator struct {
48
+}
49
+
50
+func (g FooGenerator) GenerateValue(expression string) (interface{}, error) {
51
+	return "foo", nil
52
+}
53
+
54
+type ErrorGenerator struct {
55
+}
56
+
57
+func (g ErrorGenerator) GenerateValue(expression string) (interface{}, error) {
58
+	return "", fmt.Errorf("error")
59
+}
51 60
 
52
-	processor := NewTemplateProcessor(map[string]Generator{})
61
+func TestParameterGenerators(t *testing.T) {
62
+	tests := []struct {
63
+		parameter  api.Parameter
64
+		generators map[string]generator.Generator
65
+		shouldPass bool
66
+		expected   api.Parameter
67
+	}{
68
+		{ // Empty generator, should pass
69
+			api.Parameter{Name: "PARAM", Generate: "", Value: "X"},
70
+			map[string]generator.Generator{},
71
+			true,
72
+			api.Parameter{Name: "PARAM", Generate: "", Value: "X"},
73
+		},
74
+		{ // Foo generator, should pass
75
+			api.Parameter{Name: "PARAM", Generate: "foo", Value: ""},
76
+			map[string]generator.Generator{"foo": FooGenerator{}},
77
+			true,
78
+			api.Parameter{Name: "PARAM", Generate: "", Value: "foo"},
79
+		},
80
+		{ // Invalid generator, should fail
81
+			api.Parameter{Name: "PARAM", Generate: "invalid", Value: ""},
82
+			map[string]generator.Generator{"invalid": nil},
83
+			false,
84
+			api.Parameter{Name: "PARAM", Generate: "invalid", Value: ""},
85
+		},
86
+		{ // Error generator, should fail
87
+			api.Parameter{Name: "PARAM", Generate: "error", Value: ""},
88
+			map[string]generator.Generator{"error": ErrorGenerator{}},
89
+			false,
90
+			api.Parameter{Name: "PARAM", Generate: "error", Value: ""},
91
+		},
92
+	}
53 93
 
54
-	_, err := processor.Process(&template)
55
-	if err == nil {
56
-		t.Errorf("Expected error, no generators defined for Expression fields.")
94
+	for i, test := range tests {
95
+		processor := NewTemplateProcessor(test.generators)
96
+		template := api.Template{Parameters: []api.Parameter{test.parameter}}
97
+		err := processor.GenerateParameterValues(&template)
98
+		if err != nil && test.shouldPass {
99
+			t.Errorf("test[%v]: Unexpected error %v", i, err)
100
+		}
101
+		if err == nil && !test.shouldPass {
102
+			t.Errorf("test[%v]: Expected error", i)
103
+		}
104
+		actual := template.Parameters[0]
105
+		if actual.Value != test.expected.Value {
106
+			t.Errorf("test[%v]: Unexpected value: Expected: %#v, got: %#v", i, test.expected.Value, test.parameter.Value)
107
+		}
57 108
 	}
58 109
 }
59 110
 
... ...
@@ -62,8 +113,8 @@ func ExampleProcessTemplateParameters() {
62 62
 	jsonData, _ := ioutil.ReadFile("../../examples/guestbook/template.json")
63 63
 	latest.Codec.DecodeInto(jsonData, &template)
64 64
 
65
-	generators := map[string]Generator{
66
-		"expression": NewExpressionValueGenerator(rand.New(rand.NewSource(1337))),
65
+	generators := map[string]generator.Generator{
66
+		"expression": generator.NewExpressionValueGenerator(rand.New(rand.NewSource(1337))),
67 67
 	}
68 68
 	processor := NewTemplateProcessor(generators)
69 69