Skip to content

Commit db0bd19

Browse files
author
Ian Campbell
committed
Simplify cli plugin config file entry
Make it a simple `map[string]string` for now. Signed-off-by: Ian Campbell <[email protected]>
1 parent 3a27e2b commit db0bd19

File tree

4 files changed

+111
-62
lines changed

4 files changed

+111
-62
lines changed

cli/config/configfile/file.go

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -24,32 +24,32 @@ const (
2424

2525
// ConfigFile ~/.docker/config.json file info
2626
type ConfigFile struct {
27-
AuthConfigs map[string]types.AuthConfig `json:"auths"`
28-
HTTPHeaders map[string]string `json:"HttpHeaders,omitempty"`
29-
PsFormat string `json:"psFormat,omitempty"`
30-
ImagesFormat string `json:"imagesFormat,omitempty"`
31-
NetworksFormat string `json:"networksFormat,omitempty"`
32-
PluginsFormat string `json:"pluginsFormat,omitempty"`
33-
VolumesFormat string `json:"volumesFormat,omitempty"`
34-
StatsFormat string `json:"statsFormat,omitempty"`
35-
DetachKeys string `json:"detachKeys,omitempty"`
36-
CredentialsStore string `json:"credsStore,omitempty"`
37-
CredentialHelpers map[string]string `json:"credHelpers,omitempty"`
38-
Filename string `json:"-"` // Note: for internal use only
39-
ServiceInspectFormat string `json:"serviceInspectFormat,omitempty"`
40-
ServicesFormat string `json:"servicesFormat,omitempty"`
41-
TasksFormat string `json:"tasksFormat,omitempty"`
42-
SecretFormat string `json:"secretFormat,omitempty"`
43-
ConfigFormat string `json:"configFormat,omitempty"`
44-
NodesFormat string `json:"nodesFormat,omitempty"`
45-
PruneFilters []string `json:"pruneFilters,omitempty"`
46-
Proxies map[string]ProxyConfig `json:"proxies,omitempty"`
47-
Experimental string `json:"experimental,omitempty"`
48-
StackOrchestrator string `json:"stackOrchestrator,omitempty"`
49-
Kubernetes *KubernetesConfig `json:"kubernetes,omitempty"`
50-
CurrentContext string `json:"currentContext,omitempty"`
51-
CLIPluginsExtraDirs []string `json:"cliPluginsExtraDirs,omitempty"`
52-
Plugins map[string]json.RawMessage `json:"plugins,omitempty"`
27+
AuthConfigs map[string]types.AuthConfig `json:"auths"`
28+
HTTPHeaders map[string]string `json:"HttpHeaders,omitempty"`
29+
PsFormat string `json:"psFormat,omitempty"`
30+
ImagesFormat string `json:"imagesFormat,omitempty"`
31+
NetworksFormat string `json:"networksFormat,omitempty"`
32+
PluginsFormat string `json:"pluginsFormat,omitempty"`
33+
VolumesFormat string `json:"volumesFormat,omitempty"`
34+
StatsFormat string `json:"statsFormat,omitempty"`
35+
DetachKeys string `json:"detachKeys,omitempty"`
36+
CredentialsStore string `json:"credsStore,omitempty"`
37+
CredentialHelpers map[string]string `json:"credHelpers,omitempty"`
38+
Filename string `json:"-"` // Note: for internal use only
39+
ServiceInspectFormat string `json:"serviceInspectFormat,omitempty"`
40+
ServicesFormat string `json:"servicesFormat,omitempty"`
41+
TasksFormat string `json:"tasksFormat,omitempty"`
42+
SecretFormat string `json:"secretFormat,omitempty"`
43+
ConfigFormat string `json:"configFormat,omitempty"`
44+
NodesFormat string `json:"nodesFormat,omitempty"`
45+
PruneFilters []string `json:"pruneFilters,omitempty"`
46+
Proxies map[string]ProxyConfig `json:"proxies,omitempty"`
47+
Experimental string `json:"experimental,omitempty"`
48+
StackOrchestrator string `json:"stackOrchestrator,omitempty"`
49+
Kubernetes *KubernetesConfig `json:"kubernetes,omitempty"`
50+
CurrentContext string `json:"currentContext,omitempty"`
51+
CLIPluginsExtraDirs []string `json:"cliPluginsExtraDirs,omitempty"`
52+
Plugins map[string]map[string]string `json:"plugins,omitempty"`
5353
}
5454

5555
// ProxyConfig contains proxy configuration settings
@@ -71,7 +71,7 @@ func New(fn string) *ConfigFile {
7171
AuthConfigs: make(map[string]types.AuthConfig),
7272
HTTPHeaders: make(map[string]string),
7373
Filename: fn,
74-
Plugins: make(map[string]json.RawMessage),
74+
Plugins: make(map[string]map[string]string),
7575
}
7676
}
7777

