Add config package

This change adds a config package.  This is syntactic sugar atop the
underlying config functionality in the pulumi.Context, but mirrors what
we do in our other Node.js and Python SDKs more closely.

This includes three families of functions:

    - config.Get*: returns the value or its default if missing.
    - config.Require*: returns the value or panics if missing.
    - config.Try*: returns the value or an error if missing.

In all cases, there are simple Get/Require/Try functions, that just
deal in terms of strings, in addition to type specific functions,
GetT/RequireT/TryT, for the most common Ts that you might need.
This commit is contained in:
joeduffy 2018-06-10 07:24:38 -07:00
parent cf1cb2d61f
commit da0667ef45
7 changed files with 747 additions and 26 deletions

View file

@ -13,3 +13,235 @@
// limitations under the License.
package pulumi
import (
"github.com/pulumi/pulumi/sdk/go/pulumi"
)
// Config is a struct that permits access to config as a "bag" with a package name. This avoids needing to access
// config with the fully qualified name all of the time (e.g., a bag whose namespace is "p" automatically translates
// attempted reads of keys "k" into "p:k"). This is optional but can save on some boilerplate when accessing config.
type Config struct {
ctx *pulumi.Context
namespace string
}
// New creates a new config bag with the given context and namespace.
func New(ctx *pulumi.Context, namespace string) *Config {
return &Config{ctx: ctx, namespace: namespace}
}
// fullKey turns a simple configuration key into a fully resolved one, by prepending the bag's name.
func (c *Config) fullKey(key string) string {
return c.namespace + ":" + key
}
// Get loads an optional configuration value by its key, or returns "" if it doesn't exist.
func (c *Config) Get(key string) string {
return Get(c.ctx, c.fullKey(key))
}
// GetBool loads an optional bool configuration value by its key, or returns false if it doesn't exist.
func (c *Config) GetBool(key string) bool {
return GetBool(c.ctx, c.fullKey(key))
}
// GetFloat32 loads an optional float32 configuration value by its key, or returns 0.0 if it doesn't exist.
func (c *Config) GetFloat32(key string) float32 {
return GetFloat32(c.ctx, c.fullKey(key))
}
// GetFloat64 loads an optional float64 configuration value by its key, or returns 0.0 if it doesn't exist.
func (c *Config) GetFloat64(key string) float64 {
return GetFloat64(c.ctx, c.fullKey(key))
}
// GetInt loads an optional int configuration value by its key, or returns 0 if it doesn't exist.
func (c *Config) GetInt(key string) int {
return GetInt(c.ctx, c.fullKey(key))
}
// GetInt8 loads an optional int8 configuration value by its key, or returns 0 if it doesn't exist.
func (c *Config) GetInt8(key string) int8 {
return GetInt8(c.ctx, c.fullKey(key))
}
// GetInt16 loads an optional int16 configuration value by its key, or returns 0 if it doesn't exist.
func (c *Config) GetInt16(key string) int16 {
return GetInt16(c.ctx, c.fullKey(key))
}
// GetInt32 loads an optional int32 configuration value by its key, or returns 0 if it doesn't exist.
func (c *Config) GetInt32(key string) int32 {
return GetInt32(c.ctx, c.fullKey(key))
}
// GetInt64 loads an optional int64 configuration value by its key, or returns 0 if it doesn't exist.
func (c *Config) GetInt64(key string) int64 {
return GetInt64(c.ctx, c.fullKey(key))
}
// GetUint loads an optional uint configuration value by its key, or returns 0 if it doesn't exist.
func (c *Config) GetUint(key string) uint {
return GetUint(c.ctx, c.fullKey(key))
}
// GetUint8 loads an optional uint8 configuration value by its key, or returns 0 if it doesn't exist.
func (c *Config) GetUint8(key string) uint8 {
return GetUint8(c.ctx, c.fullKey(key))
}
// GetUint16 loads an optional uint16 configuration value by its key, or returns 0 if it doesn't exist.
func (c *Config) GetUint16(key string) uint16 {
return GetUint16(c.ctx, c.fullKey(key))
}
// GetUint32 loads an optional uint32 configuration value by its key, or returns 0 if it doesn't exist.
func (c *Config) GetUint32(key string) uint32 {
return GetUint32(c.ctx, c.fullKey(key))
}
// GetUint64 loads an optional uint64 configuration value by its key, or returns 0 if it doesn't exist.
func (c *Config) GetUint64(key string) uint64 {
return GetUint64(c.ctx, c.fullKey(key))
}
// Require loads a configuration value by its key, or panics if it doesn't exist.
func (c *Config) Require(key string) string {
return Require(c.ctx, c.fullKey(key))
}
// RequireBool loads a bool configuration value by its key, or panics if it doesn't exist.
func (c *Config) RequireBool(key string) bool {
return RequireBool(c.ctx, c.fullKey(key))
}
// RequireFloat32 loads a float32 configuration value by its key, or panics if it doesn't exist.
func (c *Config) RequireFloat32(key string) float32 {
return RequireFloat32(c.ctx, c.fullKey(key))
}
// RequireFloat64 loads a float64 configuration value by its key, or panics if it doesn't exist.
func (c *Config) RequireFloat64(key string) float64 {
return RequireFloat64(c.ctx, c.fullKey(key))
}
// RequireInt loads a int configuration value by its key, or panics if it doesn't exist.
func (c *Config) RequireInt(key string) int {
return RequireInt(c.ctx, c.fullKey(key))
}
// RequireInt8 loads a int8 configuration value by its key, or panics if it doesn't exist.
func (c *Config) RequireInt8(key string) int8 {
return RequireInt8(c.ctx, c.fullKey(key))
}
// RequireInt16 loads a int16 configuration value by its key, or panics if it doesn't exist.
func (c *Config) RequireInt16(key string) int16 {
return RequireInt16(c.ctx, c.fullKey(key))
}
// RequireInt32 loads a int32 configuration value by its key, or panics if it doesn't exist.
func (c *Config) RequireInt32(key string) int32 {
return RequireInt32(c.ctx, c.fullKey(key))
}
// RequireInt64 loads a int64 configuration value by its key, or panics if it doesn't exist.
func (c *Config) RequireInt64(key string) int64 {
return RequireInt64(c.ctx, c.fullKey(key))
}
// RequireUint loads a uint configuration value by its key, or panics if it doesn't exist.
func (c *Config) RequireUint(key string) uint {
return RequireUint(c.ctx, c.fullKey(key))
}
// RequireUint8 loads a uint8 configuration value by its key, or panics if it doesn't exist.
func (c *Config) RequireUint8(key string) uint8 {
return RequireUint8(c.ctx, c.fullKey(key))
}
// RequireUint16 loads a uint16 configuration value by its key, or panics if it doesn't exist.
func (c *Config) RequireUint16(key string) uint16 {
return RequireUint16(c.ctx, c.fullKey(key))
}
// RequireUint32 loads a uint32 configuration value by its key, or panics if it doesn't exist.
func (c *Config) RequireUint32(key string) uint32 {
return RequireUint32(c.ctx, c.fullKey(key))
}
// RequireUint64 loads a uint64 configuration value by its key, or panics if it doesn't exist.
func (c *Config) RequireUint64(key string) uint64 {
return RequireUint64(c.ctx, c.fullKey(key))
}
// Try loads a configuration value by its key, returning a non-nil error if it doesn't exist.
func (c *Config) Try(key string) (string, error) {
return Try(c.ctx, c.fullKey(key))
}
// TryBool loads an optional bool configuration value by its key, or returns an error if it doesn't exist.
func (c *Config) TryBool(key string) (bool, error) {
return TryBool(c.ctx, c.fullKey(key))
}
// TryFloat32 loads an optional float32 configuration value by its key, or returns an error if it doesn't exist.
func (c *Config) TryFloat32(key string) (float32, error) {
return TryFloat32(c.ctx, c.fullKey(key))
}
// TryFloat64 loads an optional float64 configuration value by its key, or returns an error if it doesn't exist.
func (c *Config) TryFloat64(key string) (float64, error) {
return TryFloat64(c.ctx, c.fullKey(key))
}
// TryInt loads an optional int configuration value by its key, or returns an error if it doesn't exist.
func (c *Config) TryInt(key string) (int, error) {
return TryInt(c.ctx, c.fullKey(key))
}
// TryInt8 loads an optional int8 configuration value by its key, or returns an error if it doesn't exist.
func (c *Config) TryInt8(key string) (int8, error) {
return TryInt8(c.ctx, c.fullKey(key))
}
// TryInt16 loads an optional int16 configuration value by its key, or returns an error if it doesn't exist.
func (c *Config) TryInt16(key string) (int16, error) {
return TryInt16(c.ctx, c.fullKey(key))
}
// TryInt32 loads an optional int32 configuration value by its key, or returns an error if it doesn't exist.
func (c *Config) TryInt32(key string) (int32, error) {
return TryInt32(c.ctx, c.fullKey(key))
}
// TryInt64 loads an optional int64 configuration value by its key, or returns an error if it doesn't exist.
func (c *Config) TryInt64(key string) (int64, error) {
return TryInt64(c.ctx, c.fullKey(key))
}
// TryUint loads an optional uint configuration value by its key, or returns an error if it doesn't exist.
func (c *Config) TryUint(key string) (uint, error) {
return TryUint(c.ctx, c.fullKey(key))
}
// TryUint8 loads an optional uint8 configuration value by its key, or returns an error if it doesn't exist.
func (c *Config) TryUint8(key string) (uint8, error) {
return TryUint8(c.ctx, c.fullKey(key))
}
// TryUint16 loads an optional uint16 configuration value by its key, or returns an error if it doesn't exist.
func (c *Config) TryUint16(key string) (uint16, error) {
return TryUint16(c.ctx, c.fullKey(key))
}
// TryUint32 loads an optional uint32 configuration value by its key, or returns an error if it doesn't exist.
func (c *Config) TryUint32(key string) (uint32, error) {
return TryUint32(c.ctx, c.fullKey(key))
}
// TryUint64 loads an optional uint64 configuration value by its key, or returns an error if it doesn't exist.
func (c *Config) TryUint64(key string) (uint64, error) {
return TryUint64(c.ctx, c.fullKey(key))
}

