Don't fail on configuration keys like a:config:b:c
Configuration keys are simple namespace/name pairs, delimited by ":". For compatability, we also allow "<namespace>:config:<name>", but we always record the "nice" name in `Pulumi.<stack-name>.yaml`. While `pulumi config` and friends would block setting a key like `a🅱️c` (where the "name" has a colon in it), it would allow `a:config:b:c`. However, this would be recorded as `a🅱️c` in `Pulumi.<stack-name>.yaml`, which meant we'd error when parsing the configuration file later. To work around this, disallow ":" in the "name" part of a configuration key. With this change the following all work: ``` keyName my-project:keyName my-project:config:keyName ``` However, both `my-project:keyName:subKey` `my-project:config:keyName:subKey` are now disallowed. I considered allowing colons in subkeys, but I think it adds more confusion (due to the interaction with how we allow you elide the project name in the default case) than is worthwhile at this point. Fixes #2171
This commit is contained in:
parent
c878916901
commit
72d52c6e1f
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
- Fix an issue where if the directory containing the `pulumi` executable was not on the `$PATH` we would fail to load language plugins. We now will also search next to the current running copy of Pulumi (fixes [pulumi/pulumi#1956](https://github.com/pulumi/pulumi/issues/1956))
|
- Fix an issue where if the directory containing the `pulumi` executable was not on the `$PATH` we would fail to load language plugins. We now will also search next to the current running copy of Pulumi (fixes [pulumi/pulumi#1956](https://github.com/pulumi/pulumi/issues/1956))
|
||||||
|
|
||||||
|
- Fix an issue where passing a key of the form `foo:config:bar:baz` to `pulumi config set` would succeed but cause errors later when trying to interact with the stack. Setting this value is now blocked eagerly (fixes [pulumi/pulumi#2171](https://github.com/pulumi/pulumi/issues/2171))
|
||||||
|
|
||||||
## 0.16.5 (Released Novemeber 16th, 2018)
|
## 0.16.5 (Released Novemeber 16th, 2018)
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
|
|
|
@ -36,26 +36,30 @@ func MustMakeKey(namespace string, name string) Key {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseKey(s string) (Key, error) {
|
func ParseKey(s string) (Key, error) {
|
||||||
mm, err := tokens.ParseModuleMember(s)
|
// Keys can take on of two forms:
|
||||||
if err == nil {
|
//
|
||||||
return fromModuleMember(mm)
|
// - <namespace>:<name> (the preferred form)
|
||||||
}
|
// - <namespace>:config:<name> (compat with an old requirement that every config value be in the "config" module)
|
||||||
if idx := strings.Index(s, ":"); idx > -1 {
|
//
|
||||||
|
// Where <namespace> and <name> may be any string of characters, excluding ':'.
|
||||||
|
|
||||||
|
switch strings.Count(s, ":") {
|
||||||
|
case 1:
|
||||||
|
idx := strings.Index(s, ":")
|
||||||
return Key{namespace: s[:idx], name: s[idx+1:]}, nil
|
return Key{namespace: s[:idx], name: s[idx+1:]}, nil
|
||||||
|
case 2:
|
||||||
|
if mm, err := tokens.ParseModuleMember(s); err == nil {
|
||||||
|
if mm.Module().Name() == tokens.ModuleName("config") {
|
||||||
|
return Key{
|
||||||
|
namespace: mm.Module().Package().String(),
|
||||||
|
name: mm.Name().String(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Key{}, errors.Errorf("could not parse %s as a configuration key", s)
|
return Key{}, errors.Errorf("could not parse %s as a configuration key "+
|
||||||
}
|
"(configuration keys should be of the form `<namespace>:<name>`)", s)
|
||||||
|
|
||||||
func fromModuleMember(m tokens.ModuleMember) (Key, error) {
|
|
||||||
if m.Module().Name() != tokens.ModuleName("config") {
|
|
||||||
return Key{}, errors.Errorf("%s is not in config module", m)
|
|
||||||
}
|
|
||||||
|
|
||||||
return Key{
|
|
||||||
namespace: m.Module().Package().String(),
|
|
||||||
name: m.Name().String(),
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k Key) Namespace() string {
|
func (k Key) Namespace() string {
|
||||||
|
|
|
@ -18,7 +18,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/pulumi/pulumi/pkg/tokens"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
yaml "gopkg.in/yaml.v2"
|
yaml "gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
@ -36,17 +35,8 @@ func TestParseKey(t *testing.T) {
|
||||||
|
|
||||||
_, err = ParseKey("foo")
|
_, err = ParseKey("foo")
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
func TestFromModuleMember(t *testing.T) {
|
_, err = ParseKey("test:data:key")
|
||||||
mm := tokens.ModuleMember("test:config:key")
|
|
||||||
k, err := fromModuleMember(mm)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, "test", k.namespace)
|
|
||||||
assert.Equal(t, "key", k.name)
|
|
||||||
|
|
||||||
mm = tokens.ModuleMember("test:data:key")
|
|
||||||
_, err = fromModuleMember(mm)
|
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue