Browse code

Support arbitrary key:value properties for console extensions

Jessica Forrester authored on 2016/05/19 05:50:46
Showing 7 changed files
... ...
@@ -14,6 +14,7 @@ import (
14 14
 	"strings"
15 15
 
16 16
 	"github.com/openshift/origin/pkg/quota/admission/clusterresourceoverride/api"
17
+	html_template "html/template"
17 18
 	utilruntime "k8s.io/kubernetes/pkg/util/runtime"
18 19
 )
19 20
 
... ...
@@ -154,6 +155,22 @@ type WebConsoleVersion struct {
154 154
 	OpenShiftVersion  string
155 155
 }
156 156
 
157
+var extensionPropertiesTemplate = html_template.Must(html_template.New("webConsoleExtensionProperties").Parse(`
158
+window.OPENSHIFT_EXTENSION_PROPERTIES = {
159
+  {{ $values := .ExtensionPropertyValues }}
160
+  {{ range $i, $key := .ExtensionPropertyKeys }}
161
+  {{ if $i }},{{ end }}
162
+  {{ $value := index $values $i }}
163
+  "{{ $key }}": "{{ $value }}"
164
+  {{ end }}
165
+};
166
+`))
167
+
168
+type WebConsoleExtensionProperties struct {
169
+	ExtensionPropertyKeys   []html_template.JSStr
170
+	ExtensionPropertyValues []html_template.JSStr
171
+}
172
+
157 173
 var configTemplate = template.Must(template.New("webConsoleConfig").Parse(`
158 174
 window.OPENSHIFT_CONFIG = {
159 175
   apis: {
... ...
@@ -226,7 +243,7 @@ type WebConsoleConfig struct {
226 226
 	LimitRequestOverrides *api.ClusterResourceOverrideConfig
227 227
 }
228 228
 
229
-func GeneratedConfigHandler(config WebConsoleConfig, version WebConsoleVersion) (http.Handler, error) {
229
+func GeneratedConfigHandler(config WebConsoleConfig, version WebConsoleVersion, extensionProps WebConsoleExtensionProperties) (http.Handler, error) {
230 230
 	var buffer bytes.Buffer
231 231
 	if err := configTemplate.Execute(&buffer, config); err != nil {
232 232
 		return nil, err
... ...
@@ -234,6 +251,12 @@ func GeneratedConfigHandler(config WebConsoleConfig, version WebConsoleVersion)
234 234
 	if err := versionTemplate.Execute(&buffer, version); err != nil {
235 235
 		return nil, err
236 236
 	}
237
+
238
+	// We include the extension properties in config.js and not extensions.js because we
239
+	// want them treated with the same caching behavior as the rest of the values in config.js
240
+	if err := extensionPropertiesTemplate.Execute(&buffer, extensionProps); err != nil {
241
+		return nil, err
242
+	}
237 243
 	content := buffer.Bytes()
238 244
 
239 245
 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
... ...
@@ -17,7 +17,7 @@ func stubHandler(response string) http.Handler {
17 17
 }
18 18
 
19 19
 func TestWebConsoleConfigTemplate(t *testing.T) {
20
-	handler, err := GeneratedConfigHandler(WebConsoleConfig{}, WebConsoleVersion{})
20
+	handler, err := GeneratedConfigHandler(WebConsoleConfig{}, WebConsoleVersion{}, WebConsoleExtensionProperties{})
21 21
 	if err != nil {
22 22
 		t.Fatalf("expected a handler, got error %v", err)
23 23
 	}
... ...
@@ -565,6 +565,10 @@ type AssetConfig struct {
565 565
 	// Console loads
566 566
 	ExtensionScripts []string
567 567
 
568
+	// ExtensionProperties are key(string) and value(string) pairs that will be injected into the console under
569
+	// the global variable OPENSHIFT_EXTENSION_PROPERTIES
570
+	ExtensionProperties map[string]string
571
+
568 572
 	// ExtensionStylesheets are file paths on the asset server files to load as stylesheets when
569 573
 	// the Web Console loads
570 574
 	ExtensionStylesheets []string
... ...
@@ -53,6 +53,7 @@ var map_AssetConfig = map[string]string{
53 53
 	"loggingPublicURL":     "LoggingPublicURL is the public endpoint for logging (optional)",
54 54
 	"metricsPublicURL":     "MetricsPublicURL is the public endpoint for metrics (optional)",
55 55
 	"extensionScripts":     "ExtensionScripts are file paths on the asset server files to load as scripts when the Web Console loads",
56
+	"extensionProperties":  "ExtensionProperties are key(string) and value(string) pairs that will be injected into the console under the global variable OPENSHIFT_EXTENSION_PROPERTIES",
56 57
 	"extensionStylesheets": "ExtensionStylesheets are file paths on the asset server files to load as stylesheets when the Web Console loads",
57 58
 	"extensions":           "Extensions are files to serve from the asset server filesystem under a subcontext",
58 59
 	"extensionDevelopment": "ExtensionDevelopment when true tells the asset server to reload extension scripts and stylesheets for every request rather than only at startup. It lets you develop extensions without having to restart the server for every change.",
... ...
@@ -542,6 +542,10 @@ type AssetConfig struct {
542 542
 	// Console loads
543 543
 	ExtensionScripts []string `json:"extensionScripts"`
544 544
 
545
+	// ExtensionProperties are key(string) and value(string) pairs that will be injected into the console under
546
+	// the global variable OPENSHIFT_EXTENSION_PROPERTIES
547
+	ExtensionProperties map[string]string `json:"extensionProperties"`
548
+
545 549
 	// ExtensionStylesheets are file paths on the asset server files to load as stylesheets when
546 550
 	// the Web Console loads
547 551
 	ExtensionStylesheets []string `json:"extensionStylesheets"`
... ...
@@ -82,6 +82,7 @@ apiLevels: null
82 82
 apiVersion: v1
83 83
 assetConfig:
84 84
   extensionDevelopment: false
85
+  extensionProperties: null
85 86
   extensionScripts: null
86 87
   extensionStylesheets: null
87 88
   extensions:
... ...
@@ -3,6 +3,7 @@ package origin
3 3
 import (
4 4
 	"crypto/tls"
5 5
 	"fmt"
6
+	"html/template"
6 7
 	"net/http"
7 8
 	"net/url"
8 9
 	"path"
... ...
@@ -141,6 +142,18 @@ func (c *AssetConfig) buildAssetHandler() (http.Handler, error) {
141 141
 	return handler, nil
142 142
 }
143 143
 
144
+// Have to convert to arrays because go templates are limited and we need to be able to know
145
+// if we are on the last index for trailing commas in JSON
146
+func extensionPropertyArrays(extensionProperties map[string]string) ([]template.JSStr, []template.JSStr) {
147
+	extensionKeys := []template.JSStr{}
148
+	extensionValues := []template.JSStr{}
149
+	for key, value := range extensionProperties {
150
+		extensionKeys = append(extensionKeys, template.JSStr(key))
151
+		extensionValues = append(extensionValues, template.JSStr(value))
152
+	}
153
+	return extensionKeys, extensionValues
154
+}
155
+
144 156
 func (c *AssetConfig) addHandlers(mux *http.ServeMux) error {
145 157
 	assetHandler, err := c.buildAssetHandler()
146 158
 	if err != nil {
... ...
@@ -220,8 +233,14 @@ func (c *AssetConfig) addHandlers(mux *http.ServeMux) error {
220 220
 		KubernetesVersion: kVersionInfo.GitVersion,
221 221
 		OpenShiftVersion:  oVersionInfo.GitVersion,
222 222
 	}
223
+
224
+	extensionPropertyKeys, extensionPropertyValues := extensionPropertyArrays(c.Options.ExtensionProperties)
225
+	extensionProps := assets.WebConsoleExtensionProperties{
226
+		ExtensionPropertyKeys:   extensionPropertyKeys,
227
+		ExtensionPropertyValues: extensionPropertyValues,
228
+	}
223 229
 	configPath := path.Join(publicURL.Path, "config.js")
224
-	configHandler, err := assets.GeneratedConfigHandler(config, versionInfo)
230
+	configHandler, err := assets.GeneratedConfigHandler(config, versionInfo, extensionProps)
225 231
 	if err != nil {
226 232
 		return err
227 233
 	}