View file

@ -0,0 +1,79 @@
// 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 pulumi
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/pulumi/pulumi/sdk/go/pulumi"
)
// TestConfig tests the basic config wrapper.
func TestConfig(t *testing.T) {
ctx, err := pulumi.NewContext(context.Background(), pulumi.RunInfo{
Config: map[string]string{
"testpkg:sss": "a string value",
"testpkg:bbb": "true",
"testpkg:intint": "42",
"testpkg:fpfpfp": "99.963",
},
})
assert.Nil(t, err)
cfg := New(ctx, "testpkg")
// Test basic keys.
assert.Equal(t, "testpkg:sss", cfg.fullKey("sss"))
// Test Get, which returns a default value for missing entries rather than failing.
assert.Equal(t, "a string value", cfg.Get("sss"))
assert.Equal(t, true, cfg.GetBool("bbb"))
assert.Equal(t, 42, cfg.GetInt("intint"))
assert.Equal(t, 99.963, cfg.GetFloat64("fpfpfp"))
assert.Equal(t, "", cfg.Get("missing"))
// Test Require, which panics for missing entries.
assert.Equal(t, "a string value", cfg.Require("sss"))
assert.Equal(t, true, cfg.RequireBool("bbb"))
assert.Equal(t, 42, cfg.RequireInt("intint"))
assert.Equal(t, 99.963, cfg.RequireFloat64("fpfpfp"))
func() {
defer func() {
if r := recover(); r == nil {
t.Errorf("expected missing key for Require to panic")
}
}()
_ = cfg.Require("missing")
}()
// Test Try, which returns an error for missing entries.
k1, err := cfg.Try("sss")
assert.Nil(t, err)
assert.Equal(t, "a string value", k1)
k2, err := cfg.TryBool("bbb")
assert.Nil(t, err)
assert.Equal(t, true, k2)
k3, err := cfg.TryInt("intint")
assert.Nil(t, err)
assert.Equal(t, 42, k3)
k4, err := cfg.TryFloat64("fpfpfp")
assert.Nil(t, err)
assert.Equal(t, 99.963, k4)
_, err = cfg.Try("missing")
assert.NotNil(t, err)
}