@@ -332,6 +332,36 @@ func (configFile *ConfigFile) GetFilename() string {
332332
return configFile.Filename
333333
}
334334

335+
// PluginConfig retrieves the requested option for the given plugin.
336+
func (configFile *ConfigFile) PluginConfig(pluginname, option string) (string, bool) {
337+
pluginConfig, ok := configFile.Plugins[pluginname]
338+
if !ok {
339+
return "", false
340+
}
341+
value, ok := pluginConfig[option]
342+
return value, ok
343+
}
344+
345+
// SetPluginConfig sets the option to the given value for the given
346+
// plugin. Passing a value of "" will remove the option. If removing
347+
// the final config item for a given plugin then also cleans up the
348+
// overall plugin entry.
349+
func (configFile *ConfigFile) SetPluginConfig(pluginname, option, value string) {
350+
pluginConfig, ok := configFile.Plugins[pluginname]
351+
if !ok {
352+
pluginConfig = make(map[string]string)
353+
configFile.Plugins[pluginname] = pluginConfig
354+
}
355+
if value != "" {
356+
pluginConfig[option] = value
357+
} else {
358+
delete(pluginConfig, option)
359+
}
360+
if len(pluginConfig) == 0 {
361+
delete(configFile.Plugins, pluginname)
362+
}
363+
}
364+
335365
func checkKubernetesConfiguration(kubeConfig *KubernetesConfig) error {
336366
if kubeConfig == nil {
337367
return nil

cli/config/configfile/file_test.go

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package configfile
22

33
import (
44
"bytes"
5-
"encoding/json"
65
"io/ioutil"
76
"os"
87
"testing"
@@ -437,31 +436,17 @@ func TestPluginConfig(t *testing.T) {
437436
configFile := New("test-plugin")
438437
defer os.Remove("test-plugin")
439438

440-
type PluginConfig1 struct {
441-
Data1 string `json:"data1"`
442-
Data2 int `json:"data2"`
439+
// Populate some initial values
440+
configFile.Plugins["plugin1"] = map[string]string{
441+
"data1": "some string",
442+
"data2": "42",
443443
}
444-
type PluginConfig2 struct {
445-
Data3 string `json:"data3"`
444+
configFile.Plugins["plugin2"] = map[string]string{
445+
"data3": "some other string",
446446
}
447-
p1 := PluginConfig1{
448-
Data1: "some string",
449-
Data2: 42,
450-
}
451-
p2 := PluginConfig2{
452-
Data3: "some other string",
453-
}
454-
455-
plugin1, err := json.MarshalIndent(p1, "", "\t")
456-
assert.NilError(t, err)
457-
configFile.Plugins["plugin1"] = plugin1
458-
459-
plugin2, err := json.MarshalIndent(p2, "", "\t")
460-
assert.NilError(t, err)
461-
configFile.Plugins["plugin2"] = plugin2
462447

463448
// Save a config file with some plugin config
464-
err = configFile.Save()
449+
err := configFile.Save()
465450
assert.NilError(t, err)
466451

467452
// Read it back and check it has the expected content
@@ -471,25 +456,47 @@ func TestPluginConfig(t *testing.T) {
471456

472457
// Load it, resave and check again that the content is
473458
// preserved through a load/save cycle.
474-
configFile2 := New("test-plugin2")
459+
configFile = New("test-plugin2")
475460
defer os.Remove("test-plugin2")
476-
assert.NilError(t, configFile2.LoadFromReader(bytes.NewReader(cfg)))
477-
err = configFile2.Save()
461+
assert.NilError(t, configFile.LoadFromReader(bytes.NewReader(cfg)))
462+
err = configFile.Save()
478463
assert.NilError(t, err)
479464
cfg, err = ioutil.ReadFile("test-plugin2")
480465
assert.NilError(t, err)
481466
golden.Assert(t, string(cfg), "plugin-config.golden")
482467

483-
// Check that the contents was retained properly
484-
var p1bis PluginConfig1
485-
assert.Assert(t, is.Contains(configFile2.Plugins, "plugin1"))
486-
err = json.Unmarshal(configFile2.Plugins["plugin1"], &p1bis)
468+
// Check that the contents was reloaded properly
469+
v, ok := configFile.PluginConfig("plugin1", "data1")
470+
assert.Assert(t, ok)
471+
assert.Equal(t, v, "some string")
472+
v, ok = configFile.PluginConfig("plugin1", "data2")
473+
assert.Assert(t, ok)
474+
assert.Equal(t, v, "42")
475+
v, ok = configFile.PluginConfig("plugin1", "data3")
476+
assert.Assert(t, !ok)
477+
assert.Equal(t, v, "")
478+
v, ok = configFile.PluginConfig("plugin2", "data3")
479+
assert.Assert(t, ok)
480+
assert.Equal(t, v, "some other string")
481+
v, ok = configFile.PluginConfig("plugin2", "data4")
482+
assert.Assert(t, !ok)
483+
assert.Equal(t, v, "")
484+
v, ok = configFile.PluginConfig("plugin3", "data5")
485+
assert.Assert(t, !ok)
486+
assert.Equal(t, v, "")
487+
488+
// Add, remove and modify
489+
configFile.SetPluginConfig("plugin1", "data1", "some replacement string") // replacing a key
490+
configFile.SetPluginConfig("plugin1", "data2", "") // deleting a key
491+
configFile.SetPluginConfig("plugin1", "data3", "some additional string") // new key
492+
configFile.SetPluginConfig("plugin2", "data3", "") // delete the whole plugin, since this was the only data
493+
configFile.SetPluginConfig("plugin3", "data5", "a new plugin") // add a new plugin
494+
495+
err = configFile.Save()
487496
assert.NilError(t, err)
488-
assert.DeepEqual(t, p1, p1bis)
489497

490-
var p2bis PluginConfig2
491-
assert.Assert(t, is.Contains(configFile2.Plugins, "plugin2"))
492-
err = json.Unmarshal(configFile2.Plugins["plugin2"], &p2bis)
498+
// Read it back and check it has the expected content again
499+
cfg, err = ioutil.ReadFile("test-plugin2")
493500
assert.NilError(t, err)
494-
assert.DeepEqual(t, p2, p2bis)
501+
golden.Assert(t, string(cfg), "plugin-config-2.golden")
495502
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"auths": {},
3+
"plugins": {
4+
"plugin1": {
5+
"data1": "some replacement string",
6+
"data3": "some additional string"
7+
},
8+
"plugin3": {
9+
"data5": "a new plugin"
10+
}
11+
}
12+
}

cli/config/configfile/testdata/plugin-config.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"plugins": {
44
"plugin1": {
55
"data1": "some string",
6-
"data2": 42
6+
"data2": "42"
77
},
88
"plugin2": {
99
"data3": "some other string"

0 commit comments

Comments
 (0)