pulumi/sdk/go/common/resource/config/map.go

331 lines
7.7 KiB
Go
Raw Permalink Normal View History

2018-05-22 19:43:36 +00:00
// Copyright 2016-2018, Pulumi Corporation.
//
// 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.
package config
import (
"context"
"encoding/json"
2023-02-01 22:09:15 +00:00
"errors"
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
"fmt"
"strconv"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
)
// Map is a bag of config stored in the settings file.
type Map map[Key]Value
// Decrypt returns the configuration as a map from module member to decrypted value.
func (m Map) Decrypt(decrypter Decrypter) (map[Key]string, error) {
r := map[Key]string{}
for k, c := range m {
v, err := c.Value(decrypter)
if err != nil {
return nil, err
}
r[k] = v
}
return r, nil
}
func (m Map) Copy(decrypter Decrypter, encrypter Encrypter) (Map, error) {
newConfig := make(Map)
for k, c := range m {
val, err := c.Copy(decrypter, encrypter)
if err != nil {
return nil, err
}
newConfig[k] = val
}
return newConfig, nil
}
// SecureKeys returns a list of keys that have secure values.
func (m Map) SecureKeys() []Key {
var keys []Key
for k, v := range m {
if v.Secure() {
keys = append(keys, k)
}
}
return keys
}
// HasSecureValue returns true if the config map contains a secure (encrypted) value.
func (m Map) HasSecureValue() bool {
for _, v := range m {
if v.Secure() {
return true
}
}
return false
}
pass through property values to RunRequest (#14273) # Description This is an alternative to https://github.com/pulumi/pulumi/pull/14244. Instead of adding type information to the run request, pass the config through as property values. Property values are properly encoded on the wire, and can be unmarshalled on the other end including type information, so this should be a more future proof way to go forward. Eventually we'll want to parse the config directly into property values, but that can be left for the future, as it's a bigger change. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-10-20 10:44:16 +00:00
// AsDecryptedPropertyMap returns the config as a property map, with secret values decrypted.
func (m Map) AsDecryptedPropertyMap(ctx context.Context, decrypter Decrypter) (resource.PropertyMap, error) {
pass through property values to RunRequest (#14273) # Description This is an alternative to https://github.com/pulumi/pulumi/pull/14244. Instead of adding type information to the run request, pass the config through as property values. Property values are properly encoded on the wire, and can be unmarshalled on the other end including type information, so this should be a more future proof way to go forward. Eventually we'll want to parse the config directly into property values, but that can be left for the future, as it's a bigger change. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-10-20 10:44:16 +00:00
pm := resource.PropertyMap{}
for k, v := range m {
newV, err := adjustObjectValue(v)
if err != nil {
return resource.PropertyMap{}, err
}
plaintext, err := newV.toDecryptedPropertyValue(ctx, decrypter)
if err != nil {
return resource.PropertyMap{}, err
}
pm[resource.PropertyKey(k.String())] = plaintext
pass through property values to RunRequest (#14273) # Description This is an alternative to https://github.com/pulumi/pulumi/pull/14244. Instead of adding type information to the run request, pass the config through as property values. Property values are properly encoded on the wire, and can be unmarshalled on the other end including type information, so this should be a more future proof way to go forward. Eventually we'll want to parse the config directly into property values, but that can be left for the future, as it's a bigger change. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-10-20 10:44:16 +00:00
}
return pm, nil
}
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
// Get gets the value for a given key. If path is true, the key's name portion is treated as a path.
func (m Map) Get(k Key, path bool) (_ Value, ok bool, err error) {
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
// If the key isn't a path, go ahead and lookup the value.
if !path {
v, ok := m[k]
return v, ok, nil
}
// Otherwise, parse the path and get the new config key.
p, configKey, err := parseKeyPath(k)
if err != nil {
return Value{}, false, err
}
// If we only have a single path segment, go ahead and lookup the value.
root, ok := m[configKey]
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
if len(p) == 1 {
return root, ok, nil
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
}
obj, err := root.unmarshalObject()
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
if err != nil {
return Value{}, false, err
}
objValue, ok, err := obj.Get(p[1:])
if !ok || err != nil {
return Value{}, ok, err
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
}
v, err := objValue.marshalValue()
if err != nil {
return v, false, err
}
return v, true, nil
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
}
// Remove removes the value for a given key. If path is true, the key's name portion is treated as a path.
func (m Map) Remove(k Key, path bool) error {
// If the key isn't a path, go ahead and delete it and return.
if !path {
delete(m, k)
return nil
}
// Otherwise, parse the path and get the new config key.
p, configKey, err := parseKeyPath(k)
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
if err != nil {
return err
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
}
// If we only have a single path segment, delete the key and return.
root, ok := m[configKey]
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
if len(p) == 1 {
delete(m, configKey)
return nil
}
if !ok {
return nil
}
obj, err := root.unmarshalObject()
if err != nil {
return err
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
}
err = obj.Delete(p[1:], p[1:])
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
if err != nil {
return err
}
root, err = obj.marshalValue()
if err != nil {
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
return err
}
m[configKey] = root
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
return nil
}
// Set sets the value for a given key. If path is true, the key's name portion is treated as a path.
func (m Map) Set(k Key, v Value, path bool) error {
// If the key isn't a path, go ahead and set the value and return.
if !path {
m[k] = v
return nil
}
// Otherwise, parse the path and get the new config key.
p, configKey, err := parseKeyPath(k)
if err != nil {
return err
}
// If we only have a single path segment, set the value and return.
if len(p) == 1 {
m[configKey] = v
return nil
}
newV, err := adjustObjectValue(v)
if err != nil {
return err
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
}
var obj object
if root, ok := m[configKey]; ok {
obj, err = root.unmarshalObject()
if err != nil {
return err
}
} else {
obj = object{value: newContainer(p[1])}
}
err = obj.Set(p[:1], p[1:], newV)
if err != nil {
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
return err
}
root, err := obj.marshalValue()
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
if err != nil {
return err
}
m[configKey] = root
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
return nil
}
func (m Map) MarshalJSON() ([]byte, error) {
rawMap := make(map[string]Value, len(m))
for k, v := range m {
rawMap[k.String()] = v
}
return json.Marshal(rawMap)
}
func (m *Map) UnmarshalJSON(b []byte) error {
rawMap := make(map[string]Value)
if err := json.Unmarshal(b, &rawMap); err != nil {
2023-02-01 22:09:15 +00:00
return fmt.Errorf("could not unmarshal map: %w", err)
}
newMap := make(Map, len(rawMap))
for k, v := range rawMap {
pk, err := ParseKey(k)
if err != nil {
2023-02-01 22:09:15 +00:00
return fmt.Errorf("could not unmarshal map: %w", err)
}
newMap[pk] = v
}
*m = newMap
return nil
}
func (m Map) MarshalYAML() (interface{}, error) {
rawMap := make(map[string]Value, len(m))
for k, v := range m {
rawMap[k.String()] = v
}
return rawMap, nil
}
func (m *Map) UnmarshalYAML(unmarshal func(interface{}) error) error {
rawMap := make(map[string]Value)
if err := unmarshal(&rawMap); err != nil {
2023-02-01 22:09:15 +00:00
return fmt.Errorf("could not unmarshal map: %w", err)
}
newMap := make(Map, len(rawMap))
for k, v := range rawMap {
pk, err := ParseKey(k)
if err != nil {
2023-02-01 22:09:15 +00:00
return fmt.Errorf("could not unmarshal map: %w", err)
}
newMap[pk] = v
}
*m = newMap
return nil
}
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
// parseKeyPath returns the property paths in the key and a new config key with the first
// path segment as the name.
func parseKeyPath(k Key) (resource.PropertyPath, Key, error) {
// Parse the path, which will be in the name portion of the key.
[14573] Parse config paths strictly (#15173) # Description We want to parse config paths more strictly and not allow something like "foo.[0]", but property paths everywhere else in the system need to tolerate those keys. Because of circular dependency on _pulumi/esc_ I kept a function with old signature and added a new one. (instead of refactoring by adding new parameter and exposing it) Fixes https://github.com/pulumi/pulumi/issues/14573. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. --> --------- Co-authored-by: Emil Hotkowski <ehotkowski@hopper.com> Co-authored-by: Thomas Gummerer <t.gummerer@gmail.com>
2024-01-19 10:51:27 +00:00
p, err := resource.ParsePropertyPathStrict(k.Name())
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
if err != nil {
2023-02-01 22:09:15 +00:00
return nil, Key{}, fmt.Errorf("invalid config key path: %w", err)
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
}
if len(p) == 0 {
return nil, Key{}, errors.New("empty config key path")
}
// Create a new key that has the first path segment as the name.
firstKey, ok := p[0].(string)
if !ok {
return nil, Key{}, errors.New("first path segement of config key must be a string")
}
if firstKey == "" {
return nil, Key{}, errors.New("config key is empty")
}
configKey := MustMakeKey(k.Namespace(), firstKey)
return p, configKey, nil
}
// adjustObjectValue returns a more suitable value for objects:
func adjustObjectValue(v Value) (object, error) {
// If it's a secure value or an object, return as-is.
if v.Secure() || v.Object() {
return v.unmarshalObject()
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
}
// If "false" or "true", return the boolean value.
if v.value == "false" {
return newObject(false), nil
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
} else if v.value == "true" {
return newObject(true), nil
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
}
// If the value has more than one character and starts with "0", return the value as-is
// so values like "0123456" are saved as a string (without stripping any leading zeros)
// rather than as the integer 123456.
if len(v.value) > 1 && v.value[0] == '0' {
return v.unmarshalObject()
}
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
// If it's convertible to an int, return the int.
if i, err := strconv.Atoi(v.value); err == nil {
return newObject(int64(i)), nil
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
}
// Otherwise, just return the string value.
return v.unmarshalObject()
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
}