131
sdk/go/pulumi/config/get.go Normal file
View file

@ -0,0 +1,131 @@
// 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 pulumi
import (
"github.com/spf13/cast"
"github.com/pulumi/pulumi/sdk/go/pulumi"
)
// Get loads an optional configuration value by its key, or returns "" if it doesn't exist.
func Get(ctx *pulumi.Context, key string) string {
v, _ := ctx.GetConfig(key)
return v
}
// GetBool loads an optional configuration value by its key, as a bool, or returns false if it doesn't exist.
func GetBool(ctx *pulumi.Context, key string) bool {
if v, ok := ctx.GetConfig(key); ok {
return cast.ToBool(v)
}
return false
}
// GetFloat32 loads an optional configuration value by its key, as a float32, or returns 0.0 if it doesn't exist.
func GetFloat32(ctx *pulumi.Context, key string) float32 {
if v, ok := ctx.GetConfig(key); ok {
return cast.ToFloat32(v)
}
return 0
}
// GetFloat64 loads an optional configuration value by its key, as a float64, or returns 0.0 if it doesn't exist.
func GetFloat64(ctx *pulumi.Context, key string) float64 {
if v, ok := ctx.GetConfig(key); ok {
return cast.ToFloat64(v)
}
return 0
}
// GetInt loads an optional configuration value by its key, as a int, or returns 0 if it doesn't exist.
func GetInt(ctx *pulumi.Context, key string) int {
if v, ok := ctx.GetConfig(key); ok {
return cast.ToInt(v)
}
return 0
}
// GetInt8 loads an optional configuration value by its key, as a int8, or returns 0 if it doesn't exist.
func GetInt8(ctx *pulumi.Context, key string) int8 {
if v, ok := ctx.GetConfig(key); ok {
return cast.ToInt8(v)
}
return 0
}
// GetInt16 loads an optional configuration value by its key, as a int16, or returns 0 if it doesn't exist.
func GetInt16(ctx *pulumi.Context, key string) int16 {
if v, ok := ctx.GetConfig(key); ok {
return cast.ToInt16(v)
}
return 0
}
// GetInt32 loads an optional configuration value by its key, as a int32, or returns 0 if it doesn't exist.
func GetInt32(ctx *pulumi.Context, key string) int32 {
if v, ok := ctx.GetConfig(key); ok {
return cast.ToInt32(v)
}
return 0
}
// GetInt64 loads an optional configuration value by its key, as a int64, or returns 0 if it doesn't exist.
func GetInt64(ctx *pulumi.Context, key string) int64 {
if v, ok := ctx.GetConfig(key); ok {
return cast.ToInt64(v)
}
return 0
}
// GetUint loads an optional configuration value by its key, as a uint, or returns 0 if it doesn't exist.
func GetUint(ctx *pulumi.Context, key string) uint {
if v, ok := ctx.GetConfig(key); ok {
return cast.ToUint(v)
}
return 0
}
// GetUint8 loads an optional configuration value by its key, as a uint8, or returns 0 if it doesn't exist.
func GetUint8(ctx *pulumi.Context, key string) uint8 {
if v, ok := ctx.GetConfig(key); ok {
return cast.ToUint8(v)
}
return 0
}
// GetUint16 loads an optional configuration value by its key, as a uint16, or returns 0 if it doesn't exist.
func GetUint16(ctx *pulumi.Context, key string) uint16 {
if v, ok := ctx.GetConfig(key); ok {
return cast.ToUint16(v)
}
return 0
}
// GetUint32 loads an optional configuration value by its key, as a uint32, or returns 0 if it doesn't exist.
func GetUint32(ctx *pulumi.Context, key string) uint32 {
if v, ok := ctx.GetConfig(key); ok {
return cast.ToUint32(v)
}
return 0
}
// GetUint64 loads an optional configuration value by its key, as a uint64, or returns 0 if it doesn't exist.
func GetUint64(ctx *pulumi.Context, key string) uint64 {
if v, ok := ctx.GetConfig(key); ok {
return cast.ToUint64(v)
}
return 0
}

View file

@ -0,0 +1,109 @@
// 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 pulumi
import (
"github.com/spf13/cast"
"github.com/pulumi/pulumi/pkg/util/contract"
"github.com/pulumi/pulumi/sdk/go/pulumi"
)
// Require loads a configuration value by its key, or panics if it doesn't exist.
func Require(ctx *pulumi.Context, key string) string {
v, ok := ctx.GetConfig(key)
if !ok {
contract.Failf("missing required configuration variable '%s'; run `pulumi config` to set", key)
}
return v
}
// Require loads an optional configuration value by its key, as a bool, or panics if it doesn't exist.
func RequireBool(ctx *pulumi.Context, key string) bool {
v := Require(ctx, key)
return cast.ToBool(v)
}
// Require loads an optional configuration value by its key, as a float32, or panics if it doesn't exist.
func RequireFloat32(ctx *pulumi.Context, key string) float32 {
v := Require(ctx, key)
return cast.ToFloat32(v)
}
// Require loads an optional configuration value by its key, as a float64, or panics if it doesn't exist.
func RequireFloat64(ctx *pulumi.Context, key string) float64 {
v := Require(ctx, key)
return cast.ToFloat64(v)
}
// Require loads an optional configuration value by its key, as a int, or panics if it doesn't exist.
func RequireInt(ctx *pulumi.Context, key string) int {
v := Require(ctx, key)
return cast.ToInt(v)
}
// Require loads an optional configuration value by its key, as a int8, or panics if it doesn't exist.
func RequireInt8(ctx *pulumi.Context, key string) int8 {
v := Require(ctx, key)
return cast.ToInt8(v)
}
// Require loads an optional configuration value by its key, as a int16, or panics if it doesn't exist.
func RequireInt16(ctx *pulumi.Context, key string) int16 {
v := Require(ctx, key)
return cast.ToInt16(v)
}
// Require loads an optional configuration value by its key, as a int32, or panics if it doesn't exist.
func RequireInt32(ctx *pulumi.Context, key string) int32 {
v := Require(ctx, key)
return cast.ToInt32(v)
}
// Require loads an optional configuration value by its key, as a int64, or panics if it doesn't exist.
func RequireInt64(ctx *pulumi.Context, key string) int64 {
v := Require(ctx, key)
return cast.ToInt64(v)
}
// Require loads an optional configuration value by its key, as a uint, or panics if it doesn't exist.
func RequireUint(ctx *pulumi.Context, key string) uint {
v := Require(ctx, key)
return cast.ToUint(v)
}
// Require loads an optional configuration value by its key, as a uint8, or panics if it doesn't exist.
func RequireUint8(ctx *pulumi.Context, key string) uint8 {
v := Require(ctx, key)
return cast.ToUint8(v)
}
// Require loads an optional configuration value by its key, as a uint16, or panics if it doesn't exist.
func RequireUint16(ctx *pulumi.Context, key string) uint16 {
v := Require(ctx, key)
return cast.ToUint16(v)
}
// Require loads an optional configuration value by its key, as a uint32, or panics if it doesn't exist.
func RequireUint32(ctx *pulumi.Context, key string) uint32 {
v := Require(ctx, key)
return cast.ToUint32(v)
}
// Require loads an optional configuration value by its key, as a uint64, or panics if it doesn't exist.
func RequireUint64(ctx *pulumi.Context, key string) uint64 {
v := Require(ctx, key)
return cast.ToUint64(v)
}

149
sdk/go/pulumi/config/try.go Normal file
View file

@ -0,0 +1,149 @@
// 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 pulumi
import (
"github.com/pkg/errors"
"github.com/spf13/cast"
"github.com/pulumi/pulumi/sdk/go/pulumi"
)
// Try loads a configuration value by its key, returning a non-nil error if it doesn't exist.
func Try(ctx *pulumi.Context, key string) (string, error) {
v, ok := ctx.GetConfig(key)
if !ok {
return "",
errors.Errorf("missing required configuration variable '%s'; run `pulumi config` to set", key)
}
return v, nil
}
// Try loads an optional configuration value by its key, as a bool, or returns an error if it doesn't exist.
func TryBool(ctx *pulumi.Context, key string) (bool, error) {
v, err := Try(ctx, key)
if err != nil {
return false, err
}
return cast.ToBool(v), nil
}
// Try loads an optional configuration value by its key, as a float32, or returns an error if it doesn't exist.
func TryFloat32(ctx *pulumi.Context, key string) (float32, error) {
v, err := Try(ctx, key)
if err != nil {
return 0, err
}
return cast.ToFloat32(v), nil
}
// Try loads an optional configuration value by its key, as a float64, or returns an error if it doesn't exist.
func TryFloat64(ctx *pulumi.Context, key string) (float64, error) {
v, err := Try(ctx, key)
if err != nil {
return 0, err
}
return cast.ToFloat64(v), nil
}
// Try loads an optional configuration value by its key, as a int, or returns an error if it doesn't exist.
func TryInt(ctx *pulumi.Context, key string) (int, error) {
v, err := Try(ctx, key)
if err != nil {
return 0, err
}
return cast.ToInt(v), nil
}
// Try loads an optional configuration value by its key, as a int8, or returns an error if it doesn't exist.
func TryInt8(ctx *pulumi.Context, key string) (int8, error) {
v, err := Try(ctx, key)
if err != nil {
return 0, err
}
return cast.ToInt8(v), nil
}
// Try loads an optional configuration value by its key, as a int16, or returns an error if it doesn't exist.
func TryInt16(ctx *pulumi.Context, key string) (int16, error) {
v, err := Try(ctx, key)
if err != nil {
return 0, err
}
return cast.ToInt16(v), nil
}
// Try loads an optional configuration value by its key, as a int32, or returns an error if it doesn't exist.
func TryInt32(ctx *pulumi.Context, key string) (int32, error) {
v, err := Try(ctx, key)
if err != nil {
return 0, err
}
return cast.ToInt32(v), nil
}
// Try loads an optional configuration value by its key, as a int64, or returns an error if it doesn't exist.
func TryInt64(ctx *pulumi.Context, key string) (int64, error) {
v, err := Try(ctx, key)
if err != nil {
return 0, err
}
return cast.ToInt64(v), nil
}
// Try loads an optional configuration value by its key, as a uint, or returns an error if it doesn't exist.
func TryUint(ctx *pulumi.Context, key string) (uint, error) {
v, err := Try(ctx, key)
if err != nil {
return 0, err
}
return cast.ToUint(v), nil
}
// Try loads an optional configuration value by its key, as a uint8, or returns an error if it doesn't exist.
func TryUint8(ctx *pulumi.Context, key string) (uint8, error) {
v, err := Try(ctx, key)
if err != nil {
return 0, err
}
return cast.ToUint8(v), nil
}
// Try loads an optional configuration value by its key, as a uint16, or returns an error if it doesn't exist.
func TryUint16(ctx *pulumi.Context, key string) (uint16, error) {
v, err := Try(ctx, key)
if err != nil {
return 0, err
}
return cast.ToUint16(v), nil
}
// Try loads an optional configuration value by its key, as a uint32, or returns an error if it doesn't exist.
func TryUint32(ctx *pulumi.Context, key string) (uint32, error) {
v, err := Try(ctx, key)
if err != nil {
return 0, err
}
return cast.ToUint32(v), nil
}
// Try loads an optional configuration value by its key, as a uint64, or returns an error if it doesn't exist.
func TryUint64(ctx *pulumi.Context, key string) (uint64, error) {
v, err := Try(ctx, key)
if err != nil {
return 0, err
}
return cast.ToUint64(v), nil
}

View file

@ -43,28 +43,27 @@ type Context struct {
// NewContext creates a fresh run context out of the given metadata.
func NewContext(ctx context.Context, info RunInfo) (*Context, error) {
// Validate some properties.
if info.Project == "" {
return nil, errors.New("missing project name")
}
if info.Stack == "" {
return nil, errors.New("missing stack name")
}
if info.MonitorAddr == "" {
return nil, errors.New("missing resource monitor RPC address")
}
if info.EngineAddr == "" {
return nil, errors.New("missing engine RPC address")
// Connect to the gRPC endpoints if we have addresses for them.
var monitorConn *grpc.ClientConn
var monitor pulumirpc.ResourceMonitorClient
if addr := info.MonitorAddr; addr != "" {
conn, err := grpc.Dial(info.MonitorAddr, grpc.WithInsecure())
if err != nil {
return nil, errors.Wrap(err, "connecting to resource monitor over RPC")
}
monitorConn = conn
monitor = pulumirpc.NewResourceMonitorClient(monitorConn)
}
monitorConn, err := grpc.Dial(info.MonitorAddr, grpc.WithInsecure())
if err != nil {
return nil, errors.Wrap(err, "connecting to resource monitor over RPC")
}
engineConn, err := grpc.Dial(info.EngineAddr, grpc.WithInsecure())
if err != nil {
return nil, errors.Wrap(err, "connecting to engine over RPC")
var engineConn *grpc.ClientConn
var engine pulumirpc.EngineClient
if addr := info.EngineAddr; addr != "" {
conn, err := grpc.Dial(info.EngineAddr, grpc.WithInsecure())
if err != nil {
return nil, errors.Wrap(err, "connecting to engine over RPC")
}
engineConn = conn
engine = pulumirpc.NewEngineClient(engineConn)
}
mutex := &sync.Mutex{}
@ -73,9 +72,9 @@ func NewContext(ctx context.Context, info RunInfo) (*Context, error) {
info: info,
exports: make(map[string]interface{}),
monitorConn: monitorConn,
monitor: pulumirpc.NewResourceMonitorClient(monitorConn),
monitor: monitor,
engineConn: engineConn,
engine: pulumirpc.NewEngineClient(engineConn),
engine: engine,
rpcs: 0,
rpcsLock: mutex,
rpcsDone: sync.NewCond(mutex),
@ -84,11 +83,15 @@ func NewContext(ctx context.Context, info RunInfo) (*Context, error) {
// Close implements io.Closer and relinquishes any outstanding resources held by the context.
func (ctx *Context) Close() error {
if err := ctx.engineConn.Close(); err != nil {
return err
if ctx.engineConn != nil {
if err := ctx.engineConn.Close(); err != nil {
return err
}
}
if err := ctx.monitorConn.Close(); err != nil {
return err
if ctx.monitorConn != nil {
if err := ctx.monitorConn.Close(); err != nil {
return err
}
}
return nil
}
@ -105,6 +108,12 @@ func (ctx *Context) Parallel() int { return ctx.info.Parallel }
// DryRun is true when evaluating a program for purposes of planning, instead of performing a true deployment.
func (ctx *Context) DryRun() bool { return ctx.info.DryRun }
// GetConfig returns the config value, as a string, and a bool indicating whether it exists or not.
func (ctx *Context) GetConfig(key string) (string, bool) {
v, ok := ctx.info.Config[key]
return v, ok
}
// Invoke will invoke a provider's function, identified by its token tok.
func (ctx *Context) Invoke(tok string, args map[string]interface{}) (Outputs, error) {
// TODO(joe): implement this.

View file

@ -21,6 +21,7 @@ import (
"strconv"
"github.com/hashicorp/go-multierror"
"github.com/pkg/errors"
"golang.org/x/net/context"
"github.com/pulumi/pulumi/pkg/util/contract"
@ -44,6 +45,17 @@ func RunErr(body RunFunc) error {
// TODO(joe): this is a fine default, but consider `...RunOpt`s to control how we get the various addresses, etc.
info := getEnvInfo()
// Validate some properties.
if info.Project == "" {
return errors.New("missing project name")
} else if info.Stack == "" {
return errors.New("missing stack name")
} else if info.MonitorAddr == "" {
return errors.New("missing resource monitor RPC address")
} else if info.EngineAddr == "" {
return errors.New("missing engine RPC address")
}
// Create a fresh context.
ctx, err := NewContext(context.TODO(), info)
if err != nil {